OSDN Git Service

Make sure bookmarks survive a document reload
authorThorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com>
Fri, 28 May 2010 12:06:57 +0000 (14:06 +0200)
committerThorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com>
Fri, 28 May 2010 13:44:59 +0000 (15:44 +0200)
While reloading a text document, the bookmarks got lost since their
associated QTextBlocks were deleted.

This patch makes sure that before reloading, the bookmarks are removed
non-persistently in the same way as when closing a document, and that
they are restored after the document was reloaded.

Currently, no effort is made to update the location of the bookmarks
based on the way the file changed.

Task-number: QTCREATORBUG-1281
Reviewed-by: dt
src/plugins/bineditor/bineditorplugin.cpp
src/plugins/bookmarks/bookmark.h
src/plugins/coreplugin/ifile.h
src/plugins/designer/formwindowfile.cpp
src/plugins/resourceeditor/resourceeditorw.cpp
src/plugins/texteditor/basetextdocument.cpp
src/plugins/texteditor/basetextdocument.h
src/plugins/texteditor/basetextmark.cpp
src/plugins/texteditor/basetextmark.h

index 432df20..3d9f02b 100644 (file)
@@ -269,7 +269,9 @@ public:
         if (type == TypePermissions) {
             emit changed();
         } else {
-            open(m_fileName);
+            emit aboutToReload();
+            if (open(m_fileName))
+                emit reloaded();
         }
     }
 
index efa2211..aeb800a 100644 (file)
@@ -48,7 +48,7 @@ class Bookmark : public TextEditor::BaseTextMark
 {
     Q_OBJECT
 public:
-    Bookmark(const QStringfileName, int lineNumber, BookmarkManager *manager);
+    Bookmark(const QString &fileName, int lineNumber, BookmarkManager *manager);
 
     QIcon icon() const;
 
index 575cac9..77a8412 100644 (file)
@@ -92,6 +92,9 @@ public:
 
 signals:
     void changed();
+
+    void aboutToReload();
+    void reloaded();
 };
 
 } // namespace Core
index a130cc9..bbf3505 100644 (file)
@@ -133,7 +133,9 @@ void FormWindowFile::reload(ReloadFlag flag, ChangeType type)
     if (type == TypePermissions) {
         emit changed();
     } else {
+        emit aboutToReload();
         emit reload(m_fileName);
+        emit reloaded();
     }
 }
 
index 75f9fb2..b37169b 100644 (file)
@@ -203,7 +203,9 @@ void ResourceEditorFile::reload(ReloadFlag flag, ChangeType type)
     if (type == TypePermissions) {
         emit changed();
     } else {
-        m_parent->open(m_parent->m_resourceEditor->fileName());
+        emit aboutToReload();
+        if (m_parent->open(m_parent->m_resourceEditor->fileName()))
+            emit reloaded();
     }
 }
 
index 8035f02..b25bafe 100644 (file)
@@ -132,7 +132,7 @@ BaseTextDocument::BaseTextDocument()
     m_fileIsReadOnly = false;
     m_isBinaryData = false;
     m_codec = QTextCodec::codecForLocale();
-    QSettingssettings = Core::ICore::instance()->settings();
+    QSettings *settings = Core::ICore::instance()->settings();
     if (QTextCodec *candidate = QTextCodec::codecForName(
             settings->value(QLatin1String("General/DefaultFileEncoding")).toByteArray()))
         m_codec = candidate;
@@ -142,12 +142,8 @@ BaseTextDocument::BaseTextDocument()
 
 BaseTextDocument::~BaseTextDocument()
 {
-    QTextBlock block = m_document->begin();
-    while (block.isValid()) {
-        if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData()))
-            data->documentClosing();
-        block = block.next();
-    }
+    documentClosing();
+
     delete m_document;
     m_document = 0;
 }
@@ -324,6 +320,8 @@ void BaseTextDocument::reload(QTextCodec *codec)
 void BaseTextDocument::reload()
 {
     emit aboutToReload();
+    documentClosing(); // removes text marks non-permanently
+
     if (open(m_fileName))
         emit reloaded();
 }
@@ -373,9 +371,8 @@ void BaseTextDocument::cleanWhitespace(const QTextCursor &cursor)
     copyCursor.endEditBlock();
 }
 
-void BaseTextDocument::cleanWhitespace(QTextCursorcursor, bool cleanIndentation, bool inEntireDocument)
+void BaseTextDocument::cleanWhitespace(QTextCursor &cursor, bool cleanIndentation, bool inEntireDocument)
 {
-
     BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(m_document->documentLayout());
 
     QTextBlock block = m_document->findBlock(cursor.selectionStart());
@@ -423,3 +420,13 @@ void BaseTextDocument::ensureFinalNewLine(QTextCursor& cursor)
         cursor.insertText(QLatin1String("\n"));
     }
 }
+
+void BaseTextDocument::documentClosing()
+{
+    QTextBlock block = m_document->begin();
+    while (block.isValid()) {
+        if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData()))
+            data->documentClosing();
+        block = block.next();
+    }
+}
index 2958fc3..cdf778f 100644 (file)
@@ -76,7 +76,7 @@ public:
     inline const StorageSettings &storageSettings() const { return m_storageSettings; }
     inline const TabSettings &tabSettings() const { return m_tabSettings; }
 
