[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    Patch for change tracking of inline objects - Final version
From:       Ganesh Paramasivam <ganesh () crystalfab ! com>
Date:       2010-03-02 9:18:07
Message-ID: 9ecf537e1003020106t1884562eubcd38b079d6563ff () mail ! gmail ! com
[Download RAW message or body]

Pierre,

Please find attached the final version of the patch to enable change
tracking of inline objects. With this patch, loading, saving and
tracking of changes to inline objects works fine. All bugs have been
fixed and the patch is stable.

Please take a look at this and let me know your thoughts.

Thanks,
Ganesh

["inline-objects-change-tracking-v3.patch" (application/octet-stream)]

Index: libs/odf/KoGenChange.h
===================================================================
--- libs/odf/KoGenChange.h	(revision 1097379)
+++ libs/odf/KoGenChange.h	(working copy)
@@ -26,13 +26,9 @@
 #include "koodf_export.h"
 
 #include <QByteArray>
-#include <QVariant>
-#include <QTextDocumentFragment>
 
 #include <kdebug.h>
 
-Q_DECLARE_METATYPE(QTextDocumentFragment)
-
 class KoGenChanges;
 class KoXmlWriter;
 
@@ -113,15 +109,9 @@
      * The value of @p elementName isn't used, except that it must be unique.
      */
     void addChildElement(const QString& elementName, const QString& elementContents) \
                {
-        m_literalData.insert(elementName, QVariant(elementContents));
+        m_literalData.insert(elementName, elementContents);
     }
 
-    void addChildElement(const QString &elementName, const QTextDocumentFragment \
                &textFragment) {
-        QVariant var;
-        var.setValue(textFragment);
-        m_literalData.insert(elementName, var);
-    }
-
     /**
      *  Write the definition of this change to @p writer, using the OASIS format.
      *  @param writer the KoXmlWriter in which the element will be created and \
filled in @@ -151,17 +141,14 @@
 
     void writeChangeMetaData(KoXmlWriter* writer) const;
 
-    void writeDeleteChange(KoXmlWriter *writer) const;
-
 private:
     // Note that the copy constructor and assignment operator are allowed.
     // Better not use pointers below!
     Type m_type;
     /// We use QMaps since they provide automatic sorting on the key (important for \
unicity!)  typedef QMap<QString, QString> ChangeMap;
-    typedef QMap<QString, QVariant> GenericChangeMap;
     ChangeMap m_changeMetaData;
-    GenericChangeMap m_literalData;
+    ChangeMap m_literalData;
 
     short m_unused2;
 };
Index: libs/odf/KoGenChange.cpp
===================================================================
--- libs/odf/KoGenChange.cpp	(revision 1097379)
+++ libs/odf/KoGenChange.cpp	(working copy)
@@ -18,9 +18,6 @@
 */
 
 #include <QDateTime>
-#include <QTextDocument>
-#include <QTextCursor>
-#include <QTextBlock>
 
 #include "KoGenChange.h"
 #include <KoXmlWriter.h>
@@ -41,32 +38,7 @@
     return 0; // equal
 }
 
-// Return true if equal else false
-static bool compareGenericMap(const QMap<QString, QVariant> &map1, const \
                QMap<QString, QVariant> &map2)
-{
-    QMap<QString, QVariant>::const_iterator it = map1.begin();
-    QMap<QString, QVariant>::const_iterator oit = map2.begin();
 
-    for (; it != map1.end(); ++it, ++oit) {
-        if (it.key() != oit.key())
-            return false;
-        if (it.value().type() != oit.value().type())
-            return false;
-        if (it.value().type() == QVariant::String) {
-            if (it.value().toString() != oit.value().toString())
-                return false;
-        } else {
-            QString itHtml = it.value().value<QTextDocumentFragment>().toHtml();
-            QString oitHtml = oit.value().value<QTextDocumentFragment>().toHtml();
-            if (itHtml != oitHtml)
-                return false;
-        }
-    }
-
-    return true;
-}
-
-
 KoGenChange::KoGenChange()
 {
 }
@@ -121,29 +93,16 @@
         writer->startElement("office:change-info");
         writeChangeMetaData(writer);
         if (m_literalData.contains("changeMetaData"))
-            writer->addCompleteElement(m_literalData.value("changeMetaData").toString().toUtf8());
 +            writer->addCompleteElement(m_literalData.value("changeMetaData").toUtf8());
  writer->endElement(); // office:change-info
     }
-    if ((m_type == KoGenChange::deleteChange) && \
                m_literalData.contains("deletedData")) {
-        writeDeleteChange(writer);
-    }
+    if ((m_type == KoGenChange::deleteChange) && \
m_literalData.contains("deleteChangeXml")) +        \
writer->addCompleteElement(m_literalData.value("deleteChangeXml").toUtf8()); +    
     writer->endElement(); // text:insertion/format/deletion
     writer->endElement(); // text:change
 }
 
-void KoGenChange::writeDeleteChange(KoXmlWriter *writer) const
-{
-    QTextDocument document;
-    QTextCursor cursor(&document);
-    cursor.insertFragment(m_literalData["deletedData"].value<QTextDocumentFragment>());
                
-
-    for (QTextBlock block = document.begin(); block.isValid(); block = block.next()) \
                {
-        QString deletedElement;
-        deletedElement = QString("<text:p>") + block.text() + QString("</text:p>");
-        writer->addCompleteElement(deletedElement.toUtf8());
-    }
-}
-
 bool KoGenChange::operator<(const KoGenChange &other) const
 {
     Q_UNUSED(other);
@@ -160,6 +119,7 @@
     if (m_literalData.count() != other.m_literalData.count()) return false;
     int comp = compareMap(m_changeMetaData, other.m_changeMetaData);
     if (comp != 0) return false;
-    bool compResult = compareGenericMap(m_literalData, other.m_literalData);
-    return compResult;
+    comp = compareMap(m_literalData, other.m_literalData);
+    if (comp != 0) return false;
+    return true;
 }
Index: libs/kotext/KoTextAnchor.cpp
===================================================================
--- libs/kotext/KoTextAnchor.cpp	(revision 1097791)
+++ libs/kotext/KoTextAnchor.cpp	(working copy)
@@ -34,6 +34,12 @@
 #include <QPainter>
 #include <KDebug>
 
+#include "changetracker/KoChangeTracker.h"
+#include "changetracker/KoChangeTrackerElement.h"
+#include "styles/KoCharacterStyle.h"
+#include "KoTextDocument.h"
+#include <KoGenChanges.h>
+
 // #define DEBUG_PAINTING
 
 class KoTextAnchorPrivate : public KoInlineObjectPrivate
@@ -123,6 +129,7 @@
     KoTextAnchor::AnchorVertical verticalAlignment;
     const QTextDocument *document;
     int position;
+    QTextCharFormat format;
     KoTextShapeContainerModel *model;
     QPointF distance;
 };
@@ -182,6 +189,7 @@
     Q_D(KoTextAnchor);
     d->document = document;
     d->position = posInDocument;
+    d->format = format;
     d->setContainer(dynamic_cast<KoShapeContainer*>(shapeForPosition(document, \
posInDocument)));  }
 
@@ -210,6 +218,38 @@
 {
     Q_UNUSED(painter);
     Q_UNUSED(rect);
+
+    // This section of code is to indicate changes done to KoTextAnchors. Once the \
new approach is complete this can be removed +    // In this approach we draw a \
rectangle around the shape with the appropriate change indication color. +    \
Q_D(KoTextAnchor); +    int changeId = \
d->format.property(KoCharacterStyle::ChangeTrackerId).toInt(); +    bool \
drawChangeRect = false; +
+    QRectF changeRect = rect;
+    changeRect.adjust(0,0,1,0);
+    QPen changePen;
+    changePen.setWidth(2);
+   
+    KoChangeTracker *changeTracker = KoTextDocument(d->document).changeTracker(); 
+
+    if (!changeTracker)
+        return;
+
+    KoChangeTrackerElement *changeElement = changeTracker->elementById(changeId);
+    if (changeElement && changeElement->getChangeType() == \
KoGenChange::deleteChange) { +        \
changePen.setColor(changeTracker->getDeletionBgColor()); +        drawChangeRect = \
true; +    } else if (changeElement && changeElement->getChangeType() == \
KoGenChange::insertChange) { +        \
changePen.setColor(changeTracker->getInsertionBgColor()); +        drawChangeRect = \
true; +    }
+
+    painter.setPen(changePen);
+    if (drawChangeRect && changeTracker->displayChanges())
+        painter.drawRect(changeRect);
+
+    // End of Change Visualization Section. Can be removed once the new approach is \
finalized +
     // we never paint ourselves; the shape can do that.
 #ifdef DEBUG_PAINTING
     painter.setOpacity(0.5);
Index: libs/kotext/opendocument/KoTextLoader.cpp
===================================================================
--- libs/kotext/opendocument/KoTextLoader.cpp	(revision 1097791)
+++ libs/kotext/opendocument/KoTextLoader.cpp	(working copy)
@@ -1032,7 +1032,8 @@
                         QTextBlockFormat blockFormat = cursor.block().blockFormat();
                         cursor.insertBlock(blockFormat, charFormat);
                     }
-                    cursor.insertText(tag.text());
+                    bool stripLeadingSpace = true;
+                    loadSpan(tag, cursor, &stripLeadingSpace);
                     loadedTags++;
                 }
             }
Index: libs/kotext/opendocument/KoTextWriter.cpp
===================================================================
--- libs/kotext/opendocument/KoTextWriter.cpp	(revision 1097791)
+++ libs/kotext/opendocument/KoTextWriter.cpp	(working copy)
@@ -27,6 +27,7 @@
 #include <QTextTable>
 #include <QStack>
 #include <QTextTableCellFormat>
+#include <QBuffer>
 
 #include "KoInlineObject.h"
 #include "KoInlineTextObjectManager.h"
@@ -82,7 +83,7 @@
     void saveTable(QTextTable *table, QHash<QTextList *, QString> &listStyles);
     void saveTableOfContents(QTextDocument *document, int from, int to, \
QHash<QTextList *, QString> &listStyles, QTextTable *currentTable, QTextFrame *toc);  \
void writeBlocks(QTextDocument *document, int from, int to, QHash<QTextList *, \
                QString> &listStyles, QTextTable *currentTable = 0, QTextFrame \
                *currentFrame = 0);
-
+    QString generateDeleteChangeXml(KoDeleteChangeMarker *marker);
     KoShapeSavingContext &context;
     KoTextSharedSavingData *sharedData;
     KoXmlWriter *writer;
@@ -131,6 +132,8 @@
     KoDeleteChangeMarker *changeMarker;
     if (layout && (changeMarker = \
dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(format)))) \
{  if (!savedDeleteChanges.contains(changeMarker->changeId())) {
+            QString deleteChangeXml = generateDeleteChangeXml(changeMarker);
+            changeMarker->setDeleteChangeXml(deleteChangeXml);
             changeMarker->saveOdf(context);
             savedDeleteChanges.append(changeMarker->changeId());
         }
@@ -328,11 +331,6 @@
                 inlineRdf->saveOdf(context, writer);
             }
 
-            if (changeTracker
-                    && \
                charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt()
-                    && \
changeTracker->elementById(charFormat.property(KoCharacterStyle::ChangeTrackerId).toInt())->getChangeType() \
                == KoGenChange::deleteChange)
-                continue;
-
             KoInlineObject *inlineObject = layout ? \
layout->inlineTextObjectManager()->inlineTextObject(charFormat) : 0;  if \
                (currentFragment.length() == 1 && inlineObject
                     && currentFragment.text()[0].unicode() == \
QChar::ObjectReplacementCharacter) { @@ -598,6 +596,37 @@
     }
 }
 
