1401 lines
40 KiB
JavaScript
1401 lines
40 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";
|
|
|
|
(function(window)
|
|
{
|
|
let elementToCheck = {};
|
|
function checkElementInRevision(element)
|
|
{
|
|
if (!element)
|
|
return;
|
|
|
|
let logicDocument = element.GetLogicDocument();
|
|
if (!element.GetLogicDocument())
|
|
{
|
|
elementToCheck[element.GetId()] = element;
|
|
return;
|
|
}
|
|
|
|
if (!logicDocument || !logicDocument.IsDocumentEditor())
|
|
return;
|
|
|
|
logicDocument.GetTrackRevisionsManager().CheckElement(element);
|
|
}
|
|
function haveElementToCheck()
|
|
{
|
|
for (let id in elementToCheck)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
function flushElementToCheck()
|
|
{
|
|
for (let id in elementToCheck)
|
|
{
|
|
let element = elementToCheck[id];
|
|
let logicDocument = element.GetLogicDocument();
|
|
if (!logicDocument || !logicDocument.IsDocumentEditor())
|
|
continue;
|
|
|
|
logicDocument.GetTrackRevisionsManager().CheckElement(elementToCheck[id]);
|
|
}
|
|
|
|
elementToCheck = {};
|
|
}
|
|
|
|
// ВАЖНО: CheckArray - специальный массив-дублер для мапа CheckMap, для более быстрого выполнения функции
|
|
// ContinueTrackRevisions. Заметим, что на функции CompleteTrackChangesForElements мы не выкидываем
|
|
// элемент из CheckArray, но выкидываем из CheckMap. Это не страшно, т.к. при последующей проверке по
|
|
// массиву CheckArray элемент в CheckMap просто не найдется, а из CheckArray мы его выкинем, и, тем самым,
|
|
// CheckArray и CheckMap синхронизуются.
|
|
|
|
/**
|
|
* Класс для отслеживания изменений в режиме рецензирования
|
|
* @param {AscWord.CDocument} oLogicDocument
|
|
* @constructor
|
|
*/
|
|
function CTrackRevisionsManager(oLogicDocument)
|
|
{
|
|
this.LogicDocument = oLogicDocument;
|
|
|
|
this.CheckMap = {}; // Элементы, которые нужно проверить
|
|
this.CheckArray = []; // Дублирующий массив элементов, которые мы проверяем в ContinueTrackRevisions
|
|
|
|
this.Changes = {}; // Объект с ключом - Id параграфа, в котором лежит массив изменений
|
|
this.ChangesOutline = []; // Упорядоченный массив с объектами, в которых есть изменения в рецензировании
|
|
this.CurChange = null; // Текущее изменение
|
|
this.CurElement = null; // Элемент с текущим изменением
|
|
|
|
this.SelectedChanges = []; // Список изменений, попавших в выделение
|
|
this.PrevSelectedChanges = [];
|
|
this.PrevShowChanges = true;
|
|
|
|
this.MoveId = 1;
|
|
this.MoveMarks = {};
|
|
this.ProcessMove = null;
|
|
|
|
this.SkipPreDeleteMoveMarks = false;
|
|
}
|
|
|
|
/**
|
|
* Отправляем элемент на проверку на наличие рецензирования
|
|
* @param oElement {AscWord.Paragraph | AscWord.CTable}
|
|
*/
|
|
CTrackRevisionsManager.prototype.CheckElement = function(oElement)
|
|
{
|
|
if (!(oElement instanceof AscWord.Paragraph) && !(oElement instanceof AscWord.CTable))
|
|
return;
|
|
|
|
let Id = oElement.GetId();
|
|
if (!this.CheckMap[Id])
|
|
{
|
|
this.CheckMap[Id] = oElement;
|
|
this.CheckArray.push(oElement);
|
|
}
|
|
};
|
|
/**
|
|
* Добавляем изменение в рецензировании по Id элемента
|
|
* @param sId {string}
|
|
* @param oChange {CRevisionsChange}
|
|
*/
|
|
CTrackRevisionsManager.prototype.AddChange = function(sId, oChange)
|
|
{
|
|
if (this.private_CheckChangeObject(sId))
|
|
this.Changes[sId].push(oChange);
|
|
};
|
|
/**
|
|
* Получаем массив изменений заданного элемента
|
|
* @param sElementId
|
|
* @returns {CRevisionsChange[]}
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetElementChanges = function(sElementId)
|
|
{
|
|
if (this.Changes[sElementId])
|
|
return this.Changes[sElementId];
|
|
|
|
return [];
|
|
};
|
|
CTrackRevisionsManager.prototype.ContinueTrackRevisions = function(isComplete)
|
|
{
|
|
if (this.IsAllChecked())
|
|
return;
|
|
|
|
flushElementToCheck();
|
|
|
|
var nStartTime = performance.now();
|
|
|
|
// За раз обрабатываем не больше 500 параграфов либо не больше 4мс по времени,
|
|
// чтобы не подвешивать клиент на открытии файлов
|
|
const nMaxCounter = 500;
|
|
let nCounter = 0;
|
|
|
|
var bNeedUpdate = false;
|
|
|
|
let nIndex = this.CheckArray.length - 1;
|
|
for (; nIndex >= 0; --nIndex)
|
|
{
|
|
if (this.private_TrackChangesForSingleElement(this.CheckArray[nIndex].GetId()))
|
|
bNeedUpdate = true;
|
|
|
|
if (true !== isComplete)
|
|
{
|
|
++nCounter;
|
|
if (nCounter >= nMaxCounter || (performance.now() - nStartTime) > 4)
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.CheckArray.length = nIndex < 0 ? 0 : nIndex;
|
|
|
|
// TODO: Сделать нормальную проверку, что текущий параграф или текущее выделение попала в проверенные элементы
|
|
//if (bNeedUpdate)
|
|
this.LogicDocument.UpdateInterface();
|
|
};
|
|
/**
|
|
* Ищем следующее изменение
|
|
* @returns {?CRevisionsChange}
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetNextChange = function()
|
|
{
|
|
if (this.CurChange && this.CurChange.IsComplexChange())
|
|
{
|
|
var arrChanges = this.CurChange.GetSimpleChanges();
|
|
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
|
|
if (arrChanges.length > 0)
|
|
{
|
|
this.CurChange = arrChanges[arrChanges.length - 1];
|
|
this.CurElement = this.CurChange.GetElement();
|
|
|
|
if (!this.CurElement || !this.Changes[this.CurElement.GetId()])
|
|
{
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
var oChange = this.private_GetNextChange();
|
|
if (oChange && oChange.IsMove() && !oChange.IsComplexChange())
|
|
{
|
|
oChange = this.CollectMoveChange(oChange);
|
|
this.CurChange = oChange;
|
|
}
|
|
|
|
return oChange;
|
|
};
|
|
CTrackRevisionsManager.prototype.private_GetNextChange = function()
|
|
{
|
|
var oInitialCurChange = this.CurChange;
|
|
var oInitialCurElement = this.CurElement;
|
|
|
|
var oNextElement = null;
|
|
if (null !== this.CurChange && null !== this.CurElement && this.Changes[this.CurElement.GetId()])
|
|
{
|
|
var arrChangesArray = this.Changes[this.CurElement.GetId()];
|
|
|
|
var nChangeIndex = -1;
|
|
for (var nIndex = 0, nCount = arrChangesArray.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (this.CurChange === arrChangesArray[nIndex])
|
|
{
|
|
nChangeIndex = nIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (-1 !== nChangeIndex && nChangeIndex < arrChangesArray.length - 1)
|
|
{
|
|
this.CurChange = arrChangesArray[nChangeIndex + 1];
|
|
return this.CurChange;
|
|
}
|
|
|
|
oNextElement = this.LogicDocument.GetRevisionsChangeElement(1, this.CurElement);
|
|
}
|
|
else
|
|
{
|
|
var oSearchEngine = this.LogicDocument.private_GetRevisionsChangeElement(1, null);
|
|
oNextElement = oSearchEngine.GetFoundedElement();
|
|
if (null !== oNextElement && oNextElement === oSearchEngine.GetCurrentElement())
|
|
{
|
|
var arrNextChangesArray = this.Changes[oNextElement.GetId()];
|
|
if (arrNextChangesArray && arrNextChangesArray.length > 0)
|
|
{
|
|
if (oNextElement instanceof Paragraph)
|
|
{
|
|
var ParaContentPos = oNextElement.Get_ParaContentPos(oNextElement.IsSelectionUse(), true);
|
|
for (var nChangeIndex = 0, nCount = arrNextChangesArray.length; nChangeIndex < nCount; ++nChangeIndex)
|
|
{
|
|
var ChangeEndPos = arrNextChangesArray[nChangeIndex].get_EndPos();
|
|
if (ParaContentPos.Compare(ChangeEndPos) <= 0)
|
|
{
|
|
this.CurChange = arrNextChangesArray[nChangeIndex];
|
|
this.CurElement = oNextElement;
|
|
return this.CurChange;
|
|
}
|
|
}
|
|
}
|
|
else if (oNextElement instanceof CTable && oNextElement.IsCellSelection())
|
|
{
|
|
var arrSelectedCells = oNextElement.GetSelectionArray();
|
|
if (arrSelectedCells.length > 0)
|
|
{
|
|
var nTableRow = arrSelectedCells[0].Row;
|
|
for (var nChangeIndex = 0, nCount = arrNextChangesArray.length; nChangeIndex < nCount; ++nChangeIndex)
|
|
{
|
|
var nStartRow = arrNextChangesArray[nChangeIndex].get_StartPos();
|
|
if (nTableRow <= nStartRow)
|
|
{
|
|
this.CurChange = arrNextChangesArray[nChangeIndex];
|
|
this.CurElement = oNextElement;
|
|
return this.CurChange;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
oNextElement = this.LogicDocument.GetRevisionsChangeElement(1, oNextElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (null !== oNextElement)
|
|
{
|
|
var arrNextChangesArray = this.Changes[oNextElement.GetId()];
|
|
if (arrNextChangesArray && arrNextChangesArray.length > 0)
|
|
{
|
|
this.CurChange = arrNextChangesArray[0];
|
|
this.CurElement = oNextElement;
|
|
return this.CurChange;
|
|
}
|
|
}
|
|
|
|
if (null !== oInitialCurChange && null !== oInitialCurElement)
|
|
{
|
|
this.CurChange = oInitialCurChange;
|
|
this.CurElement = oInitialCurElement;
|
|
return oInitialCurChange;
|
|
}
|
|
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
return null;
|
|
};
|
|
/**
|
|
* Ищем следующее изменение
|
|
* @returns {?CRevisionsChange}
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetPrevChange = function()
|
|
{
|
|
if (this.CurChange && this.CurChange.IsComplexChange())
|
|
{
|
|
var arrChanges = this.CurChange.GetSimpleChanges();
|
|
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
|
|
if (arrChanges.length > 0)
|
|
{
|
|
this.CurChange = arrChanges[0];
|
|
this.CurElement = this.CurChange.GetElement();
|
|
|
|
if (!this.CurElement || !this.Changes[this.CurElement.GetId()])
|
|
{
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
var oChange = this.private_GetPrevChange();
|
|
if (oChange && oChange.IsMove() && !oChange.IsComplexChange())
|
|
{
|
|
oChange = this.CollectMoveChange(oChange);
|
|
this.CurChange = oChange;
|
|
}
|
|
|
|
return oChange;
|
|
};
|
|
CTrackRevisionsManager.prototype.private_GetPrevChange = function()
|
|
{
|
|
var oInitialCurChange = this.CurChange;
|
|
var oInitialCurElement = this.CurElement;
|
|
|
|
var oPrevElement = null;
|
|
if (null !== this.CurChange && null !== this.CurElement)
|
|
{
|
|
var arrChangesArray = this.Changes[this.CurElement.GetId()];
|
|
var nChangeIndex = -1;
|
|
for (var nIndex = 0, nCount = arrChangesArray.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (this.CurChange === arrChangesArray[nIndex])
|
|
{
|
|
nChangeIndex = nIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (-1 !== nChangeIndex && nChangeIndex > 0)
|
|
{
|
|
this.CurChange = arrChangesArray[nChangeIndex - 1];
|
|
return this.CurChange;
|
|
}
|
|
|
|
oPrevElement = this.LogicDocument.GetRevisionsChangeElement(-1, this.CurElement);
|
|
}
|
|
else
|
|
{
|
|
var SearchEngine = this.LogicDocument.private_GetRevisionsChangeElement(-1, null);
|
|
oPrevElement = SearchEngine.GetFoundedElement();
|
|
if (null !== oPrevElement && oPrevElement === SearchEngine.GetCurrentElement())
|
|
{
|
|
var arrPrevChangesArray = this.Changes[oPrevElement.GetId()];
|
|
if (undefined !== arrPrevChangesArray && arrPrevChangesArray.length > 0)
|
|
{
|
|
if (oPrevElement instanceof Paragraph)
|
|
{
|
|
var ParaContentPos = oPrevElement.Get_ParaContentPos(oPrevElement.IsSelectionUse(), true);
|
|
for (var ChangeIndex = arrPrevChangesArray.length - 1; ChangeIndex >= 0; ChangeIndex--)
|
|
{
|
|
var ChangeStartPos = arrPrevChangesArray[ChangeIndex].get_StartPos();
|
|
if (ParaContentPos.Compare(ChangeStartPos) >= 0)
|
|
{
|
|
this.CurChange = arrPrevChangesArray[ChangeIndex];
|
|
this.CurElement = oPrevElement;
|
|
return this.CurChange;
|
|
}
|
|
}
|
|
}
|
|
else if (oPrevElement instanceof CTable && oPrevElement.IsCellSelection())
|
|
{
|
|
var arrSelectedCells = oPrevElement.GetSelectionArray();
|
|
if (arrSelectedCells.length > 0)
|
|
{
|
|
var nTableRow = arrSelectedCells[0].Row;
|
|
for (var nChangeIndex = arrPrevChangesArray.length - 1; nChangeIndex >= 0; --nChangeIndex)
|
|
{
|
|
var nStartRow = arrPrevChangesArray[nChangeIndex].get_StartPos();
|
|
if (nTableRow >= nStartRow)
|
|
{
|
|
this.CurChange = arrPrevChangesArray[nChangeIndex];
|
|
this.CurElement = oPrevElement;
|
|
return this.CurChange;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
oPrevElement = this.LogicDocument.GetRevisionsChangeElement(-1, oPrevElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (null !== oPrevElement)
|
|
{
|
|
var arrPrevChangesArray = this.Changes[oPrevElement.GetId()];
|
|
if (undefined !== arrPrevChangesArray && arrPrevChangesArray.length > 0)
|
|
{
|
|
this.CurChange = arrPrevChangesArray[arrPrevChangesArray.length - 1];
|
|
this.CurElement = oPrevElement;
|
|
return this.CurChange;
|
|
}
|
|
}
|
|
|
|
if (null !== oInitialCurChange && null !== oInitialCurElement)
|
|
{
|
|
this.CurChange = oInitialCurChange;
|
|
this.CurElement = oInitialCurElement;
|
|
return oInitialCurChange;
|
|
}
|
|
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
return null;
|
|
};
|
|
/**
|
|
* Проверяем есть ли непримененные изменения в документе
|
|
* @returns {boolean}
|
|
*/
|
|
CTrackRevisionsManager.prototype.Have_Changes = function()
|
|
{
|
|
var oTableId = this.LogicDocument ? this.LogicDocument.GetTableId() : null;
|
|
|
|
for (var sElementId in this.Changes)
|
|
{
|
|
var oElement = oTableId ? oTableId.Get_ById(sElementId) : null;
|
|
|
|
if (!oElement || !oElement.IsUseInDocument || !oElement.IsUseInDocument())
|
|
continue;
|
|
|
|
if (this.Changes[sElementId].length > 0)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
/**
|
|
* Проверяем есть ли изменения, сделанные другими пользователями
|
|
* @returns {boolean}
|
|
*/
|
|
CTrackRevisionsManager.prototype.HaveOtherUsersChanges = function()
|
|
{
|
|
var sUserId = this.LogicDocument.GetUserId(false);
|
|
for (var sParaId in this.Changes)
|
|
{
|
|
var oParagraph = AscCommon.g_oTableId.Get_ById(sParaId);
|
|
if (!oParagraph || !oParagraph.IsUseInDocument())
|
|
continue;
|
|
|
|
for (var nIndex = 0, nCount = this.Changes[sParaId].length; nIndex < nCount; ++nIndex)
|
|
{
|
|
var oChange = this.Changes[sParaId][nIndex];
|
|
if (oChange.get_UserId() !== sUserId)
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
CTrackRevisionsManager.prototype.ClearCurrentChange = function()
|
|
{
|
|
this.CurChange = null;
|
|
this.CurElement = null;
|
|
};
|
|
CTrackRevisionsManager.prototype.SetCurrentChange = function(oCurChange)
|
|
{
|
|
if (oCurChange)
|
|
{
|
|
this.CurChange = oCurChange;
|
|
this.CurElement = oCurChange.GetElement();
|
|
}
|
|
};
|
|
CTrackRevisionsManager.prototype.GetCurrentChangeElement = function()
|
|
{
|
|
return this.CurElement;
|
|
};
|
|
CTrackRevisionsManager.prototype.GetCurrentChange = function()
|
|
{
|
|
return this.CurChange;
|
|
};
|
|
CTrackRevisionsManager.prototype.InitSelectedChanges = function()
|
|
{
|
|
var oEditorApi = this.LogicDocument.GetApi();
|
|
if (!oEditorApi)
|
|
return;
|
|
|
|
oEditorApi.sync_BeginCatchRevisionsChanges();
|
|
oEditorApi.sync_EndCatchRevisionsChanges();
|
|
};
|
|
CTrackRevisionsManager.prototype.ClearSelectedChanges = function()
|
|
{
|
|
if (this.SelectedChanges.length > 0)
|
|
{
|
|
var oEditorApi = this.LogicDocument.GetApi();
|
|
if (!oEditorApi)
|
|
return;
|
|
|
|
oEditorApi.sync_BeginCatchRevisionsChanges();
|
|
oEditorApi.sync_EndCatchRevisionsChanges();
|
|
}
|
|
|
|
this.SelectedChanges = [];
|
|
};
|
|
/**
|
|
* Добавляем изменение, видимое в текущей позиции
|
|
* @param oChange
|
|
*/
|
|
CTrackRevisionsManager.prototype.AddSelectedChange = function(oChange)
|
|
{
|
|
if (this.CurChange)
|
|
return;
|
|
|
|
if (oChange && c_oAscRevisionsChangeType.MoveMark === oChange.get_Type())
|
|
return;
|
|
|
|
if (oChange.IsMove() && !oChange.IsComplexChange())
|
|
oChange = this.CollectMoveChange(oChange);
|
|
|
|
for (var nIndex = 0, nCount = this.SelectedChanges.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
var oVisChange = this.SelectedChanges[nIndex];
|
|
if (oVisChange.IsComplexChange() && !oChange.IsComplexChange())
|
|
{
|
|
var arrSimpleChanges = oVisChange.GetSimpleChanges();
|
|
for (var nSimpleIndex = 0, nSimpleCount = arrSimpleChanges.length; nSimpleIndex < nSimpleCount; ++nSimpleIndex)
|
|
{
|
|
if (arrSimpleChanges[nSimpleIndex] === oChange)
|
|
return;
|
|
}
|
|
}
|
|
else if (!oVisChange.IsComplexChange() && oChange.IsComplexChange())
|
|
{
|
|
var arrSimpleChanges = oChange.GetSimpleChanges();
|
|
for (var nSimpleIndex = 0, nSimpleCount = arrSimpleChanges.length; nSimpleIndex < nSimpleCount; ++nSimpleIndex)
|
|
{
|
|
if (arrSimpleChanges[nSimpleIndex] === oVisChange)
|
|
{
|
|
this.SelectedChanges.splice(nIndex, 1);
|
|
nCount--;
|
|
nIndex--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (oVisChange.IsComplexChange() && oChange.IsComplexChange())
|
|
{
|
|
var arrVisSC = oVisChange.GetSimpleChanges();
|
|
var arrChangeSC = oChange.GetSimpleChanges();
|
|
|
|
var isEqual = false;
|
|
if (arrVisSC.length === arrChangeSC.length)
|
|
{
|
|
isEqual = true;
|
|
for (var nSimpleIndex = 0, nSimplesCount = arrVisSC.length; nSimpleIndex < nSimplesCount; ++nSimpleIndex)
|
|
{
|
|
if (arrVisSC[nSimpleIndex] !== arrChangeSC[nSimpleIndex])
|
|
{
|
|
isEqual = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isEqual)
|
|
return;
|
|
}
|
|
else if (oChange === oVisChange)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.SelectedChanges.push(oChange);
|
|
};
|
|
CTrackRevisionsManager.prototype.GetSelectedChanges = function()
|
|
{
|
|
return this.SelectedChanges;
|
|
};
|
|
CTrackRevisionsManager.prototype.BeginCollectChanges = function(bSaveCurrentChange)
|
|
{
|
|
if (!this.IsAllChecked())
|
|
return;
|
|
|
|
this.PrevSelectedChanges = this.SelectedChanges;
|
|
this.SelectedChanges = [];
|
|
|
|
if (true !== bSaveCurrentChange)
|
|
{
|
|
this.ClearCurrentChange();
|
|
}
|
|
else if (this.CurElement && this.CurChange)
|
|
{
|
|
var oSelectionBounds = this.CurElement.GetSelectionBounds();
|
|
|
|
var oBounds = oSelectionBounds.Direction > 0 ? oSelectionBounds.Start : oSelectionBounds.End;
|
|
|
|
if (oBounds)
|
|
{
|
|
var X = this.LogicDocument.Get_PageLimits(oBounds.Page).XLimit;
|
|
this.CurChange.put_InternalPos(X, oBounds.Y, oBounds.Page);
|
|
this.SelectedChanges.push(this.CurChange);
|
|
}
|
|
}
|
|
};
|
|
CTrackRevisionsManager.prototype.EndCollectChanges = function()
|
|
{
|
|
if (!this.IsAllChecked())
|
|
return;
|
|
|
|
var oEditor = this.LogicDocument.GetApi();
|
|
if (this.CurChange)
|
|
this.SelectedChanges = [this.CurChange];
|
|
|
|
var isPositionChanged = false;
|
|
var isArrayChanged = false;
|
|
var isShowChanges = this.CurChange || !this.LogicDocument.IsTextSelectionUse();
|
|
|
|
var nChangesCount = this.SelectedChanges.length;
|
|
if (this.PrevSelectedChanges.length !== nChangesCount || this.PrevShowChanges !== isShowChanges)
|
|
{
|
|
isArrayChanged = true;
|
|
}
|
|
else if (0 !== nChangesCount)
|
|
{
|
|
for (var nChangeIndex = 0; nChangeIndex < nChangesCount; ++nChangeIndex)
|
|
{
|
|
if (this.SelectedChanges[nChangeIndex] !== this.PrevSelectedChanges[nChangeIndex])
|
|
{
|
|
isArrayChanged = true;
|
|
break;
|
|
}
|
|
else if (this.SelectedChanges[nChangeIndex].IsPositionChanged())
|
|
{
|
|
isPositionChanged = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isArrayChanged)
|
|
{
|
|
oEditor.sync_BeginCatchRevisionsChanges();
|
|
|
|
if (nChangesCount > 0)
|
|
{
|
|
var oPos = this.private_GetSelectedChangesXY();
|
|
for (var ChangeIndex = 0; ChangeIndex < nChangesCount; ChangeIndex++)
|
|
{
|
|
var Change = this.SelectedChanges[ChangeIndex];
|
|
Change.put_XY(oPos.X, oPos.Y);
|
|
oEditor.sync_AddRevisionsChange(Change);
|
|
}
|
|
}
|
|
oEditor.sync_EndCatchRevisionsChanges(isShowChanges);
|
|
}
|
|
else if (isPositionChanged)
|
|
{
|
|
this.UpdateSelectedChangesPosition(oEditor);
|
|
}
|
|
|
|
this.PrevShowChanges = isShowChanges;
|
|
};
|
|
CTrackRevisionsManager.prototype.UpdateSelectedChangesPosition = function(oEditor)
|
|
{
|
|
if (this.SelectedChanges.length > 0)
|
|
{
|
|
var oPos = this.private_GetSelectedChangesXY();
|
|
oEditor.sync_UpdateRevisionsChangesPosition(oPos.X, oPos.Y);
|
|
}
|
|
};
|
|
CTrackRevisionsManager.prototype.private_GetSelectedChangesXY = function()
|
|
{
|
|
if (!this.SelectedChanges.length)
|
|
return {X : 0, Y : 0};
|
|
|
|
let change = this.SelectedChanges[0];
|
|
|
|
let element = change.GetElement();
|
|
if (!element)
|
|
return {X : 0, Y : 0};
|
|
|
|
let x = change.GetInternalPosX();
|
|
let y = change.GetInternalPosY();
|
|
let page = change.GetInternalPosPageNum();
|
|
|
|
let transform = element.Get_ParentTextTransform();
|
|
if (transform)
|
|
y = transform.TransformPointY(x, y);
|
|
|
|
let drawingCoords = this.LogicDocument.getDrawingDocument().ConvertCoordsToCursorWR(x, y, page);
|
|
return {X : drawingCoords.X, Y : drawingCoords.Y};
|
|
};
|
|
CTrackRevisionsManager.prototype.Get_AllChangesLogicDocuments = function()
|
|
{
|
|
this.CompleteTrackChanges();
|
|
var LogicDocuments = {};
|
|
|
|
for (var ParaId in this.Changes)
|
|
{
|
|
var Para = AscCommon.g_oTableId.Get_ById(ParaId);
|
|
if (Para && Para.Get_Parent())
|
|
{
|
|
LogicDocuments[Para.Get_Parent().Get_Id()] = true;
|
|
}
|
|
}
|
|
|
|
return LogicDocuments;
|
|
};
|
|
CTrackRevisionsManager.prototype.GetChangeRelatedParagraphs = function(oChange, bAccept)
|
|
{
|
|
var oRelatedParas = {};
|
|
|
|
if (oChange.IsComplexChange())
|
|
{
|
|
var arrSimpleChanges = oChange.GetSimpleChanges();
|
|
for (var nIndex = 0, nCount = arrSimpleChanges.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
this.private_GetChangeRelatedParagraphs(arrSimpleChanges[nIndex], bAccept, oRelatedParas);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.private_GetChangeRelatedParagraphs(oChange, bAccept, oRelatedParas);
|
|
}
|
|
|
|
return this.private_ConvertParagraphsObjectToArray(oRelatedParas);
|
|
};
|
|
CTrackRevisionsManager.prototype.private_GetChangeRelatedParagraphs = function(oChange, bAccept, oRelatedParas)
|
|
{
|
|
if (oChange)
|
|
{
|
|
var nType = oChange.GetType();
|
|
var oElement = oChange.GetElement();
|
|
if (oElement && oElement.IsUseInDocument())
|
|
{
|
|
oRelatedParas[oElement.GetId()] = true;
|
|
if ((c_oAscRevisionsChangeType.ParaAdd === nType && true !== bAccept) || (c_oAscRevisionsChangeType.ParaRem === nType && true === bAccept))
|
|
{
|
|
var oLogicDocument = oElement.GetParent();
|
|
var nParaIndex = oElement.GetIndex();
|
|
|
|
if (oLogicDocument && -1 !== nParaIndex)
|
|
{
|
|
if (nParaIndex < oLogicDocument.GetElementsCount() - 1)
|
|
{
|
|
var oNextElement = oLogicDocument.GetElement(nParaIndex + 1);
|
|
if (oNextElement && oNextElement.IsParagraph())
|
|
oRelatedParas[oNextElement.GetId()] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
CTrackRevisionsManager.prototype.private_ConvertParagraphsObjectToArray = function(ParagraphsObject)
|
|
{
|
|
var ParagraphsArray = [];
|
|
for (var ParaId in ParagraphsObject)
|
|
{
|
|
var Para = AscCommon.g_oTableId.Get_ById(ParaId);
|
|
if (null !== Para)
|
|
{
|
|
ParagraphsArray.push(Para);
|
|
}
|
|
}
|
|
return ParagraphsArray;
|
|
};
|
|
CTrackRevisionsManager.prototype.Get_AllChangesRelatedParagraphs = function(bAccept)
|
|
{
|
|
var RelatedParas = {};
|
|
for (var ParaId in this.Changes)
|
|
{
|
|
for (var ChangeIndex = 0, ChangesCount = this.Changes[ParaId].length; ChangeIndex < ChangesCount; ++ChangeIndex)
|
|
{
|
|
var Change = this.Changes[ParaId][ChangeIndex];
|
|
this.private_GetChangeRelatedParagraphs(Change, bAccept, RelatedParas);
|
|
}
|
|
}
|
|
return this.private_ConvertParagraphsObjectToArray(RelatedParas);
|
|
};
|
|
CTrackRevisionsManager.prototype.Get_AllChangesRelatedParagraphsBySelectedParagraphs = function(SelectedParagraphs, bAccept)
|
|
{
|
|
var RelatedParas = {};
|
|
for (var ParaIndex = 0, ParasCount = SelectedParagraphs.length; ParaIndex < ParasCount; ++ParaIndex)
|
|
{
|
|
var Para = SelectedParagraphs[ParaIndex];
|
|
var ParaId = Para.Get_Id();
|
|
if (this.Changes[ParaId] && this.Changes[ParaId].length > 0)
|
|
{
|
|
RelatedParas[ParaId] = true;
|
|
if (true === Para.Selection_CheckParaEnd())
|
|
{
|
|
var CheckNext = false;
|
|
for (var ChangeIndex = 0, ChangesCount = this.Changes[ParaId].length; ChangeIndex < ChangesCount; ++ChangeIndex)
|
|
{
|
|
var ChangeType = this.Changes[ParaId][ChangeIndex].get_Type();
|
|
if ((c_oAscRevisionsChangeType.ParaAdd === ChangeType && true !== bAccept) || (c_oAscRevisionsChangeType.ParaRem === ChangeType && true === bAccept))
|
|
{
|
|
CheckNext = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (true === CheckNext)
|
|
{
|
|
var NextElement = Para.Get_DocumentNext();
|
|
if (null !== NextElement && type_Paragraph === NextElement.Get_Type())
|
|
{
|
|
RelatedParas[NextElement.Get_Id()] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return this.private_ConvertParagraphsObjectToArray(RelatedParas);
|
|
};
|
|
CTrackRevisionsManager.prototype.Get_AllChanges = function()
|
|
{
|
|
this.CompleteTrackChanges();
|
|
return this.Changes;
|
|
};
|
|
CTrackRevisionsManager.prototype.IsAllChecked = function()
|
|
{
|
|
return (!this.CheckArray.length && !haveElementToCheck());
|
|
};
|
|
/**
|
|
* Завершаем проверку всех элементов на наличие рецензирования
|
|
*/
|
|
CTrackRevisionsManager.prototype.CompleteTrackChanges = function()
|
|
{
|
|
while (!this.IsAllChecked())
|
|
this.ContinueTrackRevisions();
|
|
};
|
|
/**
|
|
* Завершаем проверку рецензирования для заданных элементов
|
|
* @param arrElements
|
|
* @returns {boolean}
|
|
*/
|
|
CTrackRevisionsManager.prototype.CompleteTrackChangesForElements = function(arrElements)
|
|
{
|
|
var isChecked = false;
|
|
for (var nIndex = 0, nCount = arrElements.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (this.private_TrackChangesForSingleElement(arrElements[nIndex].GetId()))
|
|
isChecked = true;
|
|
}
|
|
|
|
return isChecked;
|
|
};
|
|
CTrackRevisionsManager.prototype.private_TrackChangesForSingleElement = function(Id)
|
|
{
|
|
if (!this.CheckMap[Id])
|
|
return false;
|
|
|
|
let oElement = this.CheckMap[Id];
|
|
|
|
delete this.CheckMap[Id];
|
|
|
|
if (!oElement.IsUseInDocument())
|
|
return false;
|
|
|
|
let isHaveChanges = !!this.Changes[Id];
|
|
|
|
this.private_RemoveChangeObject(Id);
|
|
oElement.CheckRevisionsChanges(this);
|
|
|
|
return !(!isHaveChanges && !this.Changes[Id]);
|
|
};
|
|
/**
|
|
* При чтении файла обновляем Id перетаскиваний в рецензировании
|
|
* @param sMoveId
|
|
*/
|
|
CTrackRevisionsManager.prototype.UpdateMoveId = function(sMoveId)
|
|
{
|
|
if (0 === sMoveId.indexOf("move"))
|
|
{
|
|
var nId = parseInt(sMoveId.substring(4));
|
|
if (!isNaN(nId))
|
|
this.MoveId = Math.max(this.MoveId, nId);
|
|
}
|
|
};
|
|
/**
|
|
* Возвращаем новый идентификатор перемещений
|
|
* @returns {string}
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetNewMoveId = function()
|
|
{
|
|
this.MoveId++;
|
|
return "move" + this.MoveId;
|
|
};
|
|
CTrackRevisionsManager.prototype.RegisterMoveMark = function(oMark)
|
|
{
|
|
if (this.LogicDocument && this.LogicDocument.PrintSelection)
|
|
return;
|
|
|
|
if (!oMark)
|
|
return;
|
|
|
|
var sMarkId = oMark.GetMarkId();
|
|
var isFrom = oMark.IsFrom();
|
|
var isStart = oMark.IsStart();
|
|
|
|
this.UpdateMoveId(sMarkId);
|
|
|
|
if (!this.MoveMarks[sMarkId])
|
|
{
|
|
this.MoveMarks[sMarkId] = {
|
|
|
|
From : {
|
|
Start : null,
|
|
End : null
|
|
},
|
|
|
|
To : {
|
|
Start : null,
|
|
End : null
|
|
}
|
|
};
|
|
}
|
|
|
|
if (isFrom)
|
|
{
|
|
if (isStart)
|
|
this.MoveMarks[sMarkId].From.Start = oMark;
|
|
else
|
|
this.MoveMarks[sMarkId].From.End = oMark;
|
|
}
|
|
else
|
|
{
|
|
if (isStart)
|
|
this.MoveMarks[sMarkId].To.Start = oMark;
|
|
else
|
|
this.MoveMarks[sMarkId].To.End = oMark;
|
|
}
|
|
};
|
|
CTrackRevisionsManager.prototype.UnregisterMoveMark = function(oMark)
|
|
{
|
|
if (this.LogicDocument && this.LogicDocument.PrintSelection)
|
|
return;
|
|
|
|
if (!oMark)
|
|
return;
|
|
|
|
var sMarkId = oMark.GetMarkId();
|
|
delete this.MoveMarks[sMarkId];
|
|
|
|
// TODO: Возможно тут нужно проделать дополнительные действия
|
|
};
|
|
CTrackRevisionsManager.prototype.private_CheckChangeObject = function(sId)
|
|
{
|
|
var oElement = AscCommon.g_oTableId.Get_ById(sId);
|
|
if (!oElement)
|
|
return false;
|
|
|
|
if (!this.Changes[sId])
|
|
this.Changes[sId] = [];
|
|
|
|
var nDeletePosition = -1;
|
|
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (this.ChangesOutline[nIndex].GetId() === sId)
|
|
{
|
|
nDeletePosition = nIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
var oDocPos = oElement.GetDocumentPositionFromObject();
|
|
if (!oDocPos)
|
|
return;
|
|
|
|
var nAddPosition = -1;
|
|
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
var oTempDocPos = this.ChangesOutline[nIndex].GetDocumentPositionFromObject();
|
|
|
|
if (this.private_CompareDocumentPositions(oDocPos, oTempDocPos) < 0)
|
|
{
|
|
nAddPosition = nIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (-1 === nAddPosition)
|
|
nAddPosition = this.ChangesOutline.length;
|
|
|
|
if (nAddPosition === nDeletePosition || (-1 !== nAddPosition && -1 !== nDeletePosition && nDeletePosition === nAddPosition - 1))
|
|
return true;
|
|
|
|
if (-1 !== nDeletePosition)
|
|
{
|
|
this.ChangesOutline.splice(nDeletePosition, 1);
|
|
|
|
if (nAddPosition > nDeletePosition)
|
|
nAddPosition--;
|
|
}
|
|
|
|
this.ChangesOutline.splice(nAddPosition, 0, oElement);
|
|
|
|
return true;
|
|
};
|
|
CTrackRevisionsManager.prototype.private_CompareDocumentPositions = function(oDocPos1, oDocPos2)
|
|
{
|
|
if (oDocPos1.Class !== oDocPos2.Class)
|
|
{
|
|
// TODO: Здесь нужно доработать сравнение позиций, когда они из разных частей документа
|
|
if (oDocPos1.Class instanceof CDocument)
|
|
return -1;
|
|
else if (oDocPos1.Class instanceof CDocument)
|
|
return 1;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
for (var nIndex = 0, nCount = oDocPos1.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (oDocPos2.length <= nIndex)
|
|
return 1;
|
|
|
|
if (oDocPos1[nIndex].Position < oDocPos2[nIndex].Position)
|
|
return -1;
|
|
else if (oDocPos1[nIndex].Position > oDocPos2[nIndex].Position)
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
CTrackRevisionsManager.prototype.private_RemoveChangeObject = function(sId)
|
|
{
|
|
if (this.Changes[sId])
|
|
delete this.Changes[sId];
|
|
|
|
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (this.ChangesOutline[nIndex].GetId() === sId)
|
|
{
|
|
this.ChangesOutline.splice(nIndex, 1);
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Собираем изменение связанное с переносом
|
|
* @param {CRevisionsChange} oChange
|
|
* @returns {CRevisionsChange}
|
|
*/
|
|
CTrackRevisionsManager.prototype.CollectMoveChange = function(oChange)
|
|
{
|
|
var isFrom = c_oAscRevisionsChangeType.TextRem === oChange.GetType() || c_oAscRevisionsChangeType.ParaRem === oChange.GetType() || (c_oAscRevisionsChangeType.MoveMark === oChange.GetType() && oChange.GetValue().IsFrom());
|
|
|
|
var nStartIndex = -1;
|
|
var oStartChange = null;
|
|
|
|
var oElement = oChange.GetElement();
|
|
if (!oElement)
|
|
return oChange;
|
|
|
|
var nDeep = 0;
|
|
var nSearchIndex = -1;
|
|
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
if (this.ChangesOutline[nIndex] === oElement)
|
|
{
|
|
nSearchIndex = nIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (-1 === nSearchIndex)
|
|
return oChange;
|
|
|
|
var isStart = false;
|
|
|
|
for (var nIndex = nSearchIndex; nIndex >= 0; --nIndex)
|
|
{
|
|
var arrCurChanges = this.Changes[this.ChangesOutline[nIndex].GetId()];
|
|
|
|
if (!arrCurChanges)
|
|
{
|
|
isStart = true;
|
|
continue;
|
|
}
|
|
|
|
for (var nChangeIndex = arrCurChanges.length - 1; nChangeIndex >= 0; --nChangeIndex)
|
|
{
|
|
var oCurChange = arrCurChanges[nChangeIndex];
|
|
if (!isStart)
|
|
{
|
|
if (oCurChange === oChange)
|
|
isStart = true;
|
|
}
|
|
|
|
if (isStart)
|
|
{
|
|
var nCurChangeType = oCurChange.GetType();
|
|
if (nCurChangeType === c_oAscRevisionsChangeType.MoveMark)
|
|
{
|
|
var oMoveMark = oCurChange.GetValue();
|
|
if ((isFrom && oMoveMark.IsFrom()) || (!isFrom && !oMoveMark.IsFrom()))
|
|
{
|
|
if (oMoveMark.IsStart())
|
|
{
|
|
if (nDeep > 0)
|
|
{
|
|
nDeep--;
|
|
}
|
|
else if (nDeep === 0)
|
|
{
|
|
nStartIndex = nIndex;
|
|
oStartChange = oCurChange;
|
|
break;
|
|
}
|
|
}
|
|
else if (oCurChange !== oChange)
|
|
{
|
|
nDeep++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (oStartChange)
|
|
break;
|
|
|
|
isStart = true;
|
|
}
|
|
|
|
if (!oStartChange || -1 === nStartIndex)
|
|
return oChange;
|
|
|
|
var sValue = "";
|
|
var arrChanges = [oStartChange];
|
|
|
|
isStart = false;
|
|
nDeep = 0;
|
|
var isEnd = false;
|
|
for (var nIndex = nStartIndex, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
var arrCurChanges = this.Changes[this.ChangesOutline[nIndex].GetId()];
|
|
for (var nChangeIndex = 0, nChangesCount = arrCurChanges.length; nChangeIndex < nChangesCount; ++nChangeIndex)
|
|
{
|
|
var oCurChange = arrCurChanges[nChangeIndex];
|
|
if (!isStart)
|
|
{
|
|
if (oCurChange === oStartChange)
|
|
isStart = true;
|
|
}
|
|
else
|
|
{
|
|
var nCurChangeType = oCurChange.GetType();
|
|
if (isFrom)
|
|
{
|
|
if (c_oAscRevisionsChangeType.TextRem === nCurChangeType || c_oAscRevisionsChangeType.ParaRem === nCurChangeType)
|
|
{
|
|
if (0 === nDeep)
|
|
{
|
|
sValue += c_oAscRevisionsChangeType.TextRem === nCurChangeType ? oCurChange.GetValue() : "\n";
|
|
arrChanges.push(oCurChange);
|
|
}
|
|
}
|
|
else if (c_oAscRevisionsChangeType.MoveMark === nCurChangeType && oCurChange.GetValue().IsFrom())
|
|
{
|
|
if (oCurChange.GetValue().IsStart())
|
|
{
|
|
nDeep++;
|
|
}
|
|
else if (nDeep > 0)
|
|
{
|
|
nDeep--;
|
|
}
|
|
else
|
|
{
|
|
arrChanges.push(oCurChange);
|
|
isEnd = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (c_oAscRevisionsChangeType.TextAdd === nCurChangeType || c_oAscRevisionsChangeType.ParaAdd === nCurChangeType)
|
|
{
|
|
if (0 === nDeep)
|
|
{
|
|
sValue += c_oAscRevisionsChangeType.TextAdd === nCurChangeType ? oCurChange.GetValue() : "\n";
|
|
arrChanges.push(oCurChange);
|
|
}
|
|
}
|
|
else if (c_oAscRevisionsChangeType.MoveMark === nCurChangeType && !oCurChange.GetValue().IsFrom())
|
|
{
|
|
if (oCurChange.GetValue().IsStart())
|
|
{
|
|
nDeep++;
|
|
}
|
|
else if (nDeep > 0)
|
|
{
|
|
nDeep--;
|
|
}
|
|
else
|
|
{
|
|
arrChanges.push(oCurChange);
|
|
isEnd = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isStart)
|
|
return oChange;
|
|
|
|
if (isEnd)
|
|
break;
|
|
}
|
|
|
|
var sMoveId = oStartChange.GetValue().GetMarkId();
|
|
var isDown = null;
|
|
|
|
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
var arrCurChanges = this.Changes[this.ChangesOutline[nIndex].GetId()];
|
|
if (!arrCurChanges)
|
|
continue;
|
|
|
|
for (var nChangeIndex = 0, nChangesCount = arrCurChanges.length; nChangeIndex < nChangesCount; ++nChangeIndex)
|
|
{
|
|
var oCurChange = arrCurChanges[nChangeIndex];
|
|
if (c_oAscRevisionsChangeType.MoveMark === oCurChange.GetType())
|
|
{
|
|
var oMark = oCurChange.GetValue();
|
|
if (sMoveId === oMark.GetMarkId())
|
|
{
|
|
isDown = !!oMark.IsFrom();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (null !== isDown)
|
|
break;
|
|
}
|
|
|
|
if (!isEnd || null === isDown)
|
|
return oChange;
|
|
|
|
var oMoveChange = new CRevisionsChange();
|
|
oMoveChange.SetType(isFrom ? c_oAscRevisionsChangeType.TextRem : c_oAscRevisionsChangeType.TextAdd);
|
|
oMoveChange.SetValue(sValue);
|
|
oMoveChange.SetElement(oStartChange.GetElement());
|
|
oMoveChange.SetUserId(oStartChange.GetUserId());
|
|
oMoveChange.SetUserName(oStartChange.GetUserName());
|
|
oMoveChange.SetDateTime(oStartChange.GetDateTime());
|
|
oMoveChange.SetMoveType(isFrom ? Asc.c_oAscRevisionsMove.MoveFrom : Asc.c_oAscRevisionsMove.MoveTo);
|
|
oMoveChange.SetSimpleChanges(arrChanges);
|
|
oMoveChange.SetMoveId(sMoveId);
|
|
oMoveChange.SetMovedDown(isDown);
|
|
oMoveChange.SetXY(oChange.GetX(), oChange.GetY());
|
|
oMoveChange.SetInternalPos(oChange.GetInternalPosX(), oChange.GetInternalPosY(), oChange.GetInternalPosPageNum());
|
|
return oMoveChange;
|
|
};
|
|
/**
|
|
* Получаем массив всех изменений связанных с заданным переносом
|
|
* @param {string} sMoveId
|
|
* @returns {CRevisionsChange[]}
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetAllMoveChanges = function(sMoveId)
|
|
{
|
|
var oStartFromChange = null;
|
|
var oStartToChange = null;
|
|
|
|
for (var sElementId in this.Changes)
|
|
{
|
|
var arrElementChanges = this.Changes[sElementId];
|
|
for (var nChangeIndex = 0, nChangesCount = arrElementChanges.length; nChangeIndex < nChangesCount; ++nChangeIndex)
|
|
{
|
|
var oCurChange = arrElementChanges[nChangeIndex];
|
|
if (c_oAscRevisionsChangeType.MoveMark === oCurChange.GetType() && sMoveId === oCurChange.GetValue().GetMarkId() && oCurChange.GetValue().IsStart())
|
|
{
|
|
if (oCurChange.GetValue().IsFrom())
|
|
oStartFromChange = oCurChange;
|
|
else
|
|
oStartToChange = oCurChange;
|
|
}
|
|
}
|
|
|
|
if (oStartFromChange && oStartToChange)
|
|
break;
|
|
}
|
|
|
|
if (!oStartFromChange || !oStartToChange)
|
|
return {From : [], To : []};
|
|
|
|
return {
|
|
From : this.CollectMoveChange(oStartFromChange).GetSimpleChanges(),
|
|
To : this.CollectMoveChange(oStartToChange).GetSimpleChanges()
|
|
};
|
|
};
|
|
/**
|
|
* Начинаем процесс обработки(принятия или отклонения) перетаскивания текста
|
|
* @param sMoveId {string} идентификатор перетаскивания
|
|
* @param sUserId {string} идентификатор пользователя
|
|
* @returns {CTrackRevisionsMoveProcessEngine}
|
|
*/
|
|
CTrackRevisionsManager.prototype.StartProcessReviewMove = function(sMoveId, sUserId)
|
|
{
|
|
return (this.ProcessMove = new CTrackRevisionsMoveProcessEngine(sMoveId, sUserId));
|
|
};
|
|
/**
|
|
* Завершаем процесс обработки перетаскивания текста
|
|
*/
|
|
CTrackRevisionsManager.prototype.EndProcessReviewMove = function()
|
|
{
|
|
// TODO: Здесь нужно сделать обработку MovesToDelete
|
|
|
|
this.ProcessMove = null;
|
|
};
|
|
/**
|
|
* Проверям, запущен ли процесс обрабокти перетаскивания текста
|
|
* @returns {?CTrackRevisionsMoveProcessEngine}
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetProcessTrackMove = function()
|
|
{
|
|
return this.ProcessMove;
|
|
};
|
|
/**
|
|
* Получаем метки переноса
|
|
* @param sMarkId
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetMoveMarks = function(sMarkId)
|
|
{
|
|
return this.MoveMarks[sMarkId];
|
|
};
|
|
/**
|
|
* Получаем элементарное изменение связанное с заданным переносом, относящееся к метке переноса
|
|
* @param {string} sMoveId
|
|
* @param {boolean} isFrom
|
|
* @param {boolean} isStart
|
|
*/
|
|
CTrackRevisionsManager.prototype.GetMoveMarkChange = function(sMoveId, isFrom, isStart)
|
|
{
|
|
this.CompleteTrackChanges();
|
|
|
|
var oMoveChanges = this.GetAllMoveChanges(sMoveId);
|
|
var arrChanges = isFrom ? oMoveChanges.From : oMoveChanges.To;
|
|
|
|
for (var nIndex = 0, nCount = arrChanges.length; nIndex < nCount; ++nIndex)
|
|
{
|
|
var oChange = arrChanges[nIndex];
|
|
if (Asc.c_oAscRevisionsChangeType.MoveMark === oChange.GetType())
|
|
{
|
|
var oMark = oChange.GetValue();
|
|
if (oMark.IsFrom() === isFrom && oMark.IsStart() === isStart)
|
|
{
|
|
return oChange;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
//--------------------------------------------------------export----------------------------------------------------
|
|
window['AscWord'].CTrackRevisionsManager = CTrackRevisionsManager;
|
|
window['AscWord'].checkElementInRevision = checkElementInRevision;
|
|
|
|
})(window);
|