All pastes #1708157 Raw Edit

Something

public diff v1 · immutable
#1708157 ·published 2009-12-09 11:15 UTC
rendered paste body
Index: koffice/plugins/textshape/TextTool.cpp===================================================================--- koffice/plugins/textshape/TextTool.cpp	(revision 1046549)+++ koffice/plugins/textshape/TextTool.cpp	(working copy)@@ -36,6 +36,8 @@ #include "commands/ChangeListCommand.h" #include "commands/ChangeListLevelCommand.h" #include "commands/ListItemNumberingCommand.h"+#include "commands/ShowChangesCommand.h"+#include "commands/DeleteCommand.h"  #include <KoExecutePolicy.h> #include <KoCanvasBase.h>@@ -378,10 +380,10 @@     action->setWhatsThis(i18n("Change paragraph margins, text flow, borders, bullets, numbering etc.<p>Select text in multiple paragraphs to change the formatting of all selected paragraphs.<p>If no text is selected, the paragraph where the cursor is located will be changed.</p>"));     connect(action, SIGNAL(triggered()), this, SLOT(formatParagraph())); -    action = new KAction(i18n("Record"), this);-    action->setCheckable(true);-    addAction("edit_record_changes", action);-    connect(action, SIGNAL(triggered(bool)), this, SLOT(toggleTrackChanges(bool)));+    m_actionShowChanges = new KAction(i18n("Record"), this);+    m_actionShowChanges->setCheckable(true);+    addAction("edit_record_changes", m_actionShowChanges);+    connect(m_actionShowChanges, SIGNAL(triggered(bool)), this, SLOT(toggleTrackChanges(bool)));      action = new KAction(i18n("Style Manager"), this);     action->setShortcut(Qt::ALT + Qt::CTRL + Qt::Key_S);@@ -749,7 +751,10 @@  void TextTool::deleteSelection() {-    m_textEditor->deleteChar();+    if(m_actionShowChanges->isChecked())+      m_textEditor->addCommand(new DeleteCommand(DeleteCommand::NextChar, this));+    else+      m_textEditor->deleteChar();     editingPluginEvents(); } @@ -899,7 +904,10 @@         } else if (m_textEditor->position() > 0 || m_textEditor->hasSelection()) {             if (!m_textEditor->hasSelection() && event->modifiers() & Qt::ControlModifier) // delete prev word.                 m_textEditor->movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);-            m_textEditor->deletePreviousChar();+            if(m_actionShowChanges->isChecked())+              m_textEditor->addCommand(new DeleteCommand(DeleteCommand::PreviousChar, this));+            else+              m_textEditor->deletePreviousChar();             editingPluginEvents();         }         ensureCursorVisible();@@ -915,7 +923,10 @@             m_textEditor->movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);         // the event only gets through when the Del is not used in the app         // if the app forwards Del then deleteSelection is used-        m_textEditor->deleteChar();+        if(m_actionShowChanges->isChecked())+          m_textEditor->addCommand(new DeleteCommand(DeleteCommand::NextChar, this));+        else+          m_textEditor->deleteChar();         editingPluginEvents();     } else if ((event->key() == Qt::Key_Left) && (event->modifiers() | Qt::ShiftModifier) == Qt::ShiftModifier)         moveOperation = QTextCursor::Left;@@ -1062,7 +1073,10 @@     if (event->replacementLength() > 0) {         m_textEditor->setPosition(m_textEditor->position() + event->replacementStart());         for (int i = event->replacementLength(); i > 0; --i) {-            m_textEditor->deleteChar();+            if(m_actionShowChanges->isChecked())+              m_textEditor->addCommand(new DeleteCommand(DeleteCommand::NextChar, this));+            else+              m_textEditor->deleteChar();         }     }     if (! event->commitString().isEmpty()) {@@ -1621,20 +1635,7 @@  void TextTool::toggleTrackChanges(bool on)//TODO transfer this in KoTextEditor {-    if (m_changeTracker){-        m_changeTracker->setEnabled(on);-        m_changeTracker->setDisplayDeleted(on);-        QTextCharFormat format = m_textEditor->charFormat();-        format.clearProperty(KoCharacterStyle::ChangeTrackerId);-        m_textEditor->setCharFormat(format);-        const QTextDocument *doc = m_textEditor->document();-        Q_ASSERT(doc);-        KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(doc->documentLayout());-        if(lay)-          lay->scheduleLayout();-    }-    m_textTyping = false;-    m_textDeleting = false;+    m_textEditor->addCommand(new ShowChangesCommand(on, this)); }  void TextTool::selectAll()Index: koffice/plugins/textshape/CMakeLists.txt===================================================================--- koffice/plugins/textshape/CMakeLists.txt	(revision 1046549)+++ koffice/plugins/textshape/CMakeLists.txt	(working copy)@@ -59,6 +59,8 @@     commands/TextCommandBase.cpp     commands/TextPasteCommand.cpp     commands/TextCutCommand.cpp+    commands/ShowChangesCommand.cpp+    commands/DeleteCommand.cpp )  kde4_add_ui_files(textshape_SRCSIndex: koffice/plugins/textshape/commands/TextCutCommand.cpp===================================================================--- koffice/plugins/textshape/commands/TextCutCommand.cpp	(revision 1046549)+++ koffice/plugins/textshape/commands/TextCutCommand.cpp	(working copy)@@ -21,7 +21,8 @@  #include <KoTextEditor.h> #include <TextTool.h>-+#include "DeleteCommand.h"+#include <KAction> #include <klocale.h>  TextCutCommand::TextCutCommand(TextTool *tool, QUndoCommand *parent) :@@ -44,6 +45,9 @@     } else {         m_first = false;         m_tool->copy();-        m_tool->m_textEditor->deleteChar();+        if(m_tool->m_actionShowChanges->isChecked())+          m_tool->m_textEditor->addCommand(new DeleteCommand(DeleteCommand::NextChar, m_tool));+        else+          m_tool->m_textEditor->deleteChar();     } }Index: koffice/plugins/textshape/commands/DeleteCommand.cpp===================================================================--- koffice/plugins/textshape/commands/DeleteCommand.cpp	(revision 0)+++ koffice/plugins/textshape/commands/DeleteCommand.cpp	(revision 0)@@ -0,0 +1,266 @@+/*+ This file is part of the KDE project+ * Copyright (C) 2009 Ganesh Paramasivam <ganesh@crystalfab.com>+ *+ * This library is free software; you can redistribute it and/or+ * modify it under the terms of the GNU Library General Public+ * License as published by the Free Software Foundation; either+ * version 2 of the License, or (at your option) any later version.+ *+ * This library is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+ * Library General Public License for more details.+ *+ * You should have received a copy of the GNU Library General Public License+ * along with this library; see the file COPYING.LIB.  If not, write to+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,+ * Boston, MA 02110-1301, USA.*/++#include "DeleteCommand.h"+#include <KoTextEditor.h>+#include <TextTool.h>+#include <klocale.h>+#include <KoChangeTracker.h>+#include <KoChangeTrackerElement.h>+#include <KoTextDocument.h>+#include <KoTextDocumentLayout.h>+#include <KoInlineTextObjectManager.h>+#include <KAction>+#include <QTextDocumentFragment>+#include <QUndoCommand>++#include <KDebug>+#include <iostream>+#include <QDebug>++using namespace std;+DeleteCommand::DeleteCommand(DeleteMode mode, TextTool *tool, QUndoCommand *parent) :+    TextCommandBase (parent),+    m_tool(tool),+    m_first(true),+    m_mode(mode),+    m_undone(false),+    m_removedElements()+{+      setText(i18n("Delete"));+}++void DeleteCommand::undo()+{+    TextCommandBase::undo();+    UndoRedoFinalizer finalizer(this, m_tool);+    +    QTextDocument *document = m_tool->m_textEditor->document();+    KoTextDocument(document).changeTracker()->elementById(m_addedChangeElement)->setValid(false);+    foreach (int changeId, m_removedElements) {+      KoTextDocument(document).changeTracker()->elementById(changeId)->setValid(true);+    }++    m_undone = true;+}++void DeleteCommand::redo()+{+    m_undone = false;+    if (!m_first) {+        TextCommandBase::redo();+        UndoRedoFinalizer finalizer(this, m_tool);+        QTextDocument *document = m_tool->m_textEditor->document();+        KoTextDocument(document).changeTracker()->elementById(m_addedChangeElement)->setValid(true);+        foreach (int changeId, m_removedElements) {+          KoTextDocument(document).changeTracker()->elementById(changeId)->setValid(false);+        }+    } else {+        m_first = false;+        m_tool->m_textEditor->beginEditBlock();+        if(m_mode == PreviousChar)+          deletePreviousChar();+        else+          deleteChar();+        m_tool->m_textEditor->endEditBlock();+    }+}++void DeleteCommand::deleteChar()+{+    QTextCursor *caret = m_tool->m_textEditor->cursor();++    if (caret->atEnd() && !caret->hasSelection())+      return;++    if (!caret->hasSelection())+      caret->movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);++    deleteSelection(*caret);+}++void DeleteCommand::deletePreviousChar()+{+    QTextCursor *caret = m_tool->m_textEditor->cursor();++    if (caret->atStart() && !caret->hasSelection())+      return;++    if (!caret->hasSelection())+      caret->movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);++    deleteSelection(*caret);+}++void DeleteCommand::deleteSelection(QTextCursor &selection)+{+    QTextDocument *document = m_tool->m_textEditor->document();+    KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(document->documentLayout());+    Q_ASSERT(layout);+    Q_ASSERT(layout->inlineTextObjectManager());++    QTextCursor checker = QTextCursor(selection);+    KoDeleteChangeMarker *deleteChangemarker = 0;+    KoDeleteChangeMarker *testMarker;++    bool backwards = (checker.anchor() > checker.position());+    int selectionBegin = qMin(checker.anchor(), checker.position());+    int selectionEnd = qMax(checker.anchor(), checker.position());+    int changeId;++    QString prefix;+    QString sufix;+    QString delText;++    checker.setPosition(selectionBegin);+    if (KoTextDocument(document).changeTracker()->containsInlineChanges(checker.charFormat())) {+        int changeId = checker.charFormat().property(KoCharacterStyle::ChangeTrackerId).toInt();+        if (KoTextDocument(document).changeTracker()->elementById(changeId)->getChangeType() == KoGenChange::deleteChange) {+          prefix =  KoTextDocument(document).changeTracker()->elementById(changeId)->getDeleteData();+          KoTextDocument(document).changeTracker()->elementById(changeId)->setValid(false);+	  m_removedElements.push_back(changeId);+        }+    }++    checker.setPosition(selectionEnd);+    if (!checker.atEnd()) {+        checker.movePosition(QTextCursor::NextCharacter);+        testMarker = dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(checker));+        if (testMarker) {+            sufix =  KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->getDeleteData();+            KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->setValid(false);+	    m_removedElements.push_back(testMarker->changeId());+	}+    }+    checker.setPosition(selectionBegin);++    while ((checker.position() < selectionEnd) && (!checker.atEnd())) {+	QChar charAtPos = document->characterAt(checker.position());+        checker.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);+        if (layout->inlineTextObjectManager()->inlineTextObject(checker) && charAtPos.unicode() != 0x2029) {+            testMarker = dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(checker));+            if (testMarker) {+                QString inter = KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->getDeleteData();+                delText = delText + inter;+		checker.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, inter.length());+                KoTextDocument(document).changeTracker()->elementById(testMarker->changeId())->setValid(false);+	    	m_removedElements.push_back(testMarker->changeId());+           }+        }+        else {+            delText = delText + checker.selectedText();+        }+        checker.setPosition(checker.position());+    }+    +    if (!sufix.isEmpty()) {+      selection.setPosition(selectionBegin);+      selection.setPosition(selectionEnd + sufix.length() + 1, QTextCursor::KeepAnchor);+      selectionEnd += (sufix.length() + 1);+    }++    if (!prefix.isEmpty()) {+      selection.setPosition(selectionBegin - prefix.length() - 1);+      selection.setPosition(selectionEnd, QTextCursor::KeepAnchor);+      selectionBegin -= (prefix.length() + 1);+    }++    QTextDocumentFragment deletedFragment = selection.selection();+    changeId = KoTextDocument(document).changeTracker()->getDeleteChangeId(i18n("Delete"), deletedFragment, selection.charFormat().property( KoCharacterStyle::ChangeTrackerId ).toInt());+    KoChangeTrackerElement *element = KoTextDocument(document).changeTracker()->elementById(changeId);+    deleteChangemarker = new KoDeleteChangeMarker(KoTextDocument(document).changeTracker());+    deleteChangemarker->setChangeId(changeId);+    element->setDeleteChangeMarker(deleteChangemarker);+    layout->inlineTextObjectManager()->insertInlineObject(selection, deleteChangemarker);+    +    m_addedChangeElement = changeId;+    +    //Clear the changeTrackerId of the marker. Should be done in KoInlineTextObjectManager ideally.+    selection.setPosition(selectionBegin);+    selection.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);+    QTextCharFormat markerFormat = selection.charFormat();+    markerFormat.setProperty(KoCharacterStyle::ChangeTrackerId,0);+    selection.mergeCharFormat(markerFormat);+    selection.setPosition(selectionBegin + 1);++    //Insert the deleted data again after the marker with the charformat set to the change-id+    QString deletedData = prefix + delText + sufix;+    QTextCharFormat f;+    f.setProperty(KoCharacterStyle::ChangeTrackerId, deleteChangemarker->changeId());+    selection.mergeCharFormat(f);+    selection.insertText(deletedData);+++    KoTextDocument(document).changeTracker()->elementById(deleteChangemarker->changeId())->setDeleteData(deletedData);+    if (backwards)+        selection.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, deletedData.length() + 1);++}+++int DeleteCommand::id() const+{+    return 98765;+}++bool DeleteCommand::mergeWith( const QUndoCommand *command)+{+    if (command->id() != id())+     return false;+    +    DeleteCommand *other = const_cast<DeleteCommand *>(static_cast<const DeleteCommand *>(command));+    if (other->m_removedElements.contains(m_addedChangeElement)) {+       +      removeChangeElement(m_addedChangeElement);+      other->m_removedElements.removeAll(m_addedChangeElement);+      m_addedChangeElement = other->m_addedChangeElement;++      m_removedElements += other->m_removedElements;+      other->m_removedElements.clear();++      for(int i=0; i < command->childCount(); i++)+        new UndoTextCommand(m_tool->m_textEditor->document(), this);++      return true;+    }+    +    return false;+}++DeleteCommand::~DeleteCommand()+{+    if (m_undone) {+      removeChangeElement(m_addedChangeElement);+    } else {+      foreach (int changeId, m_removedElements) {+        removeChangeElement(changeId);+      }+    }+}++void DeleteCommand::removeChangeElement(int changeId)+{++    QTextDocument *document = m_tool->m_textEditor->document();+    KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(document->documentLayout());+    KoChangeTrackerElement *element = KoTextDocument(document).changeTracker()->elementById(changeId);+    KoDeleteChangeMarker *marker = element->getDeleteChangeMarker();+    layout->inlineTextObjectManager()->removeInlineObject(marker);+    KoTextDocument(document).changeTracker()->removeById(changeId);+}Index: koffice/plugins/textshape/commands/DeleteCommand.h===================================================================--- koffice/plugins/textshape/commands/DeleteCommand.h	(revision 0)+++ koffice/plugins/textshape/commands/DeleteCommand.h	(revision 0)@@ -0,0 +1,63 @@+/*+ This file is part of the KDE project+ * Copyright (C) 2009 Ganesh Paramasivam <ganesh@crystalfab.com>+ *+ * This library is free software; you can redistribute it and/or+ * modify it under the terms of the GNU Library General Public+ * License as published by the Free Software Foundation; either+ * version 2 of the License, or (at your option) any later version.+ *+ * This library is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+ * Library General Public License for more details.+ *+ * You should have received a copy of the GNU Library General Public License+ * along with this library; see the file COPYING.LIB.  If not, write to+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,+ * Boston, MA 02110-1301, USA.*/++#ifndef DELETECOMMAND_H+#define DELETECOMMAND_H++#include <QUndoStack>+#include "TextCommandBase.h"+#include <QList>++class TextTool;+class QTextCursor;+class KoChangeTrackerElement;++class DeleteCommand : public TextCommandBase+{+public:+    typedef enum+    {+        PreviousChar,+        NextChar+    }DeleteMode;++    DeleteCommand(DeleteMode mode, TextTool *tool, QUndoCommand* parent = 0);+    ~DeleteCommand();++    virtual void undo();+    virtual void redo();++    virtual int id() const;+    virtual bool mergeWith ( const QUndoCommand *command);++private:+    TextTool *m_tool;+    bool m_first;+    bool m_undone;+    DeleteMode m_mode;+    QList<int> m_removedElements;+    int m_addedChangeElement;++    virtual void deleteChar();+    virtual void deletePreviousChar();+    virtual void deleteSelection(QTextCursor &selection);+    virtual void removeChangeElement(int changeId);+};++#endif // DELTECOMMAND_HIndex: koffice/plugins/textshape/commands/ShowChangesCommand.cpp===================================================================--- koffice/plugins/textshape/commands/ShowChangesCommand.cpp	(revision 0)+++ koffice/plugins/textshape/commands/ShowChangesCommand.cpp	(revision 0)@@ -0,0 +1,145 @@+/*+ This file is part of the KDE project+ * Copyright (C) 2009 Ganesh Paramasivam <ganesh@crystalfab.com>+ *+ * This library is free software; you can redistribute it and/or+ * modify it under the terms of the GNU Library General Public+ * License as published by the Free Software Foundation; either+ * version 2 of the License, or (at your option) any later version.+ *+ * This library is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+ * Library General Public License for more details.+ *+ * You should have received a copy of the GNU Library General Public License+ * along with this library; see the file COPYING.LIB.  If not, write to+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,+ * Boston, MA 02110-1301, USA.*/++#include "ShowChangesCommand.h"++#include <KoTextEditor.h>+#include <TextTool.h>+#include <klocale.h>+#include <KoChangeTracker.h>+#include <KoChangeTrackerElement.h>+#include <KoTextDocument.h>+#include <KoTextDocumentLayout.h>+#include <KAction>++ShowChangesCommand::ShowChangesCommand(bool showChanges, TextTool *tool, QUndoCommand *parent) :+    TextCommandBase (parent),+    m_showChanges(showChanges),+    m_tool(tool),+    m_first(true)+{+    if (showChanges)+      setText(i18n("Show Changes"));+    else+      setText(i18n("Hide Changes"));+}++void ShowChangesCommand::undo()+{+    TextCommandBase::undo();+    UndoRedoFinalizer finalizer(this, m_tool);+    m_tool->m_actionShowChanges->setChecked(!m_showChanges);+    enableDisableStates(!m_showChanges);+}++void ShowChangesCommand::redo()+{+    if (!m_first) {+        TextCommandBase::redo();+        UndoRedoFinalizer finalizer(this, m_tool);+        m_tool->m_actionShowChanges->setChecked(m_showChanges);+        enableDisableStates(m_showChanges);+    } else {+        m_first = false;+        enableDisableChanges();+    }+}++void ShowChangesCommand::enableDisableChanges()+{+    if (m_tool->m_changeTracker) {+        enableDisableStates(m_showChanges);++        if(m_showChanges)+          insertDeletedChanges();+        else+          removeDeletedChanges();++        const QTextDocument *doc = m_tool->m_textEditor->document();+        Q_ASSERT(doc);+        KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(doc->documentLayout());+        if(lay)+          lay->scheduleLayout();+    }+}++void ShowChangesCommand::enableDisableStates(bool showChanges)+{+    m_tool->m_changeTracker->setEnabled(showChanges);+    m_tool->m_changeTracker->setDisplayDeleted(showChanges);++    QTextCharFormat format = m_tool->m_textEditor->charFormat();+    format.clearProperty(KoCharacterStyle::ChangeTrackerId);+    m_tool->m_textEditor->setCharFormat(format);++    m_tool->m_textTyping = false;+    m_tool->m_textDeleting = false;+}++void ShowChangesCommand::insertDeletedChanges()+{+    int numAddedChars = 0;+    QVector<KoChangeTrackerElement *> elementVector;+    KoTextDocument(m_tool->m_textEditor->document()).changeTracker()->getDeletedChanges(elementVector);++    QTextCursor caret(m_tool->m_textEditor->document());+    caret.beginEditBlock();++    foreach(KoChangeTrackerElement *element, elementVector)+    {+        if (element->isValid()) {+          QTextCharFormat f;+          caret.setPosition(element->getDeleteChangeMarker()->position() + numAddedChars +  1);+          f.setProperty(KoCharacterStyle::ChangeTrackerId, element->getDeleteChangeMarker()->changeId());+          caret.mergeCharFormat(f);+          caret.insertText(element->getDeleteData());+          numAddedChars += element->getDeleteData().length();+        }+    }++    caret.endEditBlock();+}++void ShowChangesCommand::removeDeletedChanges()+{+    int numDeletedChars = 0;+    QVector<KoChangeTrackerElement *> elementVector;+    KoTextDocument(m_tool->m_textEditor->document()).changeTracker()->getDeletedChanges(elementVector);++    QTextCursor caret(m_tool->m_textEditor->document());+    caret.beginEditBlock();++    foreach(KoChangeTrackerElement *element, elementVector)+    {+        if (element->isValid()) {+          QTextCharFormat f;+          caret.setPosition(element->getDeleteChangeMarker()->position() +  1 - numDeletedChars);+          caret.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, element->getDeleteData().length());+          caret.removeSelectedText();+          numDeletedChars += element->getDeleteData().length();+        }+    }++    caret.endEditBlock();+}++ShowChangesCommand::~ShowChangesCommand()+{++}Index: koffice/plugins/textshape/commands/ShowChangesCommand.h===================================================================--- koffice/plugins/textshape/commands/ShowChangesCommand.h	(revision 0)+++ koffice/plugins/textshape/commands/ShowChangesCommand.h	(revision 0)@@ -0,0 +1,49 @@+/*+ This file is part of the KDE project+ * Copyright (C) 2009 Ganesh Paramasivam <ganesh@crystalfab.com>+ *+ * This library is free software; you can redistribute it and/or+ * modify it under the terms of the GNU Library General Public+ * License as published by the Free Software Foundation; either+ * version 2 of the License, or (at your option) any later version.+ *+ * This library is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+ * Library General Public License for more details.+ *+ * You should have received a copy of the GNU Library General Public License+ * along with this library; see the file COPYING.LIB.  If not, write to+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,+ * Boston, MA 02110-1301, USA.*/++#ifndef SHOWCHANGECOMMAND_H+#define SHOWCHANGECOMMAND_H++#include <QUndoStack>+#include "TextCommandBase.h"++class TextTool;++class ShowChangesCommand : public TextCommandBase+{+public:++    ShowChangesCommand(bool shoeChanges, TextTool *tool, QUndoCommand* parent = 0);+    ~ShowChangesCommand();++    virtual void undo();+    virtual void redo();++private:+    void enableDisableChanges();+    void enableDisableStates(bool showChanges);+    void insertDeletedChanges();+    void removeDeletedChanges();++    TextTool *m_tool;+    bool m_first;+    bool m_showChanges;+};++#endif // SHOWCHANGECOMMAND_HIndex: koffice/plugins/textshape/commands/TextPasteCommand.cpp===================================================================--- koffice/plugins/textshape/commands/TextPasteCommand.cpp	(revision 1046549)+++ koffice/plugins/textshape/commands/TextPasteCommand.cpp	(working copy)@@ -30,6 +30,8 @@  #include <QApplication> #include <QMimeData>+#include "DeleteCommand.h"+#include <KAction>  TextPasteCommand::TextPasteCommand(QClipboard::Mode mode, TextTool *tool, QUndoCommand *parent)     : QUndoCommand (parent),@@ -56,7 +58,10 @@         editor->cursor()->beginEditBlock();         m_first = false;         if (editor->hasSelection()) {//TODO-            editor->deleteChar();+            if(m_tool->m_actionShowChanges->isChecked())+              editor->addCommand(new DeleteCommand(DeleteCommand::NextChar, m_tool));+            else+              editor->deleteChar();         }          // check for mime typeIndex: koffice/plugins/textshape/TextTool.h===================================================================--- koffice/plugins/textshape/TextTool.h	(revision 1046549)+++ koffice/plugins/textshape/TextTool.h	(working copy)@@ -262,6 +262,8 @@     friend class ChangeTracker;     friend class TextPasteCommand;     friend class TextCutCommand;+    friend class ShowChangesCommand;+    friend class DeleteCommand;     TextShape *m_textShape;     KoTextShapeData *m_textShapeData;     QPointer<KoTextEditor> m_textEditor;@@ -286,6 +288,7 @@     KAction *m_actionFormatSub;     KAction *m_actionFormatIncreaseIndent;     KAction *m_actionFormatDecreaseIndent;+    KAction *m_actionShowChanges;     KFontSizeAction *m_actionFormatFontSize;     KFontAction *m_actionFormatFontFamily; #ifndef NO_PIGMENTIndex: koffice/libs/kotext/opendocument/KoTextLoader.cpp===================================================================--- koffice/libs/kotext/opendocument/KoTextLoader.cpp	(revision 1046549)+++ koffice/libs/kotext/opendocument/KoTextLoader.cpp	(working copy)@@ -711,6 +711,7 @@                 KoDeleteChangeMarker *deleteChangemarker = new KoDeleteChangeMarker(d->changeTracker);                 deleteChangemarker->setChangeId(changeId);                 KoChangeTrackerElement *changeElement = d->changeTracker->elementById(changeId);+                changeElement->setDeleteChangeMarker(deleteChangemarker);                 changeElement->setEnabled(true);                 KoTextDocumentLayout *layout = qobject_cast<KoTextDocumentLayout*>(cursor.block().document()->documentLayout()); Index: koffice/libs/kotext/KoTextEditor.h===================================================================--- koffice/libs/kotext/KoTextEditor.h	(revision 1046549)+++ koffice/libs/kotext/KoTextEditor.h	(working copy)@@ -30,6 +30,8 @@ #include <QClipboard> #include <QMetaType> #include <QTextCursor>+#include <QUndoCommand>+#include <QPointer>  class KoCharacterStyle; class KoInlineObject;@@ -41,7 +43,6 @@ class QTextDocument; class QTextDocumentFragment; class QString;-class QUndoCommand;  class KOTEXT_EXPORT KoTextEditor: public KoToolSelection {@@ -248,6 +249,18 @@     Private* const d; }; +class KOTEXT_EXPORT UndoTextCommand : public QUndoCommand+{+  public:+    UndoTextCommand(QTextDocument *document, QUndoCommand *parent = 0);++    void undo();++    void redo();++    QPointer<QTextDocument> m_document;+};+ Q_DECLARE_METATYPE(KoTextEditor*)  #endif // KOTEXTEDITOR_HIndex: koffice/libs/kotext/changetracker/KoChangeTracker.h===================================================================--- koffice/libs/kotext/changetracker/KoChangeTracker.h	(revision 1046549)+++ koffice/libs/kotext/changetracker/KoChangeTracker.h	(working copy)@@ -66,7 +66,11 @@     int getDeleteChangeId(QString title, QTextDocumentFragment selection, int existingChangeId);      KoChangeTrackerElement* elementById(int id);+    bool removeById(int id, bool freeMemory = true); +    //Returns all the deleted changes+    int getDeletedChanges(QVector<KoChangeTrackerElement *>& deleteVector);+     bool containsInlineChanges(const QTextFormat &format);     int mergeableId(KoGenChange::Type type, QString &title, int existingId); Index: koffice/libs/kotext/changetracker/KoDeleteChangeMarker.cpp===================================================================--- koffice/libs/kotext/changetracker/KoDeleteChangeMarker.cpp	(revision 1046549)+++ koffice/libs/kotext/changetracker/KoDeleteChangeMarker.cpp	(working copy)@@ -44,6 +44,7 @@     KoChangeTracker *changeTracker;     QString text;     int id;+    int position; };  KoDeleteChangeMarker::KoDeleteChangeMarker(KoChangeTracker* changeTracker)@@ -77,6 +78,11 @@     return d->id; } +int KoDeleteChangeMarker::position() const+{+    return d->position;+}+ bool KoDeleteChangeMarker::loadOdf(const KoXmlElement &element) {     Q_UNUSED(element)@@ -86,63 +92,26 @@ void KoDeleteChangeMarker::paint(QPainter& painter, QPaintDevice *pd, const QTextDocument *document, const QRectF &rect, QTextInlineObject object, int posInDocument, const QTextCharFormat &format) {     Q_UNUSED(posInDocument);-    Q_UNUSED(document);--    if (!d->changeTracker)-        return;--    Q_ASSERT(format.isCharFormat());--    if (d->changeTracker->isEnabled() && d->changeTracker->elementById(d->id)->isEnabled() && d->changeTracker->displayDeleted()) {-        QFont font(format.font(), pd);-        QTextLayout layout(d->changeTracker->elementById(d->id)->getDeleteData(), font, pd);-        layout.setCacheEnabled(true);-        QList<QTextLayout::FormatRange> layouts;-        QTextLayout::FormatRange range;-        range.start = 0;-        range.length = d->changeTracker->elementById(d->id)->getDeleteData().length();-        range.format = format;-        range.format.setBackground(QBrush(Qt::red));-        layouts.append(range);-        layout.setAdditionalFormats(layouts);--        QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute);-        option.setTextDirection(object.textDirection());-        layout.setTextOption(option);-        layout.beginLayout();-        layout.createLine();-        layout.endLayout();-        layout.draw(&painter, rect.topLeft());-    } }  void KoDeleteChangeMarker::resize(const QTextDocument *document, QTextInlineObject object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd) {-    Q_UNUSED(posInDocument);     Q_UNUSED(document);+    Q_UNUSED(object);+    Q_UNUSED(format);+    Q_UNUSED(pd);+    Q_UNUSED(document); -    if (!d->changeTracker)-        return;--    Q_ASSERT(format.isCharFormat());-    QFontMetricsF fm(format.font(), pd);--    if (d->changeTracker->isEnabled() && d->changeTracker->elementById(d->id)->isEnabled() && d->changeTracker->displayDeleted()) {-        object.setWidth(fm.width(d->changeTracker->elementById(d->id)->getDeleteData()));-        object.setAscent(fm.ascent());-        object.setDescent(fm.descent());-    } else {-        object.setWidth(0);-        object.setAscent(fm.ascent());-        object.setDescent(fm.descent());-    }+    d->position = posInDocument;+    object.setWidth(0); }  void KoDeleteChangeMarker::updatePosition(const QTextDocument *document, QTextInlineObject object, int posInDocument, const QTextCharFormat &format) {+    d->position = posInDocument;+     Q_UNUSED(document);     Q_UNUSED(object);-    Q_UNUSED(posInDocument);     Q_UNUSED(format); } Index: koffice/libs/kotext/changetracker/KoChangeTrackerElement.cpp===================================================================--- koffice/libs/kotext/changetracker/KoChangeTrackerElement.cpp	(revision 1046549)+++ koffice/libs/kotext/changetracker/KoChangeTrackerElement.cpp	(working copy)@@ -35,9 +35,12 @@     QString creator;     QString date;     QString extraMetaData;+    //These two elements are valid for delete changes. Need to move it to a sub-class     QString deleteData;+    KoDeleteChangeMarker *marker;      bool enabled;+    bool valid; };  KoChangeTrackerElement::KoChangeTrackerElement(const QString& title, KoGenChange::Type type)@@ -45,6 +48,7 @@ {     d->title = title;     d->type = type;+    d->valid = true; }  KoChangeTrackerElement::KoChangeTrackerElement()@@ -64,6 +68,7 @@     d->extraMetaData = other.d->extraMetaData;     d->deleteData = other.d->deleteData;     d->enabled = other.d->enabled;+    d->valid = other.d->valid; }  KoChangeTrackerElement::~KoChangeTrackerElement()@@ -81,6 +86,16 @@     return d->enabled; } +void KoChangeTrackerElement::setValid(bool valid)+{+    d->valid = valid;+}++bool KoChangeTrackerElement::isValid() const+{+    return d->valid;+}+ void KoChangeTrackerElement::setChangeType(KoGenChange::Type type) {     d->type = type;@@ -181,3 +196,13 @@     return d->deleteData; } +void KoChangeTrackerElement::setDeleteChangeMarker(KoDeleteChangeMarker *marker)+{+    d->marker = marker;+}++KoDeleteChangeMarker *KoChangeTrackerElement::getDeleteChangeMarker()+{+    return d->marker;+}+Index: koffice/libs/kotext/changetracker/KoDeleteChangeMarker.h===================================================================--- koffice/libs/kotext/changetracker/KoDeleteChangeMarker.h	(revision 1046549)+++ koffice/libs/kotext/changetracker/KoDeleteChangeMarker.h	(working copy)@@ -53,6 +53,9 @@     /// return the change id     int changeId() const; +    ///Return the position of the marker in the document+    int position() const;+     bool loadOdf(const KoXmlElement &element);     ///reimplemented     virtual void saveOdf(KoShapeSavingContext &context);Index: koffice/libs/kotext/changetracker/KoChangeTrackerElement.h===================================================================--- koffice/libs/kotext/changetracker/KoChangeTrackerElement.h	(revision 1046549)+++ koffice/libs/kotext/changetracker/KoChangeTrackerElement.h	(working copy)@@ -27,7 +27,9 @@ #include <KoGenChange.h>  #include "kotext_export.h"+#include "KoDeleteChangeMarker.h" + class KOTEXT_EXPORT KoChangeTrackerElement { public:@@ -43,6 +45,9 @@     void setEnabled(bool enabled);     bool isEnabled() const; +    void setValid(bool valid);+    bool isValid() const;+     void setChangeType(KoGenChange::Type type);     KoGenChange::Type getChangeType() const; @@ -71,6 +76,9 @@     void setDeleteData(const QString& data);     QString getDeleteData() const; +    void setDeleteChangeMarker(KoDeleteChangeMarker *marker);+    KoDeleteChangeMarker *getDeleteChangeMarker();+ private:     class Private;     Private* const d;Index: koffice/libs/kotext/changetracker/KoChangeTracker.cpp===================================================================--- koffice/libs/kotext/changetracker/KoChangeTracker.cpp	(revision 1046549)+++ koffice/libs/kotext/changetracker/KoChangeTracker.cpp	(working copy)@@ -178,6 +178,14 @@     return d->m_changes.value(id); } +bool KoChangeTracker::removeById(int id, bool freeMemory)+{+    if (freeMemory) {+      KoChangeTrackerElement *temp = d->m_changes.value(id);+      delete temp;+    }+    return d->m_changes.remove(id);+}  bool KoChangeTracker::containsInlineChanges(const QTextFormat &format) {@@ -308,4 +316,19 @@     return true; } +int KoChangeTracker::getDeletedChanges(QVector<KoChangeTrackerElement *>& deleteVector)+{+    int numAppendedItems = 0;+    foreach(KoChangeTrackerElement *element, d->m_changes.values())+    {+        if(element->getChangeType() == KoGenChange::deleteChange)+        {+          deleteVector << element;+          numAppendedItems++;+        }+    }++    return numAppendedItems;+}+ #include "KoChangeTracker.moc"Index: koffice/libs/kotext/KoTextEditor.cpp===================================================================--- koffice/libs/kotext/KoTextEditor.cpp	(revision 1046549)+++ koffice/libs/kotext/KoTextEditor.cpp	(working copy)@@ -98,28 +98,6 @@  void KoTextEditor::Private::documentCommandAdded() {-    class UndoTextCommand : public QUndoCommand-    {-    public:-        UndoTextCommand(QTextDocument *document, QUndoCommand *parent = 0)-        : QUndoCommand(i18n("Text"), parent),-        m_document(document)-        {}--        void undo() {-            if (m_document.isNull())-                return;-            m_document->undo(KoTextDocument(m_document).textEditor()->cursor());-        }--        void redo() {-            if (m_document.isNull())-                return;-            m_document->redo(KoTextDocument(m_document).textEditor()->cursor());-        }--        QPointer<QTextDocument> m_document;-    };     //kDebug() << "editor state: " << editorState << " headcommand: " << headCommand;     if (!headCommand || editorState == NoOp) {         headCommand = new QUndoCommand(commandTitle);@@ -218,12 +196,7 @@         delText.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);     QString text = delText.selectedText();     QTextDocumentFragment selection = delText.selection();-    if (KoTextDocument(document).changeTracker() && KoTextDocument(document).changeTracker()->isEnabled()) {-        QTextCharFormat format = caret.charFormat();-        q->registerTrackedChange(caret, KoGenChange::deleteChange, i18n("Delete"), format, format); //this will replace the text to be deleted by a marker.-    }-    else-        caret.deleteChar();+    caret.deleteChar(); }  void KoTextEditor::Private::runDirectionUpdater()@@ -376,62 +349,7 @@         selection.mergeCharFormat(f);     }     else {-        QTextCursor checker = QTextCursor(selection);-        KoDeleteChangeMarker *deleteChangemarker = 0;-        KoDeleteChangeMarker *testMarker;-        bool backwards = (checker.anchor() > checker.position());-        int selectionBegin = qMin(checker.anchor(), checker.position());-        int selectionEnd = qMax(checker.anchor(), checker.position());-        int changeId;-        QString prefix;-        QString sufix;-        QString delText;-        checker.setPosition(selectionBegin);-        testMarker = dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(checker));-        if (testMarker) {-            prefix =  KoTextDocument(d->document).changeTracker()->elementById(testMarker->changeId())->getDeleteData();-        }-        checker.setPosition(selectionEnd);-        if (!checker.atEnd()) {-            checker.movePosition(QTextCursor::NextCharacter);-            testMarker = dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(checker));-            if (testMarker) {-                sufix =  KoTextDocument(d->document).changeTracker()->elementById(testMarker->changeId())->getDeleteData();-            }-        }-        checker.setPosition(selectionBegin);-        while (checker.position() < selectionEnd && !checker.atEnd()) {-            checker.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);-            if (layout->inlineTextObjectManager()->inlineTextObject(checker)) {-                testMarker = dynamic_cast<KoDeleteChangeMarker*>(layout->inlineTextObjectManager()->inlineTextObject(checker));-                if (testMarker) {-                    delText = delText + KoTextDocument(d->document).changeTracker()->elementById(testMarker->changeId())->getDeleteData();-                }-            }-            else {-                delText = delText + checker.selectedText();-            }-            checker.setPosition(checker.position());-        }--        QTextDocumentFragment deletedFragment = selection.selection();-        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()) {-            selection.setPosition(selectionBegin);-            selection.setPosition(selectionEnd+1, QTextCursor::KeepAnchor);-            selectionEnd++;-        }-        if (!prefix.isEmpty()) {-            selection.setPosition(selectionBegin-1);-            selection.setPosition(selectionEnd, QTextCursor::KeepAnchor);-            selectionBegin--;-        }-        layout->inlineTextObjectManager()->insertInlineObject(selection, deleteChangemarker);-        KoTextDocument(d->document).changeTracker()->elementById(deleteChangemarker->changeId())->setDeleteData(prefix + delText + sufix);-        if (backwards)-            selection.movePosition(QTextCursor::PreviousCharacter);+        //Handled in DeleteCommand     } } @@ -1132,4 +1050,27 @@     d->caret.endEditBlock(); } +UndoTextCommand::UndoTextCommand(QTextDocument *document, QUndoCommand *parent)+  : QUndoCommand(i18n("Text"), parent),+  m_document(document)+{++}++void UndoTextCommand::undo()+{+    if (m_document.isNull())+      return;+    +    m_document->undo(KoTextDocument(m_document).textEditor()->cursor());+}++void UndoTextCommand::redo()+{+    if (m_document.isNull())+      return;+    +    m_document->redo(KoTextDocument(m_document).textEditor()->cursor());+}+ #include "KoTextEditor.moc"