+QString KoTextWriter::Private::generateDeleteChangeXml(KoDeleteChangeMarker *marker)
+{
+    //Create a QTextDocument from the Delete Fragment
+    QTextDocument doc;
+    QTextCursor cursor(&doc);
+    cursor.insertFragment(changeTracker->elementById(marker->changeId())->getDeleteData());
 +
+    //Save the current writer
+    KoXmlWriter &oldWriter = context.xmlWriter();
+
+    //Create a new KoXmlWriter pointing to a QBuffer
+    QByteArray xmlArray;
+    QBuffer xmlBuffer(&xmlArray);
+    KoXmlWriter newXmlWriter(&xmlBuffer);
+
+    //Set our xmlWriter as the writer to be used
+    writer = &newXmlWriter;
+    context.setXmlWriter(newXmlWriter);
+
+    //Call writeBlocks to generate the xml
+    QHash<QTextList *,QString> listStyles = saveListStyles(doc.firstBlock(), \
doc.characterCount()); +    writeBlocks(&doc, 0, doc.characterCount(),listStyles);
+
+    //Restore the actual xml writer
+    writer = &oldWriter;
+    context.setXmlWriter(oldWriter);
+
+    QString generatedXmlString(xmlArray);
+    return generatedXmlString;
+}
+
 void KoTextWriter::write(QTextDocument *document, int from, int to)
 {
     d->styleManager = KoTextDocument(document).styleManager();
Index: libs/kotext/changetracker/KoDeleteChangeMarker.cpp
===================================================================
--- libs/kotext/changetracker/KoDeleteChangeMarker.cpp	(revision 1097791)
+++ libs/kotext/changetracker/KoDeleteChangeMarker.cpp	(working copy)
@@ -47,6 +47,7 @@
     QString text;
     int id;
     int position;
+    QString deleteChangeXml;
 };
 
 KoDeleteChangeMarker::KoDeleteChangeMarker(KoChangeTracker* changeTracker)
@@ -86,6 +87,11 @@
     return d->position;
 }
 
+void KoDeleteChangeMarker::setDeleteChangeXml(QString &deleteChangeXml)
+{
+    d->deleteChangeXml = deleteChangeXml;
+}
+
 bool KoDeleteChangeMarker::loadOdf(const KoXmlElement &element)
 {
     Q_UNUSED(element)
@@ -143,6 +149,7 @@
         }
     }
     d->changeTracker->saveInlineChange(d->id, change);
+    change.addChildElement("deleteChangeXml", d->deleteChangeXml);
     changeName = sharedData->genChanges().insert(change);
 
     context.xmlWriter().startElement("text:change", false);
Index: libs/kotext/changetracker/KoDeleteChangeMarker.h
===================================================================
--- libs/kotext/changetracker/KoDeleteChangeMarker.h	(revision 1097791)
+++ libs/kotext/changetracker/KoDeleteChangeMarker.h	(working copy)
@@ -65,6 +65,8 @@
     ///reimplemented
     virtual void saveOdf(KoShapeSavingContext &context);
 
+    void setDeleteChangeXml(QString &deleteChangeXml);
+
 protected:
 
     virtual void paint(QPainter &painter, QPaintDevice *pd, const QTextDocument \
*document, const QRectF &rect, QTextInlineObject object, int posInDocument, const \
                QTextCharFormat &format);
Index: libs/kotext/changetracker/KoChangeTracker.cpp
===================================================================
--- libs/kotext/changetracker/KoChangeTracker.cpp	(revision 1097791)
+++ libs/kotext/changetracker/KoChangeTracker.cpp	(working copy)
@@ -274,9 +274,6 @@
     if (d->changes.value(changeId)->hasExtraMetaData())
         change.addChildElement("changeMetaData", \
d->changes.value(changeId)->getExtraMetaData());  
-    if (d->changes.value(changeId)->hasDeleteData())
-        change.addChildElement("deletedData", \
                d->changes.value(changeId)->getDeleteData());
-
     return true;
 }
 
Index: plugins/textshape/ChangeTrackingTool.cpp
===================================================================
--- plugins/textshape/ChangeTrackingTool.cpp	(revision 1097791)
+++ plugins/textshape/ChangeTrackingTool.cpp	(working copy)
@@ -56,7 +56,8 @@
     m_textShape(0),
     m_model(0),
     m_trackedChangeManager(0),
-    m_changesTreeView(0)
+    m_changesTreeView(0),
+    m_canvas(canvas)
 {
     KAction *action;
     action = new KAction(i18n("Tracked change manager"), this);
@@ -279,7 +280,7 @@
     }
     if (!data) {
         if (m_disableShowChangesOnExit) {
-            ShowChangesCommand *command = new ShowChangesCommand(false, \
m_textShapeData->document()); +            ShowChangesCommand *command = new \
ShowChangesCommand(false, m_textShapeData->document(), m_canvas);  \
m_textEditor->addCommand(command);  }
     }
