texteditor: simplify basetextmark architecture

ITextMark is not abstract anymore and has an icon and a priority.
This means separate breakpoint and location marker classes that
are only "plain" marks with icons and priorities are not needed.

BaseTextMark directly inherits from ITextMark, instead of owning
an ITextMark derived InternalMark.

Also, there is now ITextMark::paint() to make it a bit more flexible
then icon()[->paint()]
This commit is contained in:
hjk
2011-03-21 17:15:02 +01:00
parent e73f43c759
commit a18d0572bd
12 changed files with 114 additions and 223 deletions

View File

@@ -40,7 +40,6 @@
using namespace Bookmarks::Internal; using namespace Bookmarks::Internal;
Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *manager) : Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *manager) :
BaseTextMark(fileName, lineNumber),
m_manager(manager), m_manager(manager),
m_fileInfo(fileName), m_fileInfo(fileName),
m_fileName(fileName), m_fileName(fileName),
@@ -48,11 +47,9 @@ Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *man
m_path(m_fileInfo.path()), m_path(m_fileInfo.path()),
m_lineNumber(lineNumber) m_lineNumber(lineNumber)
{ {
} setLocation(fileName, lineNumber),
setPriority(TextEditor::ITextMark::LowPriority);
QIcon Bookmark::icon() const setIcon(m_manager->bookmarkIcon());
{
return m_manager->bookmarkIcon();
} }
void Bookmark::removedFromEditor() void Bookmark::removedFromEditor()

View File

@@ -54,19 +54,16 @@ class Bookmark : public TextEditor::BaseTextMark
public: public:
Bookmark(const QString &fileName, int lineNumber, BookmarkManager *manager); Bookmark(const QString &fileName, int lineNumber, BookmarkManager *manager);
QIcon icon() const;
void updateLineNumber(int lineNumber); void updateLineNumber(int lineNumber);
void updateBlock(const QTextBlock &block); void updateBlock(const QTextBlock &block);
void removedFromEditor(); void removedFromEditor();
TextEditor::ITextMark::Priority priority() const { return TextEditor::ITextMark::LowPriority; }
QString filePath() const; QString filePath() const;
QString fileName() const; QString fileName() const;
QString path() const; QString path() const;
QString lineText() const; QString lineText() const;
inline int lineNumber() const { return m_lineNumber; } int lineNumber() const { return m_lineNumber; }
private: private:
BookmarkManager *m_manager; BookmarkManager *m_manager;

View File

