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;
|