Commit cd7df865 authored by hjk's avatar hjk
Browse files

Remove ITextMarkable



There was only a single user (TextEditor::DocumentMarker) which
in turn was only used in a single place (BaseTextDocument), so
merge the ITextMarkable into BaseTextDocument.

Change-Id: I1ca8675f9fc22cb56097b843dc5a0fe76875d3e7
Reviewed-by: default avatarEike Ziller <eike.ziller@digia.com>
parent 19a44fd7
......@@ -192,7 +192,7 @@ void DisassemblerAgent::resetLocation()
return;
if (d->resetLocationScheduled) {
d->resetLocationScheduled = false;
d->document->markableInterface()->removeMark(&d->locationMark);
d->document->removeMark(&d->locationMark);
}
}
......@@ -331,9 +331,9 @@ void DisassemblerAgent::updateLocationMarker()
const DisassemblerLines contents = d->contentsAtCurrentLocation();
int lineNumber = contents.lineForAddress(d->location.address());
if (d->location.needsMarker()) {
d->document->markableInterface()->removeMark(&d->locationMark);
d->document->removeMark(&d->locationMark);
d->locationMark.updateLineNumber(lineNumber);
d->document->markableInterface()->addMark(&d->locationMark);
d->document->addMark(&d->locationMark);
}
// Center cursor.
......@@ -354,7 +354,7 @@ void DisassemblerAgent::updateBreakpointMarkers()
const DisassemblerLines contents = d->contentsAtCurrentLocation();
foreach (TextEditor::ITextMark *marker, d->breakpointMarks)
d->document->markableInterface()->removeMark(marker);
d->document->removeMark(marker);
qDeleteAll(d->breakpointMarks);
d->breakpointMarks.clear();
foreach (BreakpointModelId id, ids) {
......@@ -368,7 +368,7 @@ void DisassemblerAgent::updateBreakpointMarkers()
marker->setIcon(handler->icon(id));
marker->setPriority(ITextMark::NormalPriority);
d->breakpointMarks.append(marker);
d->document->markableInterface()->addMark(marker);
d->document->addMark(marker);
}
}
......
......@@ -59,7 +59,7 @@ public:
~SourceAgentPrivate();
public:
QPointer<TextEditor::ITextEditor> editor;
QPointer<TextEditor::BaseTextEditor> editor;
QPointer<DebuggerEngine> engine;
TextEditor::ITextMark *locationMark;
QString path;
......@@ -109,23 +109,21 @@ void SourceAgent::setContent(const QString &filePath, const QString &content)
if (!d->editor) {
QString titlePattern = d->producer + QLatin1String(": ")
+ QFileInfo(filePath).fileName();
d->editor = qobject_cast<ITextEditor *>(
d->editor = qobject_cast<BaseTextEditor *>(
EditorManager::openEditorWithContents(
CppEditor::Constants::CPPEDITOR_ID,
&titlePattern, content.toUtf8()));
QTC_ASSERT(d->editor, return);
d->editor->document()->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
BaseTextEditorWidget *baseTextEdit =
qobject_cast<BaseTextEditorWidget *>(d->editor->widget());
BaseTextEditorWidget *baseTextEdit = d->editor->editorWidget();
if (baseTextEdit)
baseTextEdit->setRequestMarkEnabled(true);
} else {
EditorManager::activateEditor(d->editor);
}
QPlainTextEdit *plainTextEdit =
qobject_cast<QPlainTextEdit *>(d->editor->widget());
QPlainTextEdit *plainTextEdit = d->editor->editorWidget();
QTC_ASSERT(plainTextEdit, return);
plainTextEdit->setReadOnly(true);
......@@ -137,7 +135,7 @@ void SourceAgent::updateLocationMarker()
QTC_ASSERT(d->editor, return);
if (d->locationMark)
d->editor->textDocument()->markableInterface()->removeMark(d->locationMark);
d->editor->baseTextDocument()->removeMark(d->locationMark);
delete d->locationMark;
d->locationMark = 0;
if (d->engine->stackHandler()->currentFrame().file == d->path) {
......@@ -145,8 +143,8 @@ void SourceAgent::updateLocationMarker()
d->locationMark = new TextEditor::ITextMark(lineNumber);
d->locationMark->setIcon(debuggerCore()->locationMarkIcon());
d->locationMark->setPriority(TextEditor::ITextMark::HighPriority);
d->editor->textDocument()->markableInterface()->addMark(d->locationMark);
QPlainTextEdit *plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget());
d->editor->baseTextDocument()->addMark(d->locationMark);
QPlainTextEdit *plainTextEdit = d->editor->editorWidget();
QTC_ASSERT(plainTextEdit, return);
QTextCursor tc = plainTextEdit->textCursor();
QTextBlock block = tc.document()->findBlockByNumber(lineNumber - 1);
......
......@@ -92,6 +92,8 @@ public:
bool m_fileIsReadOnly;
int m_autoSaveRevision;
TextMarks m_marksCache; // Marks not owned
};
BaseTextDocumentPrivate::BaseTextDocumentPrivate(BaseTextDocument *q) :
......@@ -373,14 +375,6 @@ SyntaxHighlighter *BaseTextDocument::syntaxHighlighter() const
return d->m_highlighter;
}
ITextMarkable *BaseTextDocument::markableInterface() const
{
BaseTextDocumentLayout *documentLayout =
qobject_cast<BaseTextDocumentLayout *>(d->m_document->documentLayout());
QTC_ASSERT(documentLayout, return 0);
return documentLayout->markableInterface();
}
/*!
* Saves the document to the file specified by \a fileName. If errors occur,
* \a errorString contains their cause.
......@@ -583,7 +577,7 @@ bool BaseTextDocument::reload(QString *errorString)
bool success = open(errorString, filePath(), filePath());
if (documentLayout)
documentLayout->documentReloaded(marks); // readds text marks
documentLayout->documentReloaded(marks, this); // re-adds text marks
emit reloadFinished(success);
return success;
}
......@@ -684,6 +678,130 @@ void BaseTextDocument::ensureFinalNewLine(QTextCursor& cursor)
}
}
TextMarks BaseTextDocument::marks() const
{
return d->m_marksCache;
}
bool BaseTextDocument::addMark(ITextMark *mark)
{
if (mark->baseTextDocument())
return false;
QTC_ASSERT(mark->lineNumber() >= 1, return false);
int blockNumber = mark->lineNumber() - 1;
auto documentLayout = qobject_cast<BaseTextDocumentLayout*>(d->m_document->documentLayout());
QTC_ASSERT(documentLayout, return false);
QTextBlock block = d->m_document->findBlockByNumber(blockNumber);
if (block.isValid()) {
TextBlockUserData *userData = BaseTextDocumentLayout::userData(block);
userData->addMark(mark);
d->m_marksCache.append(mark);
mark->updateLineNumber(blockNumber + 1);
QTC_CHECK(mark->lineNumber() == blockNumber + 1); // Checks that the base class is called
mark->updateBlock(block);
mark->setBaseTextDocument(this);
if (!mark->isVisible())
return true;
// Update document layout
double newMaxWidthFactor = qMax(mark->widthFactor(), documentLayout->maxMarkWidthFactor);
bool fullUpdate = newMaxWidthFactor > documentLayout->maxMarkWidthFactor || !documentLayout->hasMarks;
documentLayout->hasMarks = true;
documentLayout->maxMarkWidthFactor = newMaxWidthFactor;
if (fullUpdate)
documentLayout->requestUpdate();
else
documentLayout->requestExtraAreaUpdate();
return true;
}
return false;
}
TextMarks BaseTextDocument::marksAt(int line) const
{
QTC_ASSERT(line >= 1, return TextMarks());
int blockNumber = line - 1;
QTextBlock block = d->m_document->findBlockByNumber(blockNumber);
if (block.isValid()) {
if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(block))
return userData->marks();
}
return TextMarks();
}
void BaseTextDocument::removeMarkFromMarksCache(ITextMark *mark)
{
auto documentLayout = qobject_cast<BaseTextDocumentLayout*>(d->m_document->documentLayout());
QTC_ASSERT(documentLayout, return);
d->m_marksCache.removeAll(mark);
if (d->m_marksCache.isEmpty()) {
documentLayout->hasMarks = false;
documentLayout->maxMarkWidthFactor = 1.0;
documentLayout->requestUpdate();
return;
}
if (!mark->isVisible())
return;
if (documentLayout->maxMarkWidthFactor == 1.0
|| mark->widthFactor() == 1.0
|| mark->widthFactor() < documentLayout->maxMarkWidthFactor) {
// No change in width possible
documentLayout->requestExtraAreaUpdate();
} else {
double maxWidthFactor = 1.0;
foreach (const ITextMark *mark, marks()) {
if (!mark->isVisible())
continue;
maxWidthFactor = qMax(mark->widthFactor(), maxWidthFactor);
if (maxWidthFactor == documentLayout->maxMarkWidthFactor)
break; // Still a mark with the maxMarkWidthFactor
}
if (maxWidthFactor != documentLayout->maxMarkWidthFactor) {
documentLayout->maxMarkWidthFactor = maxWidthFactor;
documentLayout->requestUpdate();
} else {
documentLayout->requestExtraAreaUpdate();
}
}
}
void BaseTextDocument::removeMark(ITextMark *mark)
{
QTextBlock block = d->m_document->findBlockByNumber(mark->lineNumber() - 1);
if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) {
if (!data->removeMark(mark))
qDebug() << "Could not find mark" << mark << "on line" << mark->lineNumber();
}
removeMarkFromMarksCache(mark);
mark->setBaseTextDocument(0);
}
void BaseTextDocument::updateMark(ITextMark *mark)
{
Q_UNUSED(mark)
auto documentLayout = qobject_cast<BaseTextDocumentLayout*>(d->m_document->documentLayout());
QTC_ASSERT(documentLayout, return);
documentLayout->requestUpdate();
}
void BaseTextDocument::moveMark(ITextMark *mark, int previousLine)
{
QTextBlock block = d->m_document->findBlockByNumber(previousLine - 1);
if (TextBlockUserData *data = BaseTextDocumentLayout::testUserData(block)) {
if (!data->removeMark(mark))
qDebug() << "Could not find mark" << mark << "on line" << previousLine;
}
removeMarkFromMarksCache(mark);
mark->setBaseTextDocument(0);
addMark(mark);
}
} // namespace TextEditor
#include "basetextdocument.moc"
......@@ -34,6 +34,8 @@
#include "itexteditor.h"
#include <QList>
QT_BEGIN_NAMESPACE
class QTextCursor;
class QTextDocument;
......@@ -44,13 +46,14 @@ namespace TextEditor {
class BaseTextDocumentPrivate;
class ExtraEncodingSettings;
class FontSettings;
class ITextMarkable;
class Indenter;
class StorageSettings;
class SyntaxHighlighter;
class TabSettings;
class TypingSettings;
typedef QList<ITextMark *> TextMarks;
class TEXTEDITOR_EXPORT BaseTextDocument : public ITextEditorDocument
{
Q_OBJECT
......@@ -81,7 +84,13 @@ public:
QTextCursor indent(const QTextCursor &cursor);
QTextCursor unindent(const QTextCursor &cursor);
ITextMarkable *markableInterface() const;
TextMarks marks() const;
bool addMark(ITextMark *mark);
TextMarks marksAt(int line) const;
void removeMark(ITextMark *mark);
void updateMark(ITextMark *mark);
void moveMark(ITextMark *mark, int previousLine);
void removeMarkFromMarksCache(TextEditor::ITextMark *mark);
// IDocument implementation.
bool save(QString *errorString, const QString &fileName, bool autoSave);
......
......@@ -33,165 +33,6 @@
using namespace TextEditor;
namespace TextEditor {
namespace Internal {
class DocumentMarker : public ITextMarkable
{
Q_OBJECT
public:
DocumentMarker(QTextDocument *);
~DocumentMarker();
TextMarks marks() const { return m_marksCache; }
// ITextMarkable
bool addMark(ITextMark *mark);
TextMarks marksAt(int line) const;
void removeMark(ITextMark *mark);
void updateMark(ITextMark *mark);
void moveMark(ITextMark *mark, int previousLine);
void removeMarkFromMarksCache(TextEditor::ITextMark *mark);
private:
TextMarks m_marksCache; // not owned
QTextDocument *document;
};
DocumentMarker::DocumentMarker(QTextDocument *doc)
: ITextMarkable(doc), document(doc)
{
}
DocumentMarker::~DocumentMarker()
{
}
bool DocumentMarker::addMark(TextEditor::ITextMark *mark)
{
if (mark->markableInterface())
return false;
QTC_ASSERT(mark->lineNumber() >= 1, return false);
int blockNumber = mark->lineNumber() - 1;
BaseTextDocumentLayout *documentLayout =
qobject_cast<BaseTextDocumentLayout*>(document->documentLayout());
QTC_ASSERT(documentLayout, return false);
QTextBlock block = document->findBlockByNumber(blockNumber);
if (block.isValid()) {
TextBlockUserData *userData = BaseTextDocumentLayout::userData(block);
userData->addMark(mark);
m_marksCache.append(mark);
mark->updateLineNumber(blockNumber + 1);
QTC_CHECK(mark->lineNumber() == blockNumber + 1); // Checks that the base class is called
mark->updateBlock(block);
mark->setMarkableInterface(this);
if (!mark->isVisible())
return true;
// Update document layout
double newMaxWidthFactor = qMax(mark->widthFactor(), documentLayout->maxMarkWidthFactor);
bool fullUpdate = newMaxWidthFactor > documentLayout->maxMarkWidthFactor || !documentLayout->hasMarks;
documentLayout->hasMarks = true;
documentLayout->maxMarkWidthFactor = newMaxWidthFactor;
if (fullUpdate)
documentLayout->requestUpdate();
else
documentLayout->requestExtraAreaUpdate();
return true;
}
return false;
}
TextEditor::TextMarks DocumentMarker::marksAt(int line) const
{
QTC_ASSERT(line >= 1, return TextMarks());
int blockNumber = line - 1;
QTextBlock block = document->findBlockByNumber(blockNumber);
if (block.isValid()) {
if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(block))
return userData->marks();
}
return TextMarks();
}
void DocumentMarker::removeMarkFromMarksCache(TextEditor::ITextMark *mark)
{
BaseTextDocumentLayout *documentLayout =
qobject_cast<BaseTextDocumentLayout*>(document->documentLayout());
QTC_ASSERT(documentLayout, return);
m_marksCache.removeAll(mark);
if (m_marksCache.isEmpty()) {
documentLayout->hasMarks = false;
documentLayout->maxMarkWidthFactor = 1.0;
documentLayout->requestUpdate();
return;
}
if (!mark->isVisible())
return;
if (documentLayout->maxMarkWidthFactor == 1.0
|| mark->widthFactor() == 1.0
|| mark->widthFactor() < documentLayout->maxMarkWidthFactor) {
// No change in width possible
documentLayout->requestExtraAreaUpdate();
} else {
double maxWidthFactor = 1.0;
foreach (const ITextMark *mark, marks()) {
if (!mark->isVisible())
continue;
maxWidthFactor = qMax(mark->widthFactor(), maxWidthFactor);
if (maxWidthFactor == documentLayout->maxMarkWidthFactor)
break; // Still a mark with the maxMarkWidthFactor
}
if (maxWidthFactor != documentLayout->maxMarkWidthFactor) {
documentLayout->maxMarkWidthFactor = maxWidthFactor;
documentLayout->requestUpdate();
} else {
documentLayout->requestExtraAreaUpdate();
}
}
}
void DocumentMarker::removeMark(TextEditor::ITextMark *mark)
{
QTextBlock block = document->findBlockByNumber(mark->lineNumber() - 1);
if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData())) {
if (!data->removeMark(mark))
qDebug() << "Could not find mark" << mark << "on line" << mark->lineNumber();
}
removeMarkFromMarksCache(mark);
mark->setMarkableInterface(0);
}
void DocumentMarker::updateMark(ITextMark *mark)
{
Q_UNUSED(mark)
BaseTextDocumentLayout *documentLayout =
qobject_cast<BaseTextDocumentLayout*>(document->documentLayout());
QTC_ASSERT(documentLayout, return);
documentLayout->requestUpdate();
}
void DocumentMarker::moveMark(ITextMark *mark, int previousLine)
{
QTextBlock block = document->findBlockByNumber(previousLine - 1);
if (TextBlockUserData *data = BaseTextDocumentLayout::testUserData(block)) {
if (!data->removeMark(mark))
qDebug() << "Could not find mark" << mark << "on line" << previousLine;
}
removeMarkFromMarksCache(mark);
mark->setMarkableInterface(0);
addMark(mark);
}
} // namespace Internal
} // namespace TextEditor
CodeFormatterData::~CodeFormatterData()
{
......@@ -200,10 +41,8 @@ CodeFormatterData::~CodeFormatterData()
TextBlockUserData::~TextBlockUserData()
{
foreach (ITextMark *mrk, m_marks) {
TextEditor::Internal::DocumentMarker *documentMarker
= static_cast<TextEditor::Internal::DocumentMarker *>(mrk->markableInterface());
documentMarker->removeMarkFromMarksCache(mrk);
mrk->setMarkableInterface(0);
mrk->baseTextDocument()->removeMarkFromMarksCache(mrk);
mrk->setBaseTextDocument(0);
mrk->removedFromEditor();
}
......@@ -553,11 +392,8 @@ BaseTextDocumentLayout::BaseTextDocumentLayout(QTextDocument *doc)
lastSaveRevision(0),
hasMarks(false),
maxMarkWidthFactor(1.0),
m_requiredWidth(0),
m_documentMarker(new Internal::DocumentMarker(doc))
{
}
m_requiredWidth(0)
{}
BaseTextDocumentLayout::~BaseTextDocumentLayout()
{
......@@ -702,11 +538,6 @@ void BaseTextDocumentLayout::requestExtraAreaUpdate()
emit updateExtraArea();
}
ITextMarkable *BaseTextDocumentLayout::markableInterface()
{
return m_documentMarker;
}
void BaseTextDocumentLayout::doFoldOrUnfold(const QTextBlock& block, bool unfold)
{
if (!canFold(block))
......@@ -760,7 +591,7 @@ TextMarks BaseTextDocumentLayout::documentClosing()
return marks;
}
void BaseTextDocumentLayout::documentReloaded(TextMarks marks)
void BaseTextDocumentLayout::documentReloaded(TextMarks marks, BaseTextDocument *baseTextDocument)
{
foreach (ITextMark *mark, marks) {
int blockNumber = mark->lineNumber() - 1;
......@@ -768,14 +599,12 @@ void BaseTextDocumentLayout::documentReloaded(TextMarks marks)
if (block.isValid()) {
TextBlockUserData *userData = BaseTextDocumentLayout::userData(block);
userData->addMark(mark);
mark->setMarkableInterface(m_documentMarker);
mark->setBaseTextDocument(baseTextDocument);
mark->updateBlock(block);
} else {
TextEditor::Internal::DocumentMarker *documentMarker
= static_cast<TextEditor::Internal::DocumentMarker *>(m_documentMarker);
documentMarker->removeMarkFromMarksCache(mark);
baseTextDocument->removeMarkFromMarksCache(mark);
mark->removedFromEditor();
mark->setMarkableInterface(0);
mark->setBaseTextDocument(0);
}
}
requestUpdate();
......@@ -868,5 +697,3 @@ void BaseTextDocumentLayout::FoldValidator::finalize()
m_layout->emitDocumentSizeChanged();
}
}
#include "basetextdocumentlayout.moc"
......@@ -32,7 +32,7 @@
#include "texteditor_global.h"
#include "itexteditor.h"
#include "basetexteditor.h"
#include <QTextBlockUserData>
#include <QPlainTextDocumentLayout>
......@@ -81,7 +81,7 @@ public:
inline TextMarks documentClosing() {
TextMarks marks = m_marks;
foreach (ITextMark *mrk, m_marks)
mrk->setMarkableInterface(0);
mrk->setBaseTextDocument(0);
m_marks.clear();
return marks;
}
......@@ -205,21 +205,19 @@ public:
void requestExtraAreaUpdate();
void emitDocumentSizeChanged() { emit documentSizeChanged(documentSize()); }
ITextMarkable *markableInterface();
int lastSaveRevision;
bool hasMarks;
double maxMarkWidthFactor;
int m_requiredWidth;
ITextMarkable *m_documentMarker;
void setRequiredWidth(int width);
QSizeF documentSize() const;
TextMarks documentClosing();
void documentReloaded(TextMarks marks);
void documentReloaded(TextMarks marks, BaseTextDocument *baseextDocument);
void updateMarksLineNumber();
void updateMarksBlock(const QTextBlock &block);
......
......@@ -67,8 +67,6 @@ namespace Internal {
typedef QString (QString::*TransformationMethod)() const;
}
class ITextMarkable;
class BaseTextEditor;
class FontSettings;
class BehaviorSettings;
......
......@@ -59,11 +59,10 @@ BaseTextMarkRegistry::BaseTextMarkRegistry(QObject *parent)
void BaseTextMarkRegistry::add(BaseTextMark *mark)
{
m_marks[FileName::fromString(mark->fileName())].insert(mark);
ITextEditorDocument *document
= qobject_cast<ITextEditorDocument*>(DocumentModel::documentForFilePath(mark->fileName()));
auto document = qobject_cast<BaseTextDocument*>(DocumentModel::documentForFilePath(mark->fileName()));
if (!document)
return;
document->markableInterface()->addMark(mark);
document->addMark(mark);
}