Commit 76020b61 authored by Thorbjørn Lindeijer's avatar Thorbjørn Lindeijer

Make sure bookmarks survive a document reload

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
parent a36d4b9b
......@@ -269,7 +269,9 @@ public:
if (type == TypePermissions) {
emit changed();
} else {
open(m_fileName);
emit aboutToReload();
if (open(m_fileName))
emit reloaded();
}
}
......
......@@ -48,7 +48,7 @@ class Bookmark : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
Bookmark(const QString& fileName, int lineNumber, BookmarkManager *manager);
Bookmark(const QString &fileName, int lineNumber, BookmarkManager *manager);
QIcon icon() const;
......
......@@ -92,6 +92,9 @@ public:
signals:
void changed();
void aboutToReload();
void reloaded();
};
} // namespace Core
......
......@@ -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();
}
}
......
......@@ -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();
}
}
......
......@@ -132,7 +132,7 @@ BaseTextDocument::BaseTextDocument()
m_fileIsReadOnly = false;
m_isBinaryData = false;
m_codec = QTextCodec::codecForLocale();
QSettings* settings = 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(QTextCursor& cursor, 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();
}
}
......@@ -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
......
......@@ -29,6 +29,8 @@
#include "basetextmark.h"
#include "basetextdocument.h"
#include <coreplugin/editormanager/editormanager.h>
#include <extensionsystem/pluginmanager.h>
......@@ -37,18 +39,25 @@
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);
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment