commit 284f975c979d1ecfa105e0a73ccd034ada1fb0ad branch koffice/change-tracking Author: Ganesh Paramasivam Date: Tue Jan 18 15:47:05 2011 +0530 Adding support for overlapping changes in paragraphs example:- text insertion followed by paragraph deletion diff --git a/libs/kotext/opendocument/KoTextWriter.cpp b/libs/kotext/opendocument/KoTextWriter.cpp index 2e203b5..ac0db64 100644 --- a/libs/kotext/opendocument/KoTextWriter.cpp +++ b/libs/kotext/opendocument/KoTextWriter.cpp @@ -315,21 +315,24 @@ int KoTextWriter::Private::openTagRegion(int position, ElementType elementType, break; } - if (changeId && (changeStack.top() != changeId)) { - changeStack.push(changeId); - } else { + if (!changeId || (changeStack.top() == changeId)) { changeId = 0; } + returnChangeId = changeId; //Navigate through the change history and push into a stack so that they can be processed in the reverse order (i.e starting from earliest) QStack changeHistory; - while (changeId) { + while (changeId && (changeId != changeStack.top())) { changeHistory.push(changeId); saveChange(changeId); changeId = changeTracker->parent(changeId); } + if (returnChangeId) { + changeStack.push(returnChangeId); + } + while(changeHistory.size()) { int changeId = changeHistory.pop(); @@ -777,6 +780,12 @@ int KoTextWriter::Private::checkForBlockChange(const QTextBlock &block) if (currentFragment.isValid()) { QTextCharFormat charFormat = currentFragment.charFormat(); int currentChangeId = charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt(); + + KoInlineObject *inlineObject = layout ? layout->inlineTextObjectManager()->inlineTextObject(charFormat) : 0; + if (currentFragment.length() == 1 && inlineObject && currentFragment.text()[0].unicode() == QChar::ObjectReplacementCharacter) { + continue; + } + if (!currentChangeId) { // Encountered a fragment that is not a change // So break out of loop and return 0 @@ -794,6 +803,13 @@ int KoTextWriter::Private::checkForBlockChange(const QTextBlock &block) //Change Fragment and it is the same as the first change. //continue looking continue; + } else if (changeTracker->isParent(currentChangeId, changeId)) { + //The currentChangeId is a parent of changeId + changeId = currentChangeId; + continue; + } else if (changeTracker->isParent(changeId, currentChangeId)) { + //The current change id is a child of change-id + continue; } else { //A Change Fragment but not same as the first change fragment //Break-out of loop and return 0