@@ -49,8 +49,11 @@ namespace Internal {
BreakpointMarker::BreakpointMarker(BreakpointId id, BreakpointMarker::BreakpointMarker(BreakpointId id,
const QString &fileName, int lineNumber) const QString &fileName, int lineNumber)
: BaseTextMark(fileName, lineNumber), m_id(id) : m_id(id)
{ {
setLocation(fileName, lineNumber);
setIcon(breakHandler()->icon(m_id));
setPriority(TextEditor::ITextMark::NormalPriority);
//qDebug() << "CREATE MARKER " << fileName << lineNumber; //qDebug() << "CREATE MARKER " << fileName << lineNumber;
} }
@@ -59,16 +62,6 @@ BreakpointMarker::~BreakpointMarker()
//qDebug() << "REMOVE MARKER "; //qDebug() << "REMOVE MARKER ";
} }
QIcon BreakpointMarker::icon() const
{
return breakHandler()->icon(m_id);
}
void BreakpointMarker::updateBlock(const QTextBlock &)
{
//qDebug() << "BREAKPOINT MARKER UPDATE BLOCK";
}
void BreakpointMarker::removedFromEditor() void BreakpointMarker::removedFromEditor()
{ {
breakHandler()->removeBreakpoint(m_id); breakHandler()->removeBreakpoint(m_id);

View File

@@ -45,14 +45,12 @@ namespace Internal {
class BreakpointMarker : public TextEditor::BaseTextMark class BreakpointMarker : public TextEditor::BaseTextMark
{ {
Q_OBJECT Q_OBJECT
public: public:
BreakpointMarker(BreakpointId id, const QString &fileName, int lineNumber); BreakpointMarker(BreakpointId id, const QString &fileName, int lineNumber);
~BreakpointMarker(); ~BreakpointMarker();
QIcon icon() const;
void updateBlock(const QTextBlock &);
void removedFromEditor(); void removedFromEditor();
void updateLineNumber(int lineNumber); void updateLineNumber(int lineNumber);
TextEditor::ITextMark::Priority priority() const { return TextEditor::ITextMark::NormalPriority; }
private: private:
BreakpointId m_id; BreakpointId m_id;

View File

@@ -125,29 +125,6 @@ QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
} }
///////////////////////////////////////////////////////////////////////
//
// LocationMark
//
///////////////////////////////////////////////////////////////////////
// Used in "real" editors
class LocationMark : public TextEditor::BaseTextMark
{
public:
LocationMark(const QString &fileName, int linenumber)
: BaseTextMark(fileName, linenumber)
{}
QIcon icon() const { return debuggerCore()->locationMarkIcon(); }
void updateLineNumber(int /*lineNumber*/) {}
void updateBlock(const QTextBlock & /*block*/) {}
void removedFromEditor() {}
TextEditor::ITextMark::Priority priority() const { return TextEditor::ITextMark::HighPriority; }
};
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
// DebuggerEnginePrivate // DebuggerEnginePrivate
@@ -587,8 +564,12 @@ void DebuggerEngine::gotoLocation(const Location &loc)
if (texteditor) if (texteditor)
texteditor->gotoLine(line, 0); texteditor->gotoLine(line, 0);
if (loc.needsMarker()) if (loc.needsMarker()) {
d->m_locationMark.reset(new LocationMark(file, line)); d->m_locationMark.reset(new TextEditor::BaseTextMark);
d->m_locationMark->setLocation(file, line);
d->m_locationMark->setIcon(debuggerCore()->locationMarkIcon());
d->m_locationMark->setPriority(TextEditor::ITextMark::HighPriority);
}
// FIXME: Breaks with split views. // FIXME: Breaks with split views.
if (!d->m_memoryAgent.hasVisibleEditor() || loc.needsRaise()) if (!d->m_memoryAgent.hasVisibleEditor() || loc.needsRaise())

View File

@@ -58,6 +58,7 @@
#include <QtCore/QPointer> #include <QtCore/QPointer>
using namespace Core; using namespace Core;
using namespace TextEditor;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -68,38 +69,6 @@ namespace Internal {
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
class LocationMark2 : public TextEditor::ITextMark
{
public:
LocationMark2() {}
QIcon icon() const { return debuggerCore()->locationMarkIcon(); }
void updateLineNumber(int /*lineNumber*/) {}
void updateBlock(const QTextBlock & /*block*/) {}
void removedFromEditor() {}
void documentClosing() {}
TextEditor::ITextMark::Priority priority() const
{ return TextEditor::ITextMark::HighPriority; }
};
class BreakpointMarker2 : public TextEditor::ITextMark
{
public:
BreakpointMarker2(const QIcon &icon) : m_icon(icon) {}
QIcon icon() const { return m_icon; }
void updateLineNumber(int) {}
void updateBlock(const QTextBlock &) {}
void removedFromEditor() {}
void documentClosing() {}
TextEditor::ITextMark::Priority priority() const
{ return TextEditor::ITextMark::NormalPriority; }
private:
QIcon m_icon;
};
class DisassemblerAgentPrivate class DisassemblerAgentPrivate
{ {
public: public:
@@ -112,8 +81,8 @@ public:
Location location; Location location;
bool tryMixed; bool tryMixed;
QPointer<DebuggerEngine> engine; QPointer<DebuggerEngine> engine;
TextEditor::ITextMark *locationMark; ITextMark *locationMark;
QList<TextEditor::ITextMark *> breakpointMarks; QList<ITextMark *> breakpointMarks;
QHash<QString, DisassemblerLines> cache; QHash<QString, DisassemblerLines> cache;
QString mimeType; QString mimeType;
@@ -122,9 +91,11 @@ public:
DisassemblerAgentPrivate::DisassemblerAgentPrivate() DisassemblerAgentPrivate::DisassemblerAgentPrivate()
: editor(0), : editor(0),
tryMixed(true), tryMixed(true),
locationMark(new LocationMark2),
mimeType(_("text/x-qtcreator-generic-asm")) mimeType(_("text/x-qtcreator-generic-asm"))
{ {
locationMark = new ITextMark;
locationMark->setIcon(debuggerCore()->locationMarkIcon());
locationMark->setPriority(TextEditor::ITextMark::HighPriority);
} }
DisassemblerAgentPrivate::~DisassemblerAgentPrivate() DisassemblerAgentPrivate::~DisassemblerAgentPrivate()
@@ -337,7 +308,9 @@ void DisassemblerAgent::updateBreakpointMarkers()
const int lineNumber = contents.lineForAddress(address); const int lineNumber = contents.lineForAddress(address);
if (!lineNumber) if (!lineNumber)
continue; continue;
BreakpointMarker2 *marker = new BreakpointMarker2(handler->icon(id)); ITextMark *marker = new ITextMark;
marker->setIcon(handler->icon(id));
marker->setPriority(ITextMark::NormalPriority);
d->breakpointMarks.append(marker); d->breakpointMarks.append(marker);
d->editor->markableInterface()->addMark(marker, lineNumber); d->editor->markableInterface()->addMark(marker, lineNumber);
} }

View File

@@ -74,20 +74,6 @@ using namespace Core;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class LocationMarkFoo : public TextEditor::ITextMark
{
public:
LocationMarkFoo() {}
QIcon icon() const { return debuggerCore()->locationMarkIcon(); }
void updateLineNumber(int /*lineNumber*/) {}
void updateBlock(const QTextBlock & /*block*/) {}
void removedFromEditor() {}
void documentClosing() {}
TextEditor::ITextMark::Priority priority() const
{ return TextEditor::ITextMark::HighPriority; }
};
class SourceAgentPrivate class SourceAgentPrivate
{ {
public: public:
@@ -104,9 +90,11 @@ public:
SourceAgentPrivate::SourceAgentPrivate() SourceAgentPrivate::SourceAgentPrivate()
: editor(0) : editor(0)
, locationMark(new LocationMarkFoo)
, producer("remote") , producer("remote")
{ {
locationMark = new TextEditor::ITextMark;
locationMark->setIcon(debuggerCore()->locationMarkIcon());
locationMark->setPriority(TextEditor::ITextMark::HighPriority);
} }
SourceAgentPrivate::~SourceAgentPrivate() SourceAgentPrivate::~SourceAgentPrivate()

View File

@@ -3710,10 +3710,9 @@ void BaseTextEditorWidget::extraAreaPaintEvent(QPaintEvent *e)
if (d->m_marksVisible) { if (d->m_marksVisible) {
int xoffset = 0; int xoffset = 0;
foreach (ITextMark *mrk, userData->marks()) { foreach (ITextMark *mrk, userData->marks()) {
int x = 0; const int radius = fmLineSpacing - 1;
int radius = fmLineSpacing - 1; const QRect r(xoffset, top, radius, radius);
QRect r(x + xoffset, top, radius, radius); mrk->paint(&painter, r);
mrk->icon().paint(&painter, r, Qt::AlignCenter);
xoffset += 2; xoffset += 2;
} }
} }

View File

@@ -42,72 +42,34 @@
#include <QtGui/QIcon> #include <QtGui/QIcon>
namespace TextEditor { namespace TextEditor {
namespace Internal {
class InternalMark : public TextEditor::ITextMark BaseTextMark::BaseTextMark()
{ : m_markableInterface(0), m_init(false)
public: {}
explicit InternalMark(BaseTextMark *parent) : m_parent(parent) {}
virtual QIcon icon() const
{
return m_parent->icon();
}
virtual void updateLineNumber(int lineNumber)
{
return m_parent->updateLineNumber(lineNumber);
}
virtual void updateBlock(const QTextBlock &block)
{
return m_parent->updateBlock(block);
}
virtual void removedFromEditor()
{
m_parent->childRemovedFromEditor(this);
}
virtual void documentClosing()
{
m_parent->documentClosingFor(this);
}
virtual Priority priority() const
{
return m_parent->priority();
}
private:
BaseTextMark *m_parent;
};
} // namespace Internal
BaseTextMark::BaseTextMark(const QString &filename, int line)
: 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() BaseTextMark::~BaseTextMark()
{ {
// oha we are deleted // oha we are deleted
if (m_markableInterface) if (m_markableInterface)
m_markableInterface->removeMark(m_internalMark); m_markableInterface->removeMark(this);
removeInternalMark(); removeInternalMark();
} }
void BaseTextMark::setLocation(const QString &fileName, int line)
{
m_fileName = fileName;
m_line = line;
//init();
// This basically mimics 'two phase initialization'
QTimer::singleShot(0, this, SLOT(init()));
}
void BaseTextMark::init() void BaseTextMark::init()
{ {
m_init = true; m_init = true;
Core::EditorManager *em = Core::EditorManager::instance(); Core::EditorManager *em = Core::EditorManager::instance();
connect(em, SIGNAL(editorOpened(Core::IEditor *)), this, SLOT(editorOpened(Core::IEditor *))); connect(em, SIGNAL(editorOpened(Core::IEditor *)),
SLOT(editorOpened(Core::IEditor *)));
foreach (Core::IEditor *editor, em->openedEditors()) foreach (Core::IEditor *editor, em->openedEditors())
editorOpened(editor); editorOpened(editor);
@@ -125,9 +87,7 @@ void BaseTextMark::editorOpened(Core::IEditor *editor)
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) { if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
if (m_markableInterface == 0) { // We aren't added to something if (m_markableInterface == 0) { // We aren't added to something
m_markableInterface = textEditor->markableInterface(); m_markableInterface = textEditor->markableInterface();
m_internalMark = new Internal::InternalMark(this); if (m_markableInterface->addMark(this, m_line)) {
if (m_markableInterface->addMark(m_internalMark, m_line)) {
// Handle reload of text documents, readding the mark as necessary // Handle reload of text documents, readding the mark as necessary
connect(textEditor->file(), SIGNAL(reloaded()), connect(textEditor->file(), SIGNAL(reloaded()),
this, SLOT(documentReloaded()), Qt::UniqueConnection); this, SLOT(documentReloaded()), Qt::UniqueConnection);
@@ -148,56 +108,37 @@ void BaseTextMark::documentReloaded()
return; return;
m_markableInterface = doc->documentMarker(); m_markableInterface = doc->documentMarker();
m_internalMark = new Internal::InternalMark(this);
if (!m_markableInterface->addMark(m_internalMark, m_line)) if (!m_markableInterface->addMark(this, m_line))
removeInternalMark();
}
void BaseTextMark::childRemovedFromEditor(Internal::InternalMark *mark)
{
Q_UNUSED(mark)
// m_internalMark was removed from the editor
removeInternalMark();
removedFromEditor();
}
void BaseTextMark::documentClosingFor(Internal::InternalMark *mark)
{
Q_UNUSED(mark)
removeInternalMark(); removeInternalMark();
} }
void BaseTextMark::removeInternalMark() void BaseTextMark::removeInternalMark()
{ {
delete m_internalMark;
m_internalMark = 0;
m_markableInterface = 0; m_markableInterface = 0;
} }
//#include <QDebug>
void BaseTextMark::updateMarker() void BaseTextMark::updateMarker()
{ {
//qDebug()<<"BaseTextMark::updateMarker()"<<m_markableInterface<<m_internalMark; //qDebug()<<"BaseTextMark::updateMarker()"<<m_markableInterface<<this;
if (m_markableInterface) if (m_markableInterface)
m_markableInterface->updateMark(m_internalMark); m_markableInterface->updateMark(this);
} }
void BaseTextMark::moveMark(const QString & /* filename */, int /* line */) void BaseTextMark::moveMark(const QString & /* filename */, int /* line */)
{ {
Core::EditorManager *em = Core::EditorManager::instance(); Core::EditorManager *em = Core::EditorManager::instance();
if (!m_init) { if (!m_init) {
connect(em, SIGNAL(editorOpened(Core::IEditor *)), this, SLOT(editorOpened(Core::IEditor *))); connect(em, SIGNAL(editorOpened(Core::IEditor *)),
SLOT(editorOpened(Core::IEditor *)));
m_init = true; m_init = true;
} }
if (m_markableInterface) if (m_markableInterface)
m_markableInterface->removeMark(m_internalMark); m_markableInterface->removeMark(this);
// This is only necessary since m_internalMark is created in editorOpened
removeInternalMark();
foreach (Core::IEditor *editor, em->openedEditors()) foreach (Core::IEditor *editor, em->openedEditors())
editorOpened(editor); editorOpened(editor);
} }
} // namespace TextEditor } // namespace TextEditor

View File

@@ -37,63 +37,47 @@
#include "texteditor_global.h" #include "texteditor_global.h"
#include "itexteditor.h" #include "itexteditor.h"
#include <QtCore/QPointer>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QIcon;
class QTextBlock; class QTextBlock;
class QPainter;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace TextEditor { namespace TextEditor {
class ITextMarkable; class ITextMarkable;
namespace Internal { class TEXTEDITOR_EXPORT BaseTextMark : public TextEditor::ITextMark
class InternalMark;
}
class TEXTEDITOR_EXPORT BaseTextMark : public QObject
{ {
friend class Internal::InternalMark;
Q_OBJECT Q_OBJECT
public: public:
explicit BaseTextMark(const QString &filename, int line); BaseTextMark();
virtual ~BaseTextMark(); virtual ~BaseTextMark();
// return your icon here // our location in the "owning" edtitor
virtual QIcon icon() const = 0; virtual void setLocation(const QString &fileName, int lineNumber);
// called if the linenumber changes
virtual void updateLineNumber(int lineNumber) = 0;
// called whenever the text of the block for the marker changed
virtual void updateBlock(const QTextBlock &block) = 0;
// called if the block containing this mark has been removed
// if this also removes your mark call this->deleteLater();
virtual void removedFromEditor() = 0;
// call this if the icon has changed. // call this if the icon has changed.
void updateMarker(); void updateMarker();
// access to internal data // access to internal data
QString fileName() const { return m_fileName; } QString fileName() const { return m_fileName; }
int lineNumber() const { return m_line; } int lineNumber() const { return m_line; }
void moveMark(const QString &filename, int line); void moveMark(const QString &filename, int line);
virtual TextEditor::ITextMark::Priority priority() const = 0;
private slots: private slots:
void init(); void init();
void editorOpened(Core::IEditor *editor); void editorOpened(Core::IEditor *editor);
void documentReloaded(); void documentReloaded();
private: private:
void childRemovedFromEditor(Internal::InternalMark *mark);
void documentClosingFor(Internal::InternalMark *mark);
void removeInternalMark(); void removeInternalMark();
ITextMarkable *m_markableInterface; QPointer<ITextMarkable> m_markableInterface;
Internal::InternalMark *m_internalMark;
QString m_fileName; QString m_fileName;
int m_line; int m_line;
bool m_init; bool m_init;

View File

@@ -39,6 +39,40 @@
using namespace TextEditor; using namespace TextEditor;
void ITextMark::paint(QPainter *painter, const QRect &rect) const
{
m_icon.paint(painter, rect, Qt::AlignCenter);
}
void ITextMark::updateLineNumber(int lineNumber)
{
Q_UNUSED(lineNumber)
}
void ITextMark::updateBlock(const QTextBlock &)
{}
void ITextMark::removedFromEditor()
{}
void ITextMark::documentClosing()
{}
void ITextMark::setIcon(const QIcon &icon)
{
m_icon = icon;
}
void ITextMark::setPriority(Priority priority)
{
m_priority = priority;
}
ITextMark::Priority ITextMark::priority() const
{
return m_priority;
}
QMap<QString, QString> ITextEditor::openedTextEditorsContents() QMap<QString, QString> ITextEditor::openedTextEditorsContents()
{ {
QMap<QString, QString> workingCopy; QMap<QString, QString> workingCopy;

View File

@@ -41,13 +41,15 @@
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QMap> #include <QtCore/QMap>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMenu;
class QTextBlock;
class QIcon; class QIcon;
class QRect; class QMenu;
class QPainter;
class QPoint; class QPoint;
class QRect;
class QTextBlock;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace TextEditor { namespace TextEditor {
@@ -61,13 +63,6 @@ public:
ITextMark(QObject *parent = 0) : QObject(parent) {} ITextMark(QObject *parent = 0) : QObject(parent) {}
virtual ~ITextMark() {} virtual ~ITextMark() {}
virtual QIcon icon() const = 0;
virtual void updateLineNumber(int lineNumber) = 0;
virtual void updateBlock(const QTextBlock &block) = 0;
virtual void removedFromEditor() = 0;
virtual void documentClosing() = 0;
// determine order on markers on the same line. // determine order on markers on the same line.
enum Priority enum Priority
{ {
@@ -76,7 +71,18 @@ public:
HighPriority // shown on top. HighPriority // shown on top.
}; };
virtual Priority priority() const = 0; virtual void paint(QPainter *painter, const QRect &rect) const;
virtual void updateLineNumber(int lineNumber);
virtual void updateBlock(const QTextBlock &block);
virtual void removedFromEditor();
virtual void documentClosing();
virtual void setIcon(const QIcon &icon);
virtual Priority priority() const;
virtual void setPriority(Priority prioriy);
private:
QIcon m_icon;
Priority m_priority;
}; };
typedef QList<ITextMark *> TextMarks; typedef QList<ITextMark *> TextMarks;