-    DocumentMarker *documentMarker() const {return m_documentMarker; }
+    DocumentMarker *documentMarker() const { return m_documentMarker; }
 
     //IFile
     virtual bool save(const QString &fileName = QString());
@@ -116,8 +116,6 @@ public:
 
 signals:
     void titleChanged(QString title);
-    void aboutToReload();
-    void reloaded();
 
 private:
     QString m_fileName;
@@ -150,6 +148,7 @@ private:
 
     void cleanWhitespace(QTextCursor& cursor, bool cleanIndentation, bool inEntireDocument);
     void ensureFinalNewLine(QTextCursor& cursor);
+    void documentClosing();
 };
 
 } // namespace TextEditor
index 17b238b..fb425cb 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "basetextmark.h"
 
+#include "basetextdocument.h"
+
 #include <coreplugin/editormanager/editormanager.h>
 #include <extensionsystem/pluginmanager.h>
 
 using namespace TextEditor;
 using namespace TextEditor::Internal;
 
-BaseTextMark::BaseTextMark()
-    : m_markableInterface(0), m_internalMark(0), m_init(false)
-{
-}
-
 BaseTextMark::BaseTextMark(const QString &filename, int line)
-    : m_markableInterface(0), m_internalMark(0), m_fileName(filename), m_line(line), m_init(false)
+    : m_markableInterface(0)
+    , m_internalMark(0)
+    , m_fileName(filename)
+    , m_line(line)
+    , m_init(false)
 {
     // Why is this?
     QTimer::singleShot(0, this, SLOT(init()));
 }
 
+BaseTextMark::~BaseTextMark()
+{
+    // oha we are deleted
+    if (m_markableInterface)
+        m_markableInterface->removeMark(m_internalMark);
+    removeInternalMark();
+}
+
 void BaseTextMark::init()
 {
     m_init = true;
@@ -73,39 +82,49 @@ void BaseTextMark::editorOpened(Core::IEditor *editor)
             m_markableInterface = textEditor->markableInterface();
             m_internalMark = new InternalMark(this);
 
-            if (!m_markableInterface->addMark(m_internalMark, m_line)) {
-                delete m_internalMark;
-                m_internalMark = 0;
-                m_markableInterface = 0;
+            if (m_markableInterface->addMark(m_internalMark, m_line)) {
+                // Handle reload of text documents, readding the mark as necessary
+                connect(textEditor->file(), SIGNAL(reloaded()),
+                        this, SLOT(documentReloaded()), Qt::UniqueConnection);
+            } else {
+                removeInternalMark();
             }
         }
     }
 }
 
+void BaseTextMark::documentReloaded()
+{
+    if (m_markableInterface)
+        return;
+
+    BaseTextDocument *doc = qobject_cast<BaseTextDocument*>(sender());
+    if (!doc)
+        return;
+
+    m_markableInterface = doc->documentMarker();
+    m_internalMark = new InternalMark(this);
+
+    if (!m_markableInterface->addMark(m_internalMark, m_line))
+        removeInternalMark();
+}
+
 void BaseTextMark::childRemovedFromEditor(InternalMark *mark)
 {
     Q_UNUSED(mark)
     // m_internalMark was removed from the editor
-    delete m_internalMark;
-    m_markableInterface = 0;
-    m_internalMark = 0;
+    removeInternalMark();
     removedFromEditor();
 }
 
 void BaseTextMark::documentClosingFor(InternalMark *mark)
 {
     Q_UNUSED(mark)
-    // the document is closing
-    delete m_internalMark;
-    m_markableInterface = 0;
-    m_internalMark = 0;
+    removeInternalMark();
 }
 
-BaseTextMark::~BaseTextMark()
+void BaseTextMark::removeInternalMark()
 {
-    // oha we are deleted
-    if (m_markableInterface)
-        m_markableInterface->removeMark(m_internalMark);
     delete m_internalMark;
     m_internalMark = 0;
     m_markableInterface = 0;
@@ -128,13 +147,10 @@ void BaseTextMark::moveMark(const QString & /* filename */, int /* line */)
         m_init = true;
     }
 
-
     if (m_markableInterface)
         m_markableInterface->removeMark(m_internalMark);
-    m_markableInterface = 0;
-    // This is only necessary since m_internalMark is created in ediorOpened
-    delete m_internalMark;
-    m_internalMark = 0;
+    // This is only necessary since m_internalMark is created in editorOpened
+    removeInternalMark();
 
     foreach (Core::IEditor *editor, em->openedEditors())
         editorOpened(editor);
index 244dd00..ad40b75 100644 (file)
@@ -45,8 +45,8 @@ class TEXTEDITOR_EXPORT BaseTextMark : public QObject
 {
     friend class Internal::InternalMark;
     Q_OBJECT
+
 public:
-    BaseTextMark();
     BaseTextMark(const QString &filename, int line);
     ~BaseTextMark();
 
@@ -69,12 +69,16 @@ public:
     int lineNumber() const { return m_line; }
 
     void moveMark(const QString &filename, int line);
+
 private slots:
-    void editorOpened(Core::IEditor *editor);
     void init();
+    void editorOpened(Core::IEditor *editor);
+    void documentReloaded();
+
 private:
     void childRemovedFromEditor(Internal::InternalMark *mark);
     void documentClosingFor(Internal::InternalMark *mark);
+    void removeInternalMark();
 
     ITextMarkable *m_markableInterface;
     Internal::InternalMark *m_internalMark;