Commit 8e1a0373 authored by Ilya Kirillov's avatar Ilya Kirillov

Worked on the scheme for undo changes in fast collaboration mode.

parent 6d38edf8
......@@ -2899,6 +2899,17 @@
{
return this.Add;
};
CChangesBaseContentChange.prototype.Copy = function()
{
var oChanges = new this.constructor(this.Class, this.Pos, this.Items, this.Add);
oChanges.UseArray = this.UseArray;
for (var nIndex = 0, nCount = this.PosArray.length; nIndex < nCount; ++nIndex)
oChanges.PosArray[nIndex] = this.PosArray[nIndex];
return oChanges;
};
CChangesBaseContentChange.prototype.GetItemsCount = function()
{
return this.Items.length;
......@@ -2972,6 +2983,56 @@
{
return null;
};
CChangesBaseContentChange.prototype.ConvertToSimpleActions = function()
{
var arrActions = [];
if (this.UseArray)
{
for (var nIndex = 0, nCount = this.Items.length; nIndex < nCount; ++nIndex)
{
arrActions.push({
Item : this.Items[nIndex],
Pos : this.PosArray[nIndex],
Add : this.Add
});
}
}
else
{
var Pos = this.Pos;
for (var nIndex = 0, nCount = this.Items.length; nIndex < nCount; ++nIndex)
{
arrActions.push({
Item : this.Items[nIndex],
Pos : Pos + nIndex,
Add : this.Add
});
}
}
return arrActions;
};
CChangesBaseContentChange.prototype.ConvertFromSimpleActions = function(arrActions)
{
this.UseArray = true;
this.Pos = 0;
this.Items = [];
this.PosArray = [];
for (var nIndex = 0, nCount = arrActions.length; nIndex < nCount; ++nIndex)
{
this.PosArray[nIndex] = arrActions[nIndex].Pos;
this.Items[nIndex] = arrActions[nIndex].Item;
}
};
CChangesBaseContentChange.prototype.IsRelated = function(oChanges)
{
if (this.Class !== oChanges.GetClass() || this.Type !== oChanges.Type)
return false;
return true;
};
window['AscDFH'].CChangesBaseContentChange = CChangesBaseContentChange;
/**
* Базовый класс для изменения свойств.
......
......@@ -626,26 +626,42 @@ CWordCollaborativeEditing.prototype.Undo = function()
// Формируем новую пачку действий, которые будут откатывать нужные нам действия.
var oIndexes = this.m_aOwnChangesIndexes[this.m_aOwnChangesIndexes.length - 1];
var nPosition = oIndexes.Position;
var nCount = oIndexes.Count;
for (var nIndex = 0; nIndex < nCount; ++nIndex)
// На первом шаге мы заданнуюю пачку изменений коммутируем с последними измениями. Смотрим на то какой набор
// изменений у нас получается.
// Объектная модель у нас простая: класс, в котором возможно есть массив элементов(тоже классов), у которого воможно
// есть набор свойств. Поэтому у нас ровно 2 типа изменений: изменения внутри массива элементов, либо изменения
// свойств. Изменения этих двух типов коммутируют между собой, изменения разных классов тоже коммутируют.
var arrChanges = [];
var oIndexes = this.m_aOwnChangesIndexes[this.m_aOwnChangesIndexes.length - 1];
var nPosition = oIndexes.Position;
var nCount = oIndexes.Count;
var nOverallCount = this.m_aAllChanges.length;
var oContentChangesMap = {
};
for (var nIndex = nCount - 1; nIndex >= 0; --nIndex)
{
var oChange = this.m_aAllChanges[nPosition + nIndex];
if (!oChange || !oChange.IsChangesClass || !oChange.IsChangesClass())
continue;
if (oChange && oChange.IsChangesClass && oChange.IsChangesClass())
var oClass = oChange.GetClass();
if (oChange.IsContentChange())
{
if (oChange.IsContentChange())
{
var bAdd = oChange.IsAdd();
console.log(bAdd);
}
var _oChange = oChange.Copy();
if (this.private_CommutateContentChanges(oContentChangesMap, oClass, _oChange, nPosition + nCount))
arrChanges.splice(0, 0, _oChange);
}
else
{
console.log("Old change:");
console.log(oChange);
var _oChange = oChange; // TODO: Тут надо бы сделать копирование
if (this.private_CommutatePropertyChanges(oClass, _oChange, nPosition + nCount))
arrChanges.splice(0, 0, _oChange);
}
}
......@@ -656,6 +672,136 @@ CWordCollaborativeEditing.prototype.CanUndo = function()
{
return this.m_aOwnChangesIndexes.length <= 0 ? false : true;
};
CWordCollaborativeEditing.prototype.private_CommutateContentChanges = function(oMap, oClass, oChange, nStartPosition)
{
var arrOtherActions = [];
if (oMap[oClass.Get_Id()])
{
arrOtherActions = oMap[oClass.Get_Id()];
}
else
{
for (var nIndex = nStartPosition, nOverallCount = this.m_aAllChanges.length; nIndex < nOverallCount; ++nIndex)
{
var oTempChange = this.m_aAllChanges[nIndex];
if (!oTempChange || !oTempChange.IsChangesClass || !oTempChange.IsChangesClass())
continue;
if (oChange.IsRelated(oTempChange))
{
arrOtherActions.push(oTempChange.ConvertToSimpleActions());
}
}
oMap[oClass.Get_Id()] = arrOtherActions;
}
var arrActions = oChange.ConvertToSimpleActions();
var arrCommutateActions = [];
for (var nActionIndex = arrActions.length - 1; nActionIndex >= 0; --nActionIndex)
{
var oAction = arrActions[nActionIndex];
var oResult = oAction;
for (var nIndex = 0, nOtherActionsCount = arrOtherActions.length; nIndex < nOtherActionsCount; ++nIndex)
{
var arrOActions = arrOtherActions[nIndex];
for (var nIndex2 = 0, nOtherActionsCount2 = arrOActions.length; nIndex2 < nOtherActionsCount2; ++nIndex2)
{
var oOtherAction = arrOActions[nIndex2];
if (false === this.private_Commutate(oAction, oOtherAction))
{
arrOActions.splice(nIndex2, 1);
oResult = null;
break;
}
}
if (null === oResult)
break;
}
if (null !== oResult)
arrCommutateActions.splice(0, 0, oResult);
}
if (arrCommutateActions.length > 0)
oChange.ConvertFromSimpleActions(arrCommutateActions);
else
return false;
return true;
};
CWordCollaborativeEditing.prototype.private_Commutate = function(oActionL, oActionR)
{
if (oActionL.Add)
{
if (oActionR.Add)
{
if (oActionL.Pos >= oActionR.Pos)
oActionL.Pos++;
else
oActionR.Pos--;
}
else
{
if (oActionL.Pos > oActionR.Pos)
oActionL.Pos--;
else if (oActionL.Pos === oActionR.Pos)
return false;
else
oActionR.Pos--;
}
}
else
{
if (oActionR.Add)
{
if (oActionL.Pos >= oActionR)
oActionL.Pos++;
else
oActionR.Pos++;
}
else
{
if (oActionL.Pos > oActionR.Pos)
oActionL.Pos--;
else
oActionR.Pos++;
}
}
return true;
};
CWordCollaborativeEditing.prototype.private_CommutatePropertyChanges = function(oClass, oChange, nStartPosition)
{
// В GoogleDocs если 2 пользователя исправляют одно и тоже свойство у одного и того же класса, тогда Undo работает
// у обоих. Например, первый выставляет параграф по центру (изначально по левому), второй после этого по правому
// краю. Тогда на Undo первого пользователя возвращает параграф по левому краю, а у второго по центру, неважно в
// какой последовательности они вызывают Undo.
// Далем как у них: т.е. изменения свойств мы всегда откатываем, даже если данное свойсво менялось в последующих
// изменениях.
// Здесь вариант: свойство не откатываем, если оно менялось в одном из последующих действий. (для работы этого
// варианта нужно реализовать функцию IsRelated у всех изменений).
// // Значит это изменение свойства. Пробегаемся по всем следующим изменениям и смотрим, менялось ли такое
// // свойство у данного класса, если да, тогда данное изменение невозможно скоммутировать.
// for (var nIndex = nStartPosition, nOverallCount = this.m_aAllChanges.length; nIndex < nOverallCount; ++nIndex)
// {
// var oTempChange = this.m_aAllChanges[nIndex];
// if (!oTempChange || !oTempChange.IsChangesClass || !oTempChangeIsChangesClass())
// continue;
//
// if (oChange.IsRelated(oTempChange))
// return false;
// }
return true;
};
//--------------------------------------------------------export----------------------------------------------------
window['AscCommon'] = window['AscCommon'] || {};
......
......@@ -167,6 +167,13 @@ CChangesDocumentAddItem.prototype.Load = function(Color)
AscCommon.CollaborativeEditing.Update_DocumentPositionsOnAdd(oDocument, Pos);
}
};
CChangesDocumentAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Document_AddItem === oChanges.Type || AscDFH.historyitem_Document_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -276,6 +283,13 @@ CChangesDocumentRemoveItem.prototype.Load = function(Color)
oDocument.private_ReindexContent(Pos);
}
};
CChangesDocumentRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Document_AddItem === oChanges.Type || AscDFH.historyitem_Document_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBase}
......
......@@ -160,6 +160,13 @@ CChangesDocumentContentAddItem.prototype.Load = function(Color)
AscCommon.CollaborativeEditing.Update_DocumentPositionsOnAdd(oDocument, Pos);
}
};
CChangesDocumentContentAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_DocumentContent_AddItem === oChanges.Type || AscDFH.historyitem_DocumentContent_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -270,4 +277,11 @@ CChangesDocumentContentRemoveItem.prototype.Load = function(Color)
oDocument.private_ReindexContent(Pos);
}
};
CChangesDocumentContentRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_DocumentContent_AddItem === oChanges.Type || AscDFH.historyitem_DocumentContent_RemoveItem === oChanges.Type))
return true;
return false;
};
\ No newline at end of file
......@@ -94,6 +94,13 @@ CChangesParaFieldAddItem.prototype.Load = function(Color)
oField.private_UpdateTrackRevisions();
oField.protected_UpdateSpellChecking();
};
CChangesParaFieldAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Field_AddItem === oChanges.Type || AscDFH.historyitem_Field_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -145,4 +152,11 @@ CChangesParaFieldRemoveItem.prototype.Load = function(Color)
}
oField.private_UpdateTrackRevisions();
oField.protected_UpdateSpellChecking();
};
CChangesParaFieldRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Field_AddItem === oChanges.Type || AscDFH.historyitem_Field_RemoveItem === oChanges.Type))
return true;
return false;
};
\ No newline at end of file
......@@ -123,6 +123,13 @@ CChangesHyperlinkAddItem.prototype.Load = function(Color)
oHyperlink.private_UpdateTrackRevisions();
oHyperlink.protected_UpdateSpellChecking();
};
CChangesHyperlinkAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Hyperlink_AddItem === oChanges.Type || AscDFH.historyitem_Hyperlink_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -173,4 +180,11 @@ CChangesHyperlinkRemoveItem.prototype.Load = function(Color)
}
oHyperlink.private_UpdateTrackRevisions();
oHyperlink.protected_UpdateSpellChecking();
};
CChangesHyperlinkRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Hyperlink_AddItem === oChanges.Type || AscDFH.historyitem_Hyperlink_RemoveItem === oChanges.Type))
return true;
return false;
};
\ No newline at end of file
......@@ -145,6 +145,13 @@ CChangesMathContentAddItem.prototype.Load = function(Color)
}
}
};
CChangesMathContentAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_MathContent_AddItem === oChanges.Type || AscDFH.historyitem_MathContent_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -194,6 +201,13 @@ CChangesMathContentRemoveItem.prototype.Load = function(Color)
AscCommon.CollaborativeEditing.Update_DocumentPositionsOnRemove(oMathContent, ChangesPos, 1);
}
};
CChangesMathContentRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_MathContent_AddItem === oChanges.Type || AscDFH.historyitem_MathContent_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* Изменение настроек ArgSize в классе CMathContent
* @constructor
......@@ -273,6 +287,13 @@ CChangesMathBaseAddItems.prototype.Load = function(Color)
oMathBase.fillContent();
};
CChangesMathBaseAddItems.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_MathBase_AddItems === oChanges.Type || AscDFH.historyitem_MathBase_RemoveItems === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -313,6 +334,13 @@ CChangesMathBaseRemoveItems.prototype.Load = function()
}
oMathBase.fillContent();
};
CChangesMathBaseRemoveItems.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_MathBase_AddItems === oChanges.Type || AscDFH.historyitem_MathBase_RemoveItems === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseLongProperty}
......
......@@ -163,6 +163,13 @@ CChangesParagraphAddItem.prototype.Load = function(Color)
private_ParagraphChangesOnSetValue(this.Class);
};
CChangesParagraphAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Paragraph_AddItem === oChanges.Type || AscDFH.historyitem_Paragraph_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -216,6 +223,13 @@ CChangesParagraphRemoveItem.prototype.Load = function(Color)
private_ParagraphChangesOnSetValue(this.Class);
};
CChangesParagraphRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Paragraph_AddItem === oChanges.Type || AscDFH.historyitem_Paragraph_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseObjectProperty}
......
......@@ -152,6 +152,13 @@ CChangesRunAddItem.prototype.Load = function(Color)
oRun.protected_UpdateSpellChecking();
oRun.private_UpdateTrackRevisionOnChangeContent(false);
};
CChangesRunAddItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_ParaRun_AddItem === oChanges.Type || AscDFH.historyitem_ParaRun_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -215,6 +222,13 @@ CChangesRunRemoveItem.prototype.Load = function()
oRun.protected_UpdateSpellChecking();
oRun.private_UpdateTrackRevisionOnChangeContent(false);
};
CChangesRunRemoveItem.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_ParaRun_AddItem === oChanges.Type || AscDFH.historyitem_ParaRun_RemoveItem === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseBoolProperty}
......
......@@ -515,6 +515,13 @@ CChangesTableAddRow.prototype.Load = function(Color)
oTable.Internal_ReIndexing();
oTable.Recalc_CompiledPr2();
};
CChangesTableAddRow.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Table_AddRow === oChanges.Type || AscDFH.historyitem_Table_RemoveRow === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -578,6 +585,13 @@ CChangesTableRemoveRow.prototype.Load = function(Color)
oTable.Internal_ReIndexing();
oTable.Recalc_CompiledPr2();
};
CChangesTableRemoveRow.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_Table_AddRow === oChanges.Type || AscDFH.historyitem_Table_RemoveRow === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseProperty}
......
......@@ -402,6 +402,13 @@ CChangesTableRowAddCell.prototype.Load = function(Color)
oRow.Internal_ReIndexing();
};
CChangesTableRowAddCell.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_TableRow_AddCell === oChanges.Type || AscDFH.historyitem_TableRow_RemoveCell === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseContentChange}
......@@ -456,6 +463,13 @@ CChangesTableRowRemoveCell.prototype.Load = function(Color)
oRow.Internal_ReIndexing();
};
CChangesTableRowRemoveCell.prototype.IsRelated = function(oChanges)
{
if (this.Class === oChanges.Class && (AscDFH.historyitem_TableRow_AddCell === oChanges.Type || AscDFH.historyitem_TableRow_RemoveCell === oChanges.Type))
return true;
return false;
};
/**
* @constructor
* @extends {AscDFH.CChangesBaseBoolProperty}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment