|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
Request for reviewHere are three patches I'd like you to review:
- the first allows to save the user name instead of a blank space in the dc- creator field of a tracked change. This field is required by odf - the patches 2 and 3 are presented independently but patch 3 depends on patch 2. Patch 2 allows to save changes that are nested inside a previous change. For example, if you type some text and then make part of it bold, the bold change is nested within the insert change. Without the patch, the insert change is lost for the part of text which has been put bold. There is loss of data then. Patch 3 fixes a crash when pasting an element which contains a tracked change. The crash is solved, however, we would still need to handle the change when pasting. I'd like to commit this in 2.1. It is to be noted that the only code path which is affected by these is the one with tracked change. When tracked changes is not there or not enabled, the previous code path remains. Thanks, Pierre [commit_1_saveUserName] diff --git libs/kotext/changetracker/KoChangeTracker.cpp libs/kotext/changetracker/KoChangeTracker.cpp index 05f605f..2088c8f 100644 --- libs/kotext/changetracker/KoChangeTracker.cpp (revision 1043432) +++ libs/kotext/changetracker/KoChangeTracker.cpp (working copy) @@ -30,6 +30,7 @@ #include <KDateTime> #include <KGlobal> #include <KLocale> +#include <KUser> //Qt includes #include <QList> @@ -117,7 +118,9 @@ int KoChangeTracker::getFormatChangeId(QString title, QTextFormat &format, QText changeElement->setPrevFormat(prevFormat); changeElement->setDate(KDateTime::currentLocalDateTime().toString(KDateTime::ISODate).replace(KGlobal::locale()->decimalSymbol(), QString("."))); - changeElement->setCreator(QString(" ")); + + KUser user(KUser::UseRealUserID); + changeElement->setCreator(user.fullName()); changeElement->setEnabled(d->m_enabled); @@ -137,7 +140,8 @@ int KoChangeTracker::getInsertChangeId(QString title, int existingChangeId) changeElement->setDate(KDateTime::currentLocalDateTime().toString(KDateTime::ISODate).replace(KGlobal::locale()->decimalSymbol(), QString("."))); // changeElement->setDate(KDateTime::currentLocalDateTime().toString("Y-m-dTH:M:Sz")); //i must have misunderstood the API doc but it doesn't work. - changeElement->setCreator(QString(" ")); + KUser user(KUser::UseRealUserID); + changeElement->setCreator(user.fullName()); changeElement->setEnabled(d->m_enabled); @@ -156,7 +160,8 @@ int KoChangeTracker::getDeleteChangeId(QString title, QTextDocumentFragment sele KoChangeTrackerElement *changeElement = new KoChangeTrackerElement(title, KoGenChange::deleteChange); changeElement->setDate(KDateTime::currentLocalDateTime().toString(KDateTime::ISODate).replace(KGlobal::locale()->decimalSymbol(), QString("."))); - changeElement->setCreator(QString(" ")); + KUser user(KUser::UseRealUserID); + changeElement->setCreator(user.fullName()); //TODO preserve formating info there. this will do for now changeElement->setDeleteData(selection.toPlainText()); @@ -201,9 +206,9 @@ bool KoChangeTracker::saveInlineChange(int changeId, KoGenChange &change) return false; change.setType(d->m_changes.value(changeId)->getChangeType()); - if (d->m_changes.value(changeId)->hasCreator()) +// if (d->m_changes.value(changeId)->hasCreator()) change.addChangeMetaData("dc-creator", d->m_changes.value(changeId)->getCreator()); - if (d->m_changes.value(changeId)->hasDate()) +// if (d->m_changes.value(changeId)->hasDate()) change.addChangeMetaData("dc-date", d->m_changes.value(changeId)->getDate()); if (d->m_changes.value(changeId)->hasExtraMetaData()) change.addChildElement("changeMetaData", d->m_changes.value(changeId)->getExtraMetaData()); [commit_2_saveNested] diff --git libs/kotext/KoTextDrag.cpp libs/kotext/KoTextDrag.cpp index 521a0d4..66fd4f0 100644 --- libs/kotext/KoTextDrag.cpp (revision 1043432) +++ libs/kotext/KoTextDrag.cpp (working copy) @@ -85,7 +85,7 @@ bool KoTextDrag::setOdf(const char * mimeType, KoTextOdfSaveHelper &helper) KoGenChanges changes; KoSharedSavingData *sharedData = context->sharedData(KOTEXT_SHARED_SAVING_ID); - KoTextSharedSavingData *textSharedData; + KoTextSharedSavingData *textSharedData = 0; if (sharedData) { textSharedData = dynamic_cast<KoTextSharedSavingData *>(sharedData); } diff --git libs/kotext/KoTextEditor.cpp libs/kotext/KoTextEditor.cpp index 79f250a..d8f4f6a 100644 --- libs/kotext/KoTextEditor.cpp (revision 1043432) +++ libs/kotext/KoTextEditor.cpp (working copy) @@ -351,7 +351,7 @@ void KoTextEditor::registerTrackedChange(QTextCursor &selection, KoGenChange::Ty } changeId = (idBefore)?idBefore:idAfter; - switch (changeType) { + switch (changeType) {//TODO: this whole thing actually needs to be done like a visitor. If the selection contains several change regions, the parenting needs to be individualised. case KoGenChange::insertChange: if (!changeId) changeId = KoTextDocument(d->document).changeTracker()->getInsertChangeId(title, selection.charFormat().property( KoCharacterStyle::ChangeTrackerId ).toInt()); @@ -414,7 +414,7 @@ void KoTextEditor::registerTrackedChange(QTextCursor &selection, KoGenChange::Ty } QTextDocumentFragment deletedFragment = selection.selection(); - changeId = KoTextDocument(d->document).changeTracker()->getDeleteChangeId(i18n("Delete"), deletedFragment, selection.charFormat().property( KoCharacterStyle::ChangeTrackerId ).toInt()); + changeId = KoTextDocument(d->document).changeTracker()->getDeleteChangeId(i18n("Delete"), deletedFragment, selection.charFormat().property( KoCharacterStyle::ChangeTrackerId ).toInt()); //TODO this needs to be done like a visitor for individualised parenting deleteChangemarker = new KoDeleteChangeMarker(KoTextDocument(d->document).changeTracker()); deleteChangemarker->setChangeId(changeId); if (!sufix.isEmpty()) { diff --git libs/kotext/changetracker/KoChangeTracker.cpp libs/kotext/changetracker/KoChangeTracker.cpp index 2088c8f..a6e9c70 100644 --- libs/kotext/changetracker/KoChangeTracker.cpp (revision 1043432) +++ libs/kotext/changetracker/KoChangeTracker.cpp (working copy) @@ -36,6 +36,7 @@ #include <QList> #include <QString> #include <QHash> +#include <QMultiHash> #include <QTextCursor> #include <QTextFormat> #include <QTextCharFormat> @@ -53,7 +54,7 @@ public: ~Private() { } // TODO remove the m_ prefix - QHash<int, int> m_childs; // TODO rename to 'children' + QMultiHash<int, int> children; QHash<int, int> m_parents; QHash<int, KoChangeTrackerElement *> m_changes; QHash<QString, int> m_loadedChanges; @@ -109,7 +110,7 @@ int KoChangeTracker::getChangeId(QString &title, KoGenChange::Type type, QTextCu int KoChangeTracker::getFormatChangeId(QString title, QTextFormat &format, QTextFormat &prevFormat, int existingChangeId) { if ( existingChangeId ) { - d->m_childs.insert(existingChangeId, d->m_changeId); + d->children.insert(existingChangeId, d->m_changeId); d->m_parents.insert(d->m_changeId, existingChangeId); } @@ -132,7 +133,7 @@ int KoChangeTracker::getFormatChangeId(QString title, QTextFormat &format, QText int KoChangeTracker::getInsertChangeId(QString title, int existingChangeId) { if ( existingChangeId ) { - d->m_childs.insert(existingChangeId, d->m_changeId); + d->children.insert(existingChangeId, d->m_changeId); d->m_parents.insert(d->m_changeId, existingChangeId); } @@ -153,7 +154,7 @@ int KoChangeTracker::getInsertChangeId(QString title, int existingChangeId) int KoChangeTracker::getDeleteChangeId(QString title, QTextDocumentFragment selection, int existingChangeId) { if ( existingChangeId ) { - d->m_childs.insert(existingChangeId, d->m_changeId); + d->children.insert(existingChangeId, d->m_changeId); d->m_parents.insert(d->m_changeId, existingChangeId); } @@ -200,6 +201,33 @@ int KoChangeTracker::mergeableId(KoGenChange::Type type, QString &title, int exi return 0; } +int KoChangeTracker::split(int changeId) +{ + KoChangeTrackerElement *element = new KoChangeTrackerElement(*d->m_changes.value(changeId)); + d->m_changes.insert(d->m_changeId, element); + return d->m_changeId++; +} + +bool KoChangeTracker::isParent(int testedId, int baseId) +{ + if (testedId == baseId) + return true; + else if (d->m_parents.contains(baseId)) + return isParent(testedId, d->m_parents.value(baseId)); + else + return false; +} + +void KoChangeTracker::setParent(int child, int parent) +{ + if (!d->children.values(parent).contains(child)) { + d->children.insert(parent, child); + } + if (!d->m_parents.contains(child)) { + d->m_parents.insert(child, parent); + } +} + bool KoChangeTracker::saveInlineChange(int changeId, KoGenChange &change) { if (!d->m_changes.contains(changeId)) diff --git libs/kotext/changetracker/KoChangeTracker.h libs/kotext/changetracker/KoChangeTracker.h index 18d86ce..1dd472c 100644 --- libs/kotext/changetracker/KoChangeTracker.h (revision 1043432) +++ libs/kotext/changetracker/KoChangeTracker.h (working copy) @@ -70,6 +70,12 @@ public: bool containsInlineChanges(const QTextFormat &format); int mergeableId(KoGenChange::Type type, QString &title, int existingId); + /// Splits a changeElement. This creates a duplicate changeElement with a different changeId. This is used because we do not support overlapping change regions. The function returns the new changeId + int split(int changeId); + + bool isParent(int testedId, int baseId); + void setParent(int child, int parent); + /// Load/save methods bool saveInlineChange(int changeId, KoGenChange &change); diff --git libs/kotext/changetracker/KoChangeTrackerElement.cpp libs/kotext/changetracker/KoChangeTrackerElement.cpp index c8eb18a..2e6fc2a 100644 --- libs/kotext/changetracker/KoChangeTrackerElement.cpp (revision 1043432) +++ libs/kotext/changetracker/KoChangeTrackerElement.cpp (working copy) @@ -52,6 +52,20 @@ KoChangeTrackerElement::KoChangeTrackerElement() { } +KoChangeTrackerElement::KoChangeTrackerElement(const KoChangeTrackerElement& other) + :d(new Private()) +{ + d->title = other.d->title; + d->type = other.d->type; + d->changeFormat = other.d->changeFormat; + d->prevFormat = other.d->prevFormat; + d->creator = other.d->creator; + d->date = other.d->date; + d->extraMetaData = other.d->extraMetaData; + d->deleteData = other.d->deleteData; + d->enabled = other.d->enabled; +} + KoChangeTrackerElement::~KoChangeTrackerElement() { delete d; diff --git libs/kotext/changetracker/KoChangeTrackerElement.h libs/kotext/changetracker/KoChangeTrackerElement.h index 3624c0a..27445a7 100644 --- libs/kotext/changetracker/KoChangeTrackerElement.h (revision 1043432) +++ libs/kotext/changetracker/KoChangeTrackerElement.h (working copy) @@ -36,6 +36,8 @@ public: KoChangeTrackerElement(); + KoChangeTrackerElement(const KoChangeTrackerElement &other); + ~KoChangeTrackerElement(); void setEnabled(bool enabled); diff --git libs/kotext/changetracker/KoDeleteChangeMarker.cpp libs/kotext/changetracker/KoDeleteChangeMarker.cpp index 11c9df2..f83c23d 100644 --- libs/kotext/changetracker/KoDeleteChangeMarker.cpp (revision 1043432) +++ libs/kotext/changetracker/KoDeleteChangeMarker.cpp (working copy) @@ -150,7 +150,7 @@ void KoDeleteChangeMarker::saveOdf(KoShapeSavingContext &context) { KoGenChange change; QString changeName; - KoTextSharedSavingData *sharedData; + KoTextSharedSavingData *sharedData = 0; if (context.sharedData(KOTEXT_SHARED_SAVING_ID)) { sharedData = dynamic_cast<KoTextSharedSavingData*>(context.sharedData(KOTEXT_SHARED_SAVING_ID)); if (!sharedData) { diff --git libs/kotext/opendocument/KoTextLoader.cpp libs/kotext/opendocument/KoTextLoader.cpp index 24a1fe9..3d234a3 100644 --- libs/kotext/opendocument/KoTextLoader.cpp (revision 1043432) +++ libs/kotext/opendocument/KoTextLoader.cpp (working copy) @@ -6,6 +6,7 @@ * Copyright (C) 2007-2009 Thorsten Zachmann <zachmann@...> * Copyright (C) 2008 Girish Ramakrishnan <girish@...> * Copyright (C) 2009 KO GmbH <cbo@...> + * Copyright (C) 2009 Pierre Stirnweiss <pstirnweiss@...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,30 +26,36 @@ #include "KoTextLoader.h" -// koffice +#include <KoBookmark.h> +#include <KoBookmarkManager.h> +#include <KoInlineNote.h> +#include <KoInlineTextObjectManager.h> +#include "KoList.h" +#include <KoOdfLoadingContext.h> #include <KoOdfStylesReader.h> -#include <KoXmlNS.h> -#include <KoXmlReader.h> -#include <KoUnit.h> -#include <KoShapeRegistry.h> -#include <KoShapeFactory.h> +#include <KoProperties.h> #include <KoShapeContainer.h> -#include <KoOdfLoadingContext.h> +#include <KoShapeFactory.h> #include <KoShapeLoadingContext.h> +#include <KoShapeRegistry.h> +#include <KoTableColumnAndRowStyleManager.h> #include <KoTextAnchor.h> +#include <KoTextBlockData.h> +#include "KoTextDebug.h" +#include "KoTextDocument.h" #include <KoTextDocumentLayout.h> #include <KoTextShapeData.h> +#include "KoTextSharedLoadingData.h" +#include <KoUnit.h> #include <KoVariable.h> -#include <KoInlineNote.h> -#include <KoBookmark.h> -#include <KoBookmarkManager.h> #include <KoVariableManager.h> -#include <KoInlineTextObjectManager.h> #include <KoVariableRegistry.h> -#include <KoProperties.h> -#include <KoTextBlockData.h> -#include <KoTableColumnAndRowStyleManager.h> +#include <KoXmlNS.h> +#include <KoXmlReader.h> +#include "changetracker/KoChangeTracker.h" +#include "changetracker/KoChangeTrackerElement.h" +#include "changetracker/KoDeleteChangeMarker.h" #include "styles/KoStyleManager.h" #include "styles/KoParagraphStyle.h" #include "styles/KoCharacterStyle.h" @@ -57,24 +64,19 @@ #include "styles/KoTableStyle.h" #include "styles/KoTableColumnStyle.h" #include "styles/KoTableCellStyle.h" -#include "KoTextSharedLoadingData.h" -#include "KoTextDocument.h" -#include "KoTextDebug.h" -#include "KoList.h" -#include "changetracker/KoChangeTracker.h" -#include "changetracker/KoChangeTrackerElement.h" -#include "changetracker/KoDeleteChangeMarker.h" +#include <klocale.h> -// KDE + Qt includes -#include <QTextCursor> +#include <QList> +#include <QMap> +#include <QRect> +#include <QStack> #include <QTextBlock> +#include <QTextCursor> #include <QTextList> #include <QTextTable> #include <QTime> -#include <QList> -#include <QRect> -#include <klocale.h> + #include <kdebug.h> // if defined then debugging is enabled @@ -108,7 +110,8 @@ public: int loadSpanLevel; int loadSpanInitialPos; - int currentChangeId; + QStack<int> changeStack; + QMap<QString, int> changeTransTable; explicit Private(KoShapeLoadingContext &context) : context(context), @@ -127,8 +130,7 @@ public: styleManager(0), changeTracker(0), loadSpanLevel(0), - loadSpanInitialPos(0), - currentChangeId(0) { + loadSpanInitialPos(0) { dt.start(); } @@ -136,17 +138,62 @@ public: kDebug(32500) << "Loading took" << (float)(dt.elapsed()) / 1000 << " seconds"; } - KoList *list(const QTextDocument *document, KoListStyle *listStyle) - { - if (lists.contains(listStyle)) - return lists[listStyle]; + KoList *list(const QTextDocument *document, KoListStyle *listStyle); - KoList *newList = new KoList(document, listStyle); - lists[listStyle] = newList; - return newList; - } + void openChangeRegion(const KoXmlElement &element); + void closeChangeRegion(const KoXmlElement &element); + void splitStack(int id); }; +void KoTextLoader::Private::splitStack(int id) +{ + if (changeStack.isEmpty()) + return; + + int oldId = changeStack.top(); + changeStack.pop(); + if (id == oldId) + return; + int newId = changeTracker->split(oldId); + splitStack(id); + changeTracker->setParent(newId, changeStack.top()); + changeStack.push(newId); +} + +void KoTextLoader::Private::openChangeRegion(const KoXmlElement& element) +{ + QString id = element.attributeNS(KoXmlNS::text,"change-id"); + int changeId = changeTracker->getLoadedChangeId(id); + + if (!changeStack.empty()) + changeTracker->setParent(changeId, changeStack.top()); + changeStack.push(changeId); + changeTransTable.insert(id, changeId); + + KoChangeTrackerElement *changeElement = changeTracker->elementById(changeId); + changeElement->setEnabled(true); +} + +void KoTextLoader::Private::closeChangeRegion(const KoXmlElement& element) +{ + QString id = element.attributeNS(KoXmlNS::text,"change-id"); + int changeId = changeTracker->getLoadedChangeId(id); + + splitStack(changeId); +} + +KoList *KoTextLoader::Private::list(const QTextDocument *document, KoListStyle *listStyle) +{ + if (lists.contains(listStyle)) + return lists[listStyle]; + + KoList *newList = new KoList(document, listStyle); + lists[listStyle] = newList; + return newList; +} + +/////////////KoTextLoader + KoTextLoader::KoTextLoader(KoShapeLoadingContext &context) : QObject() , d(new Private(context)) @@ -211,10 +258,25 @@ void KoTextLoader::loadBody(const KoXmlElement &bodyElem, QTextCursor &cursor) d->changeTracker->loadOdfChanges(tag); usedParagraph = false; } else if (d->changeTracker && localName == "change-start") { - loadChangedRegion(tag, cursor); + d->openChangeRegion(tag); usedParagraph = false; } else if (d->changeTracker && localName == "change-end") { - d->currentChangeId = 0; + d->closeChangeRegion(tag); + usedParagraph = false; + } else if (d->changeTracker && localName == "change") { + QString id = tag.attributeNS(KoXmlNS::text,"change-id"); + int changeId = d->changeTracker->getLoadedChangeId(id); + if (d->changeStack.count()) + d->changeTracker->setParent(changeId, d->changeStack.top()); + KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker); + deleteChangemarker->setChangeId(changeId); + KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); + changeElement->setEnabled(true); + KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); + if(layout){ + KoInlineTextObjectManager *textObjectManager = layout->inlineTextObjectManager(); + textObjectManager->insertInlineObject(cursor, deleteChangemarker); + } usedParagraph = false; } else if (localName == "p") { // text paragraph loadParagraph(tag, cursor); @@ -353,19 +415,6 @@ void KoTextLoader::loadBody(const KoXmlElement &bodyElem, QTextCursor &cursor) cursor.endEditBlock(); } -void KoTextLoader::loadChangedRegion(const KoXmlElement &element, QTextCursor &cursor) -{ - Q_UNUSED(cursor) - QString id = element.attributeNS(KoXmlNS::text,"change-id"); - int changeId = d->changeTracker->getLoadedChangeId(id); - d->currentChangeId = changeId; - - //debug - KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); - changeElement->setEnabled(true); -// Q_UNUSED(changeElement) -} - void KoTextLoader::loadParagraph(const KoXmlElement &element, QTextCursor &cursor) { // TODO use the default style name a default value? @@ -631,9 +680,9 @@ void KoTextLoader::loadSpan(const KoXmlElement &element, QTextCursor &cursor, bo // we can remove the leading space in the next text *stripLeadingSpace = text[text.length() - 1].isSpace(); - if (d->changeTracker && d->currentChangeId) { + if (d->changeTracker && d->changeStack.count()) { QTextCharFormat format; - format.setProperty(KoCharacterStyle::ChangeTrackerId, d->currentChangeId); + format.setProperty(KoCharacterStyle::ChangeTrackerId, d->changeStack.top()); cursor.mergeCharFormat(format); } cursor.insertText(text); @@ -648,13 +697,15 @@ void KoTextLoader::loadSpan(const KoXmlElement &element, QTextCursor &cursor, bo } } } else if (isTextNS && localName == "change-start") { // text:change-start - loadChangedRegion(ts,cursor); + d->openChangeRegion(ts); } else if (isTextNS && localName == "change-end") { - d->currentChangeId = 0; + d->closeChangeRegion(ts); //kDebug() << "change-end"; }else if(isTextNS && localName == "change") { QString id = ts.attributeNS(KoXmlNS::text,"change-id"); int changeId = d->changeTracker->getLoadedChangeId(id); + if (d->changeStack.count()) + d->changeTracker->setParent(changeId, d->changeStack.top()); KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker); deleteChangemarker->setChangeId(changeId); KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); diff --git libs/kotext/opendocument/KoTextLoader.h libs/kotext/opendocument/KoTextLoader.h index 1d6e1ce..56f4a03 100644 --- libs/kotext/opendocument/KoTextLoader.h (revision 1043432) +++ libs/kotext/opendocument/KoTextLoader.h (working copy) @@ -121,16 +121,6 @@ private: void loadShape(const KoXmlElement &element, QTextCursor& cursor); /** - * Load the changed area data - */ - void loadChangedRegion(const KoXmlElement &element, QTextCursor &cursor); - - /** - * Close a changed area - */ - void closeChangedRegion(); - - /** * This is called in loadBody before reading the body starts. */ void startBody(int total); diff --git libs/kotext/opendocument/KoTextWriter.cpp libs/kotext/opendocument/KoTextWriter.cpp index d6a193d..a59661c 100644 --- libs/kotext/opendocument/KoTextWriter.cpp (revision 1043432) +++ libs/kotext/opendocument/KoTextWriter.cpp (working copy) @@ -2,6 +2,7 @@ * Copyright (C) 2006 Thomas Zander <zander@...> * Copyright (C) 2008 Thorsten Zachmann <zachmann@...> * Copyright (C) 2008 Girish Ramakrishnan <girish@...> + * Copyright (C) 2009 Pierre Stirnweiss <pstirnweiss@...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,8 +22,10 @@ #include "KoTextWriter.h" +#include <QMap> #include <QTextDocument> #include <QTextTable> +#include <QStack> #include "KoInlineObject.h" #include "KoInlineTextObjectManager.h" @@ -63,6 +66,8 @@ public: ~Private() {} + void saveChange(QTextCharFormat format); + KoShapeSavingContext &context; KoTextSharedSavingData *sharedData; KoXmlWriter *writer; @@ -70,8 +75,52 @@ public: KoTextDocumentLayout *layout; KoStyleManager *styleManager; KoChangeTracker *changeTracker; + + QStack<int> changeStack; + QMap<int, QString> changeTransTable; + QList<int> savedDeleteChanges; }; +void KoTextWriter::Private::saveChange(QTextCharFormat format) +{ + if (!changeTracker /*&& d->changeTracker->isEnabled()*/) + return;//The change tracker exist and we are allowed to save tracked changes + + int changeId = format.property(KoCharacterStyle::ChangeTrackerId).toInt(); + + //First we need to check if the eventual already opened change regions are still valid + foreach(int change, changeStack) { + if (!changeId || !changeTracker->isParent(change, changeId)) { + writer->startElement("text:change-end", false); + writer->addAttribute("text:change-id", changeTransTable.value(change)); + writer->endElement(); + changeStack.pop(); + } + } + + if (changeId) { //There is a tracked change + if (changeTracker->elementById(changeId)->getChangeType() != KoGenChange::deleteChange) { + //Now start a new change region if not already done + if (!changeStack.contains(changeId)) { + KoGenChange change; + changeTracker->saveInlineChange(changeId, change); + QString changeName = sharedData->genChanges().insert(change); + writer->startElement("text:change-start", false); + writer->addAttribute("text:change-id",changeName); + writer->endElement(); + changeStack.push(changeId); + changeTransTable.insert(changeId, changeName); + } + } + } + if (KoDeleteChangeMarker *changeMarker = dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(format))) { + if (!savedDeleteChanges.contains(changeMarker->changeId())) { + changeMarker->saveOdf(context); + savedDeleteChanges.append(changeMarker->changeId()); + } + } +} + KoTextWriter::KoTextWriter(KoShapeSavingContext &context) : d(new Private(context)) { @@ -213,7 +262,7 @@ QHash<QTextList *, QString> KoTextWriter::saveListStyles(QTextBlock block, int t void KoTextWriter::saveParagraph(const QTextBlock &block, int from, int to) { - QString changeName; + QTextCursor cursor(block); QTextBlockFormat blockFormat = block.blockFormat(); const int outlineLevel = blockFormat.intProperty(KoParagraphStyle::OutlineLevel); @@ -229,7 +278,6 @@ void KoTextWriter::saveParagraph(const QTextBlock &block, int from, int to) d->writer->addAttribute("text:style-name", styleName); // Write the fragments and their formats - QTextCursor cursor(block); QTextCharFormat blockCharFormat = cursor.blockCharFormat(); QTextCharFormat previousCharFormat; QTextBlock::iterator it; @@ -250,24 +298,13 @@ void KoTextWriter::saveParagraph(const QTextBlock &block, int from, int to) else identical = false; - if (d->changeTracker /*&& d->changeTracker->isEnabled()*/ && d->changeTracker->containsInlineChanges(charFormat) - && d->changeTracker->elementById(charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt())->isEnabled()) { //TODO uncomment changeTracker->isEnabled or implement another "security" measure to prevent saving changes at all - if (d->changeTracker->elementById(charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt())->getChangeType() == KoGenChange::deleteChange - && dynamic_cast<KoDeleteChangeMarker*>(d->layout->inlineTextObjectManager()->inlineTextObject(charFormat))) { - continue; - } - KoGenChange change; - d->changeTracker->saveInlineChange(charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt(), change); - changeName = d->sharedData->genChanges().insert(change); - d->writer->startElement("text:change-start", false); - d->writer->addAttribute("text:change-id", changeName); - d->writer->endElement(); - } + d->saveChange(charFormat); KoInlineObject *inlineObject = d->layout->inlineTextObjectManager()->inlineTextObject(charFormat); if (currentFragment.length() == 1 && inlineObject && currentFragment.text()[0].unicode() == QChar::ObjectReplacementCharacter) { - inlineObject->saveOdf(d->context); + if (!dynamic_cast<KoDeleteChangeMarker*>(inlineObject)) + inlineObject->saveOdf(d->context); } else { QString styleName = saveCharacterStyle(charFormat, blockCharFormat); if (charFormat.isAnchor()) { @@ -292,16 +329,17 @@ void KoTextWriter::saveParagraph(const QTextBlock &block, int from, int to) d->writer->endElement(); } // if (inlineObject) - if (!changeName.isEmpty()) { - d->writer->startElement("text:change-end", false); - d->writer->addAttribute("text:change-id",changeName); - d->writer->endElement(); - changeName=QString(); - } previousCharFormat = charFormat; } // if (fragment.valid()) } // foreach(fragment) + foreach(int change, d->changeStack) { + d->writer->startElement("text:change-end", false); + d->writer->addAttribute("text:change-id", d->changeTransTable.value(change)); + d->writer->endElement(); + d->changeStack.pop(); + } + d->writer->endElement(); } [commit_3_fisCrashPaste] diff --git libs/kotext/changetracker/KoChangeTracker.cpp libs/kotext/changetracker/KoChangeTracker.cpp index a6e9c70..c3fd39f 100644 --- libs/kotext/changetracker/KoChangeTracker.cpp (revision 1043432) +++ libs/kotext/changetracker/KoChangeTracker.cpp (working copy) @@ -234,10 +234,8 @@ bool KoChangeTracker::saveInlineChange(int changeId, KoGenChange &change) return false; change.setType(d->m_changes.value(changeId)->getChangeType()); -// if (d->m_changes.value(changeId)->hasCreator()) - change.addChangeMetaData("dc-creator", d->m_changes.value(changeId)->getCreator()); -// if (d->m_changes.value(changeId)->hasDate()) - change.addChangeMetaData("dc-date", d->m_changes.value(changeId)->getDate()); + change.addChangeMetaData("dc-creator", d->m_changes.value(changeId)->getCreator()); + change.addChangeMetaData("dc-date", d->m_changes.value(changeId)->getDate()); if (d->m_changes.value(changeId)->hasExtraMetaData()) change.addChildElement("changeMetaData", d->m_changes.value(changeId)->getExtraMetaData()); diff --git libs/kotext/opendocument/KoTextLoader.cpp libs/kotext/opendocument/KoTextLoader.cpp index 3d234a3..885d0fd 100644 --- libs/kotext/opendocument/KoTextLoader.cpp (revision 1043432) +++ libs/kotext/opendocument/KoTextLoader.cpp (working copy) @@ -164,7 +164,8 @@ void KoTextLoader::Private::openChangeRegion(const KoXmlElement& element) { QString id = element.attributeNS(KoXmlNS::text,"change-id"); int changeId = changeTracker->getLoadedChangeId(id); - + if (!changeId) + return; if (!changeStack.empty()) changeTracker->setParent(changeId, changeStack.top()); changeStack.push(changeId); @@ -266,16 +267,18 @@ void KoTextLoader::loadBody(const KoXmlElement &bodyElem, QTextCursor &cursor) } else if (d->changeTracker && localName == "change") { QString id = tag.attributeNS(KoXmlNS::text,"change-id"); int changeId = d->changeTracker->getLoadedChangeId(id); - if (d->changeStack.count()) - d->changeTracker->setParent(changeId, d->changeStack.top()); - KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker); - deleteChangemarker->setChangeId(changeId); - KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); - changeElement->setEnabled(true); - KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); - if(layout){ - KoInlineTextObjectManager *textObjectManager = layout->inlineTextObjectManager(); - textObjectManager->insertInlineObject(cursor, deleteChangemarker); + if (changeId) { + if (d->changeStack.count()) + d->changeTracker->setParent(changeId, d->changeStack.top()); + KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker); + deleteChangemarker->setChangeId(changeId); + KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); + changeElement->setEnabled(true); + KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); + if(layout){ + KoInlineTextObjectManager *textObjectManager = layout->inlineTextObjectManager(); + textObjectManager->insertInlineObject(cursor, deleteChangemarker); + } } usedParagraph = false; } else if (localName == "p") { // text paragraph @@ -494,7 +497,6 @@ void KoTextLoader::loadHeading(const KoXmlElement &element, QTextCursor &cursor) void KoTextLoader::loadList(const KoXmlElement &element, QTextCursor &cursor) { - //kDebug() << "in load List"; const bool numberedParagraph = element.localName() == "numbered-paragraph"; QString styleName = element.attributeNS(KoXmlNS::text, "style-name", QString()); @@ -700,21 +702,22 @@ void KoTextLoader::loadSpan(const KoXmlElement &element, QTextCursor &cursor, bo d->openChangeRegion(ts); } else if (isTextNS && localName == "change-end") { d->closeChangeRegion(ts); - //kDebug() << "change-end"; }else if(isTextNS && localName == "change") { QString id = ts.attributeNS(KoXmlNS::text,"change-id"); int changeId = d->changeTracker->getLoadedChangeId(id); - if (d->changeStack.count()) - d->changeTracker->setParent(changeId, d->changeStack.top()); - KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker); - deleteChangemarker->setChangeId(changeId); - KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); - changeElement->setEnabled(true); - KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); + if (changeId) { + if (d->changeStack.count()) + d->changeTracker->setParent(changeId, d->changeStack.top()); + KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker); + deleteChangemarker->setChangeId(changeId); + KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId); + changeElement->setEnabled(true); + KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); - if(layout){ - KoInlineTextObjectManager *textObjectManager = layout->inlineTextObjectManager(); - textObjectManager->insertInlineObject(cursor, deleteChangemarker); + if(layout){ + KoInlineTextObjectManager *textObjectManager = layout->inlineTextObjectManager(); + textObjectManager->insertInlineObject(cursor, deleteChangemarker); + } } }else if (isTextNS && localName == "span") { // text:span #ifdef KOOPENDOCUMENTLOADER_DEBUG _______________________________________________ koffice-devel mailing list koffice-devel@... https://mail.kde.org/mailman/listinfo/koffice-devel |
| Free embeddable forum powered by Nabble | Forum Help |