@@ -302,7 +303,7 @@
     m_textEditor->updateDefaultTextDirection(m_textShapeData->pageDirection());
     if (!KoTextDocument(m_textShapeData->document()).changeTracker()->displayChanges()) \
{  m_disableShowChangesOnExit = true;
-        ShowChangesCommand *command = new ShowChangesCommand(true, \
m_textShapeData->document()); +        ShowChangesCommand *command = new \
ShowChangesCommand(true, m_textShapeData->document(), m_canvas);  \
m_textEditor->addCommand(command);  }
     if (m_model) {
Index: plugins/textshape/TextTool.cpp
===================================================================
--- plugins/textshape/TextTool.cpp	(revision 1097791)
+++ plugins/textshape/TextTool.cpp	(working copy)
@@ -1659,7 +1659,7 @@
 
 void TextTool::toggleShowChanges(bool on)//TODO transfer this in KoTextEditor
 {
-    ShowChangesCommand *command = new ShowChangesCommand(on, \
m_textShapeData->document()); +    ShowChangesCommand *command = new \
                ShowChangesCommand(on, m_textShapeData->document(), this->canvas());
     connect(command, SIGNAL(toggledShowChange(bool)), m_actionShowChanges, \
SLOT(setChecked(bool)));  m_textEditor->addCommand(command);
 }
Index: plugins/textshape/ChangeTrackingTool.h
===================================================================
--- plugins/textshape/ChangeTrackingTool.h	(revision 1097791)
+++ plugins/textshape/ChangeTrackingTool.h	(working copy)
@@ -73,6 +73,7 @@
     bool m_disableShowChangesOnExit;
     KoTextEditor *m_textEditor;
     KoTextShapeData *m_textShapeData;
+    KoCanvasBase *m_canvas;
     TextShape *m_textShape;
     TrackedChangeModel *m_model;
 
Index: plugins/textshape/commands/ChangeTrackedDeleteCommand.cpp
===================================================================
--- plugins/textshape/commands/ChangeTrackedDeleteCommand.cpp	(revision 1097791)
+++ plugins/textshape/commands/ChangeTrackedDeleteCommand.cpp	(working copy)
@@ -28,6 +28,9 @@
 #include <KoTextDocumentLayout.h>
 #include <KoInlineTextObjectManager.h>
 #include <KAction>
+#include <KoTextAnchor.h>
+#include <KoCanvasBase.h>
+#include <KoShapeController.h>
 #include <QTextDocumentFragment>
 #include <QUndoCommand>
 
@@ -49,6 +52,9 @@
 
 void ChangeTrackedDeleteCommand::undo()
 {
+    foreach(QUndoCommand *shapeDeleteCommand, m_shapeDeleteCommands)
+        shapeDeleteCommand->undo();
+
     TextCommandBase::undo();
     UndoRedoFinalizer finalizer(this);
 
@@ -65,6 +71,8 @@
 {
     m_undone = false;
     if (!m_first) {
+        foreach(QUndoCommand *shapeDeleteCommand, m_shapeDeleteCommands)
+            shapeDeleteCommand->redo();
         TextCommandBase::redo();
         UndoRedoFinalizer finalizer(this);
         QTextDocument *document = m_tool->m_textEditor->document();
@@ -130,6 +138,8 @@
     QTextDocument delText;
     QTextCursor delTextCursor(&delText);
 
+    QList<KoShape *> shapesInSelection;
+
     checker.setPosition(selectionBegin);
 
     if (KoTextDocument(document).changeTracker()->displayChanges()) {
@@ -179,6 +189,9 @@
                 KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->setValid(false);
  m_removedElements.push_back(testMarker->changeId());
            } else {
+                KoTextAnchor *anchor = dynamic_cast<KoTextAnchor \
*>(layout->inlineTextObjectManager()->inlineTextObject(checker)); +                if \
(anchor) +                    shapesInSelection.push_back(anchor->shape());
                 delTextCursor.insertFragment(checker.selection());
            } 
         }
@@ -251,6 +264,12 @@
     } else {
         if (backwards)
             selection.movePosition(QTextCursor::PreviousCharacter, \
QTextCursor::MoveAnchor,1); +
+        foreach (KoShape *shape, shapesInSelection) {
+            QUndoCommand *shapeDeleteCommand = \
m_tool->canvas()->shapeController()->removeShape(shape); +            \
m_shapeDeleteCommands.push_back(shapeDeleteCommand); +            \
shapeDeleteCommand->redo(); +        }
     }
 }
 
@@ -296,6 +315,9 @@
         m_removedElements += other->m_removedElements;
         other->m_removedElements.clear();
 
+        m_shapeDeleteCommands += other->m_shapeDeleteCommands;
+        other->m_shapeDeleteCommands.clear();
+
         for(int i=0; i < command->childCount(); i++)
             new UndoTextCommand(m_tool->m_textEditor->document(), this);
 
@@ -312,6 +334,9 @@
         foreach (int changeId, m_removedElements) {
            removeChangeElement(changeId);
         }
+        
+        foreach(QUndoCommand *shapeDeleteCommand, m_shapeDeleteCommands)
+            delete shapeDeleteCommand;
     }
 }
 
Index: plugins/textshape/commands/ShowChangesCommand.cpp
===================================================================
--- plugins/textshape/commands/ShowChangesCommand.cpp	(revision 1097791)
+++ plugins/textshape/commands/ShowChangesCommand.cpp	(working copy)
@@ -18,7 +18,7 @@
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
 */
-
+#include <iostream>
 #include "ShowChangesCommand.h"
 
 #include <KoChangeTracker.h>
@@ -26,6 +26,11 @@
 #include <KoTextDocument.h>
 #include <KoTextDocumentLayout.h>
 #include <KoTextEditor.h>
+#include <KoTextAnchor.h>
+#include <KoInlineTextObjectManager.h>
+#include <KoCanvasBase.h>
+#include <KoShapeController.h>
+#include <KoShapeContainer.h>
 
 #include <KAction>
 #include <klocale.h>
@@ -33,11 +38,12 @@
 #include <QTextDocument>
 #include <QtAlgorithms>
 
-ShowChangesCommand::ShowChangesCommand(bool showChanges, QTextDocument *document, \
QUndoCommand *parent) : +ShowChangesCommand::ShowChangesCommand(bool showChanges, \
QTextDocument *document, KoCanvasBase *canvas, QUndoCommand *parent) :  \
TextCommandBase (parent),  m_document(document),
     m_first(true),
-    m_showChanges(showChanges)
+    m_showChanges(showChanges),
+    m_canvas(canvas)
 {
     Q_ASSERT(document);
     m_changeTracker = KoTextDocument(m_document).changeTracker();
@@ -114,12 +120,43 @@
             f.setProperty(KoCharacterStyle::ChangeTrackerId, \
element->getDeleteChangeMarker()->changeId());  \
f.clearProperty(KoCharacterStyle::InlineInstanceId);  caret.setCharFormat(f);
+            int insertPosition = caret.position();
             caret.insertFragment(element->getDeleteData());
+            checkAndAddAnchoredShapes(insertPosition, \
                element->getDeleteData().toPlainText().length());
             numAddedChars += element->getDeleteData().toPlainText().length();
         }
     }
 }
 
+void ShowChangesCommand::checkAndAddAnchoredShapes(int position, int length)
+{
+    QTextCursor cursor(m_textEditor->document());
+    for (int i=position;i < (position + length);i++) {
+        if (m_textEditor->document()->characterAt(i) == \
QChar::ObjectReplacementCharacter) { +            cursor.setPosition(i+1);
+            KoInlineObject *object = \
KoTextDocument(m_textEditor->document()).inlineTextObjectManager()->inlineTextObject(cursor);
 +            if (!object)
+                continue;
+
+            KoTextAnchor *anchor = dynamic_cast<KoTextAnchor *>(object);
+            if (!anchor)
+                continue;
+           
+            KoTextDocumentLayout *lay = \
qobject_cast<KoTextDocumentLayout*>(m_document->documentLayout()); +            \
KoShapeContainer *container = dynamic_cast<KoShapeContainer \
*>(lay->shapeForPosition(i)); +            
+            // a very ugly hack. Since this class is going away soon, it should be \
okay +            if (!container)
+                container = dynamic_cast<KoShapeContainer *>((lay->shapes()).at(0));
+
+            if (container) {
+                container->addChild(anchor->shape()); 
+                m_canvas->shapeController()->addShapeDirect(anchor->shape(), \
this)->redo(); +            }
+        }
+    }
+}
+
 void ShowChangesCommand::removeDeletedChanges()
 {
     int numDeletedChars = 0;
@@ -131,14 +168,35 @@
         if (element->isValid()) {
             QTextCursor caret(element->getDeleteChangeMarker()->document());
             QTextCharFormat f;
-            caret.setPosition(element->getDeleteChangeMarker()->position() +  1 - \
numDeletedChars); +            int deletePosition = \
element->getDeleteChangeMarker()->position() + 1 - numDeletedChars; +            \
                caret.setPosition(deletePosition);
             caret.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, \
element->getDeleteData().toPlainText().length()); +            \
checkAndRemoveAnchoredShapes(deletePosition, \
element->getDeleteData().toPlainText().length());  caret.removeSelectedText();
             numDeletedChars += element->getDeleteData().toPlainText().length();
         }
     }
 }
 
