510 lines
16 KiB
JavaScript
510 lines
16 KiB
JavaScript
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2024
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
// Import
|
|
var g_oTextMeasurer = AscCommon.g_oTextMeasurer;
|
|
var History = AscCommon.History;
|
|
|
|
/**
|
|
* Класс реализующий w:abstractNum
|
|
* @constructor
|
|
*/
|
|
function CAbstractNum()
|
|
{
|
|
this.Id = AscCommon.g_oIdCounter.Get_NewId();
|
|
|
|
this.Lock = new AscCommon.CLock();
|
|
if (false === AscCommon.g_oIdCounter.m_bLoad)
|
|
{
|
|
this.Lock.Set_Type(AscCommon.c_oAscLockTypes.kLockTypeMine, false);
|
|
if (typeof AscCommon.CollaborativeEditing !== "undefined")
|
|
AscCommon.CollaborativeEditing.Add_Unlock2(this);
|
|
}
|
|
|
|
this.Numbering = null; // Link to the main class
|
|
|
|
this.NumStyleLink = undefined;
|
|
this.StyleLink = undefined;
|
|
this.nsid = undefined;
|
|
|
|
this.Lvl = [];
|
|
for (var nLvl = 0; nLvl < 9; ++nLvl)
|
|
{
|
|
this.Lvl[nLvl] = new CNumberingLvl();
|
|
}
|
|
|
|
this.MultiLvlType = Asc.c_oAbstractNumMultiLvlTypes.MultiLevel;
|
|
|
|
// Добавляем данный класс в таблицу Id (обязательно в конце конструктора)
|
|
AscCommon.g_oTableId.Add(this, this.Id);
|
|
}
|
|
|
|
CAbstractNum.prototype.Get_Id = function()
|
|
{
|
|
return this.Id;
|
|
};
|
|
CAbstractNum.prototype.GetId = function()
|
|
{
|
|
return this.Id;
|
|
};
|
|
CAbstractNum.prototype.SetParent = function(parent)
|
|
{
|
|
this.Numbering = parent;
|
|
};
|
|
CAbstractNum.prototype.Copy = function(oAbstractNum)
|
|
{
|
|
this.SetStyleLink(oAbstractNum.StyleLink);
|
|
this.SetNumStyleLink(oAbstractNum.NumStyleLink);
|
|
|
|
for (var nLvl = 0; nLvl < 9; ++nLvl)
|
|
{
|
|
var oLvlNew = oAbstractNum.Lvl[nLvl].Copy();
|
|
var oLvlOld = this.Lvl[nLvl];
|
|
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, oLvlNew, nLvl));
|
|
this.Lvl[nLvl] = oLvlNew;
|
|
}
|
|
};
|
|
CAbstractNum.prototype.SetStyleLink = function(sValue)
|
|
{
|
|
if (sValue !== this.StyleLink)
|
|
{
|
|
History.Add(new AscDFH.CChangesAbstractNumStyleLink(this, this.StyleLink, sValue));
|
|
this.StyleLink = sValue;
|
|
}
|
|
};
|
|
CAbstractNum.prototype.GetStyleLink = function()
|
|
{
|
|
return this.StyleLink;
|
|
};
|
|
CAbstractNum.prototype.SetNumStyleLink = function(sValue)
|
|
{
|
|
if (sValue !== this.NumStyleLink)
|
|
{
|
|
History.Add(new AscDFH.CChangesAbstractNumNumStyleLink(this, this.NumStyleLink, sValue));
|
|
this.NumStyleLink = sValue;
|
|
}
|
|
};
|
|
CAbstractNum.prototype.GetNumStyleLink = function()
|
|
{
|
|
return this.NumStyleLink;
|
|
};
|
|
CAbstractNum.prototype.SetNsid = function(nsid)
|
|
{
|
|
if (this.nsid === nsid)
|
|
return false;
|
|
|
|
AscCommon.History.Add(new AscDFH.CChangesAbstractNumNsid(this, this.nsid, nsid));
|
|
this.nsid = nsid;
|
|
};
|
|
CAbstractNum.prototype.GetNsid = function()
|
|
{
|
|
return this.nsid;
|
|
};
|
|
CAbstractNum.prototype.RecalculateRelatedParagraphs = function(nLvl)
|
|
{
|
|
if (nLvl < 0 || nLvl > 8)
|
|
nLvl = undefined;
|
|
|
|
let logicDocument = editor.WordControl.m_oLogicDocument;
|
|
if (!logicDocument || !logicDocument.IsDocumentEditor())
|
|
return;
|
|
|
|
let numberingManager = logicDocument.GetNumbering();
|
|
numberingManager.GetAllNumsByAbstractNum(this).forEach(function(num)
|
|
{
|
|
num.RecalculateRelatedParagraphs(nLvl);
|
|
});
|
|
};
|
|
CAbstractNum.prototype.GetMultiLvlType = function()
|
|
{
|
|
return this.MultiLvlType;
|
|
};
|
|
|
|
CAbstractNum.prototype.SetMultiLvlType = function(nMultiLvlType)
|
|
{
|
|
this.MultiLvlType = nMultiLvlType;
|
|
};
|
|
/**
|
|
* Получаем заданный уровень
|
|
* @param nLvl {number}
|
|
* @returns {CNumberingLvl}
|
|
*/
|
|
CAbstractNum.prototype.GetLvl = function(nLvl)
|
|
{
|
|
if (!this.Lvl[nLvl])
|
|
return this.Lvl[0];
|
|
|
|
return this.Lvl[nLvl];
|
|
};
|
|
/**
|
|
* Задаем уровень
|
|
* @param nLvl {number}
|
|
* @param oLvlNew {CNumberingLvl}
|
|
*/
|
|
CAbstractNum.prototype.SetLvl = function(nLvl, oLvlNew)
|
|
{
|
|
if ("number" != typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[nLvl];
|
|
this.Lvl[nLvl] = oLvlNew;
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, oLvlNew, nLvl));
|
|
this.RecalculateRelatedParagraphs(nLvl);
|
|
};
|
|
/**
|
|
* Создаем многоуровневый список с заданным пресетом
|
|
* @param nType {c_oAscMultiLevelNumbering}
|
|
*/
|
|
CAbstractNum.prototype.CreateDefault = function(nType)
|
|
{
|
|
for (var nLvl = 0; nLvl < 9; ++nLvl)
|
|
{
|
|
let lvlOld = this.Lvl[nLvl].Copy();
|
|
this.Lvl[nLvl].InitDefault(nLvl, nType);
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, lvlOld, this.Lvl[nLvl].Copy(), nLvl));
|
|
this.RecalculateRelatedParagraphs(nLvl);
|
|
}
|
|
};
|
|
/**
|
|
* Делаем заданный уровень заданного пресета
|
|
* @param nLvl {number} 0..8
|
|
* @param nType {c_oAscNumberingLevel}
|
|
* @param [sText=undefined] Используется для типа c_oAscNumberingLevel.Bullet
|
|
* @param [oTextPr=undefined] {CTextPr} Используется для типа c_oAscNumberingLevel.Bullet
|
|
*/
|
|
CAbstractNum.prototype.SetLvlByType = function(nLvl, nType, sText, oTextPr)
|
|
{
|
|
if ("number" !== typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[nLvl].Copy();
|
|
this.Lvl[nLvl].SetByType(nType, nLvl, sText, oTextPr);
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, this.Lvl[nLvl].Copy(), nLvl));
|
|
this.RecalculateRelatedParagraphs(nLvl);
|
|
};
|
|
/**
|
|
* Заполняем уровень по заданному формату
|
|
* @param nLvl {number} 0..8
|
|
* @param nType
|
|
* @param sFormatText
|
|
* @param nAlign
|
|
*/
|
|
CAbstractNum.prototype.SetLvlByFormat = function(nLvl, nType, sFormatText, nAlign)
|
|
{
|
|
if ("number" !== typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[nLvl].Copy();
|
|
this.Lvl[nLvl].SetByFormat(nLvl, nType, sFormatText, nAlign);
|
|
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, this.Lvl[nLvl].Copy(), nLvl));
|
|
this.RecalculateRelatedParagraphs(nLvl);
|
|
};
|
|
/**
|
|
* Связываем заданный уровень с заданным стилем
|
|
* @param iLvl {number} 0..8
|
|
* @param styleId {string}
|
|
*/
|
|
CAbstractNum.prototype.SetLvlPStyle = function(iLvl, styleId)
|
|
{
|
|
if ("number" !== typeof(iLvl) || iLvl < 0 || iLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[iLvl].Copy();
|
|
|
|
this.Lvl[iLvl].SetPStyle(styleId);
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, this.Lvl[iLvl].Copy(), iLvl));
|
|
};
|
|
/**
|
|
* Выставляем является ли данный уровень сквозным или каждый раз перестартовывать нумерацию
|
|
* @param nLvl {number} 0..8
|
|
* @param isRestart {boolean}
|
|
*/
|
|
CAbstractNum.prototype.SetLvlRestart = function(nLvl, isRestart)
|
|
{
|
|
if ("number" !== typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[nLvl].Copy();
|
|
|
|
this.Lvl[nLvl].Restart = (isRestart ? -1 : 0);
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, this.Lvl[nLvl].Copy(), nLvl));
|
|
};
|
|
/**
|
|
* Задаем начальное значения для данного уровня
|
|
* @param nLvl {number} 0..8
|
|
* @param nStart {number}
|
|
*/
|
|
CAbstractNum.prototype.SetLvlStart = function(nLvl, nStart)
|
|
{
|
|
if ("number" !== typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[nLvl].Copy();
|
|
|
|
this.Lvl[nLvl].Start = nStart;
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, this.Lvl[nLvl].Copy(), nLvl));
|
|
};
|
|
/**
|
|
* Получаем начальное значение для заданного уровня
|
|
* @param nLvl {number} 0..8
|
|
* @returns {number}
|
|
*/
|
|
CAbstractNum.prototype.GetLvlStart = function(nLvl)
|
|
{
|
|
if ("number" !== typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return 1;
|
|
|
|
return this.Lvl[nLvl].Start;
|
|
};
|
|
/**
|
|
* Выставляем тип разделителя между табом и последующим текстом
|
|
* @param nLvl {number} 0..8
|
|
* @param nSuff {number}
|
|
*/
|
|
CAbstractNum.prototype.SetLvlSuff = function(nLvl, nSuff)
|
|
{
|
|
if ("number" !== typeof(nLvl) || nLvl < 0 || nLvl >= 9)
|
|
return;
|
|
|
|
var oLvlOld = this.Lvl[nLvl].Copy();
|
|
|
|
this.Lvl[nLvl].Suff = nSuff;
|
|
History.Add(new AscDFH.CChangesAbstractNumLvlChange(this, oLvlOld, this.Lvl[nLvl].Copy(), nLvl));
|
|
};
|
|
/**
|
|
* Применяем новые тектовые настройки к данной нумерации на заданном уровне
|
|
* @param nLvl {number} 0..8
|
|
* @param oTextPr {CTextPr}
|
|
*/
|
|
CAbstractNum.prototype.ApplyTextPr = function(nLvl, oTextPr)
|
|
{
|
|
var oTextPrOld = this.Lvl[nLvl].TextPr.Copy();
|
|
this.Lvl[nLvl].TextPr.Merge(oTextPr);
|
|
History.Add(new AscDFH.CChangesAbstractNumTextPrChange(this, oTextPrOld, this.Lvl[nLvl].TextPr.Copy(), nLvl));
|
|
};
|
|
/**
|
|
* Выставляем текстовые настройки для заданного уровня
|
|
* @param nLvl {number} 0..8
|
|
* @param oTextPr {CTextPr}
|
|
*/
|
|
CAbstractNum.prototype.SetTextPr = function(nLvl, oTextPr)
|
|
{
|
|
History.Add(new AscDFH.CChangesAbstractNumTextPrChange(this, this.Lvl[nLvl].TextPr, oTextPr.Copy(), nLvl));
|
|
this.Lvl[nLvl].TextPr = oTextPr;
|
|
};
|
|
/**
|
|
* Выставляем настройки параграфа для заданного уровня
|
|
* @param nLvl {number} 0..8
|
|
* @param oParaPr {CParaPr}
|
|
*/
|
|
CAbstractNum.prototype.SetParaPr = function(nLvl, oParaPr)
|
|
{
|
|
History.Add(new AscDFH.CChangesAbstractNumParaPrChange(this, this.Lvl[nLvl].ParaPr, oParaPr.Copy(), nLvl));
|
|
this.Lvl[nLvl].ParaPr = oParaPr;
|
|
};
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// Undo/Redo функции
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
CAbstractNum.prototype.Refresh_RecalcData = function(Data)
|
|
{
|
|
var oHistory = History;
|
|
if (!oHistory)
|
|
return;
|
|
|
|
if (!oHistory.AddChangedNumberingToRecalculateData(this.Get_Id(), Data.Index, this))
|
|
return;
|
|
|
|
var oLogicDocument = editor.WordControl.m_oLogicDocument;
|
|
if (!oLogicDocument)
|
|
return;
|
|
|
|
var oNumbering = oLogicDocument.GetNumbering();
|
|
var arrNumPr = [];
|
|
|
|
for (var sId in oNumbering.Num)
|
|
{
|
|
var oNum = oNumbering.Num[sId];
|
|
if (this.Id === oNum.GetAbstractNumId())
|
|
{
|
|
arrNumPr.push(new AscWord.NumPr(oNum.GetId(), Data.Index));
|
|
}
|
|
}
|
|
|
|
var arrAllParagraphs = oLogicDocument.GetAllParagraphsByNumbering(arrNumPr);
|
|
|
|
for (var nIndex = 0, nCount = arrAllParagraphs.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
arrAllParagraphs[nIndex].Refresh_RecalcData({Type : AscDFH.historyitem_Paragraph_Numbering});
|
|
}
|
|
};
|
|
CAbstractNum.prototype.Document_Is_SelectionLocked = function(nCheckType)
|
|
{
|
|
return this.IsSelectionLocked(nCheckType);
|
|
};
|
|
CAbstractNum.prototype.IsSelectionLocked = function(nCheckType)
|
|
{
|
|
switch (nCheckType)
|
|
{
|
|
case AscCommon.changestype_Paragraph_Content:
|
|
case AscCommon.changestype_Paragraph_Properties:
|
|
case AscCommon.changestype_Paragraph_AddText:
|
|
case AscCommon.changestype_Paragraph_TextProperties:
|
|
case AscCommon.changestype_ContentControl_Add:
|
|
{
|
|
this.Lock.Check(this.Get_Id());
|
|
break;
|
|
}
|
|
case AscCommon.changestype_Document_Content:
|
|
case AscCommon.changestype_Document_Content_Add:
|
|
case AscCommon.changestype_Image_Properties:
|
|
{
|
|
AscCommon.CollaborativeEditing.Add_CheckLock(true);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// Функции для работы с совместным редактирования
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
CAbstractNum.prototype.Write_ToBinary2 = function(Writer)
|
|
{
|
|
Writer.WriteLong(AscDFH.historyitem_type_AbstractNum);
|
|
|
|
// String : Id
|
|
// String : StyleLink
|
|
// String : NumStyleLink
|
|
// Variable[9 Lvl] : 9 уровней
|
|
// Long : nsid
|
|
|
|
Writer.WriteString2(this.Id);
|
|
|
|
Writer.WriteString2(this.StyleLink ? this.StyleLink : "");
|
|
Writer.WriteString2(this.NumStyleLink ? this.NumStyleLink : "");
|
|
|
|
for (var nLvl = 0; nLvl < 9; ++nLvl)
|
|
this.Lvl[nLvl].WriteToBinary(Writer);
|
|
|
|
Writer.WriteLong(this.nsid ? this.nsid : 0);
|
|
};
|
|
CAbstractNum.prototype.Read_FromBinary2 = function(Reader)
|
|
{
|
|
// String : Id
|
|
// String : StyleLink
|
|
// String : NumStyleLink
|
|
// Variable[9 Lvl] : 9 уровней
|
|
|
|
this.Id = Reader.GetString2();
|
|
|
|
this.StyleLink = Reader.GetString2();
|
|
this.NumStyleLink = Reader.GetString2();
|
|
|
|
if ("" === this.StyleLink)
|
|
this.StyleLink = undefined;
|
|
|
|
if ("" === this.NumStyleLink)
|
|
this.NumStyleLink = undefined;
|
|
|
|
for (var nLvl = 0; nLvl < 9; ++nLvl)
|
|
{
|
|
this.Lvl[nLvl] = new CNumberingLvl();
|
|
this.Lvl[nLvl].ReadFromBinary(Reader);
|
|
}
|
|
|
|
this.nsid = Reader.GetLong();
|
|
if (0 === this.nsid)
|
|
this.nsid = undefined;
|
|
|
|
// Если мы создали нумерацию с nsid, который уже был занят, то далее мы его меняем на не занятый
|
|
// Тут при добавлении уже тоже должен быть занят этот nsid
|
|
|
|
// TODO: Нужно перенести в сам класс нумерации
|
|
// Добавим данный список в нумерацию
|
|
let numbering = editor.WordControl.m_oLogicDocument.Get_Numbering();
|
|
numbering._AddAbstractNum(this, this.GetId());
|
|
};
|
|
CAbstractNum.prototype.Process_EndLoad = function(Data)
|
|
{
|
|
var iLvl = Data.iLvl;
|
|
if (undefined !== iLvl)
|
|
{
|
|
// Пересчитываем стили у все параграфов с данной нумерацией
|
|
this.Recalc_CompiledPr(iLvl);
|
|
}
|
|
};
|
|
CAbstractNum.prototype.Recalc_CompiledPr = function(nLvl)
|
|
{
|
|
// Ищем все параграфы, который используют данную нумерацию и проставляем у них, то что их стиль
|
|
// нужно перекомпилировать.
|
|
|
|
this.RecalculateRelatedParagraphs(nLvl);
|
|
};
|
|
CAbstractNum.prototype.isEqual = function(abstractNum)
|
|
{
|
|
var lvlUsuallyAdd = this.Lvl;
|
|
var lvlNew = abstractNum.Lvl;
|
|
for (var lvl = 0; lvl < lvlUsuallyAdd.length; lvl++)
|
|
{
|
|
var LvlTextEqual = null;
|
|
var ParaPrEqual = null;
|
|
var TextPrEqual = null;
|
|
if (lvlUsuallyAdd[lvl].Format == lvlNew[lvl].Format && lvlUsuallyAdd[lvl].Jc == lvlNew[lvl].Jc && lvlUsuallyAdd[lvl].PStyle == lvlNew[lvl].PStyle && lvlUsuallyAdd[lvl].Restart == lvlNew[lvl].Restart && lvlUsuallyAdd[lvl].Start == lvlNew[lvl].Start && lvlUsuallyAdd[lvl].Suff == lvlNew[lvl].Suff)
|
|
{
|
|
LvlTextEqual = this._isEqualLvlText(lvlUsuallyAdd[lvl].LvlText, lvlNew[lvl].LvlText);
|
|
ParaPrEqual = lvlUsuallyAdd[lvl].ParaPr.isEqual(lvlUsuallyAdd[lvl].ParaPr, lvlNew[lvl].ParaPr);
|
|
TextPrEqual = lvlUsuallyAdd[lvl].TextPr.isEqual(lvlUsuallyAdd[lvl].TextPr, lvlNew[lvl].TextPr);
|
|
}
|
|
if (!LvlTextEqual || !ParaPrEqual || !TextPrEqual)
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
CAbstractNum.prototype._isEqualLvlText = function(LvlTextOld, LvlTextNew)
|
|
{
|
|
if (LvlTextOld.length !== LvlTextNew.length)
|
|
return false;
|
|
|
|
for (var LvlText = 0; LvlText < LvlTextOld.length; LvlText++)
|
|
{
|
|
if (LvlTextOld[LvlText].Type != LvlTextNew[LvlText].Type || LvlTextOld[LvlText].Value != LvlTextNew[LvlText].Value)
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
//--------------------------------------------------------export--------------------------------------------------------
|
|
window['AscWord'] = window['AscWord'] || {};
|
|
window['AscWord'].CAbstractNum = CAbstractNum;
|