+void ShowChangesCommand::checkAndRemoveAnchoredShapes(int position, int length)
+{
+    QTextCursor cursor(m_textEditor->document());
+    for (int i=position;i < (position + length);i++) {
+        if (m_textEditor->document()->characterAt(i) == \
QChar::ObjectReplacementCharacter) { +            cursor.setPosition(i+1);
+            KoInlineObject *object = \
KoTextDocument(m_textEditor->document()).inlineTextObjectManager()->inlineTextObject(cursor);
 +            if (!object)
+                continue;
+
+            KoTextAnchor *anchor = dynamic_cast<KoTextAnchor *>(object);
+            if (!anchor)
+                continue;
+            
+            m_canvas->shapeController()->removeShape(anchor->shape(), this)->redo();
+        }
+    }
+}
+
 ShowChangesCommand::~ShowChangesCommand()
 {
 }
Index: plugins/textshape/commands/ChangeTrackedDeleteCommand.h
===================================================================
--- plugins/textshape/commands/ChangeTrackedDeleteCommand.h	(revision 1097791)
+++ plugins/textshape/commands/ChangeTrackedDeleteCommand.h	(working copy)
@@ -25,8 +25,10 @@
 #include <QList>
 
 class TextTool;
+class QTextDocument;
 class QTextCursor;
 class KoChangeTrackerElement;
+class KoInlineTextObjectManager;
 
 class ChangeTrackedDeleteCommand : public TextCommandBase
 {
@@ -51,6 +53,7 @@
     bool m_undone;
     DeleteMode m_mode;
     QList<int> m_removedElements;
+    QList<QUndoCommand *> m_shapeDeleteCommands;
     int m_addedChangeElement;
 
     virtual void deleteChar();
Index: plugins/textshape/commands/ShowChangesCommand.h
===================================================================
--- plugins/textshape/commands/ShowChangesCommand.h	(revision 1097791)
+++ plugins/textshape/commands/ShowChangesCommand.h	(working copy)
@@ -22,20 +22,21 @@
 #define SHOWCHANGECOMMAND_H
 
 #include "TextCommandBase.h"
-
 #include <QObject>
 
 class KoChangeTracker;
 class KoTextEditor;
+class KoCanvasBase;
 
 class QTextDocument;
+class QTextDocumentFragment;
 
 class ShowChangesCommand : public QObject, public TextCommandBase
 {
     Q_OBJECT
 public:
 
-    ShowChangesCommand(bool showChanges, QTextDocument *document, QUndoCommand* \
parent = 0); +    ShowChangesCommand(bool showChanges, QTextDocument *document, \
KoCanvasBase *canvas, QUndoCommand* parent = 0);  ~ShowChangesCommand();
 
     virtual void undo();
@@ -48,13 +49,16 @@
     void enableDisableChanges();
     void enableDisableStates(bool showChanges);
     void insertDeletedChanges();
+    void checkAndAddAnchoredShapes(int position, int length);
     void removeDeletedChanges();
+    void checkAndRemoveAnchoredShapes(int position, int length);
 
     QTextDocument *m_document;
     KoChangeTracker *m_changeTracker;
     KoTextEditor *m_textEditor;
     bool m_first;
     bool m_showChanges;
+    KoCanvasBase *m_canvas;
 };
 
 #endif // SHOWCHANGECOMMAND_H



_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic