Commit a18d0572 authored by hjk's avatar hjk

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()]
parent e73f43c7
......@@ -40,7 +40,6 @@
using namespace Bookmarks::Internal;
Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *manager) :
BaseTextMark(fileName, lineNumber),
m_manager(manager),
m_fileInfo(fileName),
m_fileName(fileName),
......@@ -48,11 +47,9 @@ Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *man
m_path(m_fileInfo.path()),
m_lineNumber(lineNumber)
{
}
QIcon Bookmark::icon() const
{
return m_manager->bookmarkIcon();
setLocation(fileName, lineNumber),
setPriority(TextEditor::ITextMark::LowPriority);
setIcon(m_manager->bookmarkIcon());
}
void Bookmark::removedFromEditor()
......
......@@ -54,19 +54,16 @@ class Bookmark : public TextEditor::BaseTextMark
public:
Bookmark(const QString &fileName, int lineNumber, BookmarkManager *manager);
QIcon icon() const;
void updateLineNumber(int lineNumber);
void updateBlock(const QTextBlock &block);
void removedFromEditor();
TextEditor::ITextMark::Priority priority() const { return TextEditor::ITextMark::LowPriority; }
QString filePath() const;
QString fileName() const;
QString path() const;
QString lineText() const;
inline int lineNumber() const { return m_lineNumber; }
int lineNumber() const { return m_lineNumber; }
private:
BookmarkManager *m_manager;
......
......@@ -49,8 +49,11 @@ namespace Internal {
BreakpointMarker::BreakpointMarker(BreakpointId id,
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;
}
......@@ -59,16 +62,6 @@ BreakpointMarker::~BreakpointMarker()
//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()
{
breakHandler()->removeBreakpoint(m_id);
......
......@@ -45,14 +45,12 @@ namespace Internal {
class BreakpointMarker : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
BreakpointMarker(BreakpointId id, const QString &fileName, int lineNumber);
~BreakpointMarker();
QIcon icon() const;
void updateBlock(const QTextBlock &);
void removedFromEditor();
void updateLineNumber(int lineNumber);
TextEditor::ITextMark::Priority priority() const { return TextEditor::ITextMark::NormalPriority; }
private:
BreakpointId m_id;
......
......@@ -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
......@@ -587,8 +564,12 @@ void DebuggerEngine::gotoLocation(const Location &loc)
if (texteditor)
texteditor->gotoLine(line, 0);
if (loc.needsMarker())
d->m_locationMark.reset(new LocationMark(file, line));
if (loc.needsMarker()) {
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.
if (!d->m_memoryAgent.hasVisibleEditor() || loc.needsRaise())
......
......@@ -58,6 +58,7 @@
#include <QtCore/QPointer>
using namespace Core;
using namespace TextEditor;
namespace Debugger {
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
{
public:
......@@ -112,8 +81,8 @@ public:
Location location;
bool tryMixed;
QPointer<DebuggerEngine> engine;
TextEditor::ITextMark *locationMark;
QList<TextEditor::ITextMark *> breakpointMarks;
ITextMark *locationMark;
QList<ITextMark *> breakpointMarks;
QHash<QString, DisassemblerLines> cache;
QString mimeType;
......@@ -122,9 +91,11 @@ public:
DisassemblerAgentPrivate::DisassemblerAgentPrivate()
: editor(0),
tryMixed(true),
locationMark(new LocationMark2),
mimeType(_("text/x-qtcreator-generic-asm"))
{
locationMark = new ITextMark;
locationMark->setIcon(debuggerCore()->locationMarkIcon());
locationMark->setPriority(TextEditor::ITextMark::HighPriority);
}
DisassemblerAgentPrivate::~DisassemblerAgentPrivate()
......@@ -337,7 +308,9 @@ void DisassemblerAgent::updateBreakpointMarkers()
const int lineNumber = contents.lineForAddress(address);
if (!lineNumber)
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->editor->markableInterface()->addMark(marker, lineNumber);
}
......
......@@ -74,20 +74,6 @@ using namespace Core;
namespace Debugger {
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
{
public:
......@@ -104,9 +90,11 @@ public:
SourceAgentPrivate::SourceAgentPrivate()
: editor(0)
, locationMark(new LocationMarkFoo)
, producer("remote")
{
locationMark = new TextEditor::ITextMark;
locationMark->setIcon(debuggerCore()->locationMarkIcon());
locationMark->setPriority(TextEditor::ITextMark::HighPriority);
}
SourceAgentPrivate::~SourceAgentPrivate()
......
......@@ -3710,10 +3710,9 @@ void BaseTextEditorWidget::extraAreaPaintEvent(QPaintEvent *e)
if (d->m_marksVisible) {
int xoffset = 0;
foreach (ITextMark *mrk, userData->marks()) {
int x = 0;
int radius = fmLineSpacing - 1;
QRect r(x + xoffset, top, radius, radius);
mrk->icon().paint(&painter, r, Qt::AlignCenter);
const int radius = fmLineSpacing - 1;
const QRect r(xoffset, top, radius, radius);
mrk->paint(&painter, r);
xoffset += 2;
}
}
......
......@@ -42,72 +42,34 @@
#include <QtGui/QIcon>
namespace TextEditor {
namespace Internal {
class InternalMark : public TextEditor::ITextMark
{
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()
: m_markableInterface(0), m_init(false)
{}
BaseTextMark::~BaseTextMark()
{
// oha we are deleted
if (m_markableInterface)
m_markableInterface->removeMark(m_internalMark);
m_markableInterface->removeMark(this);
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()
{
m_init = true;
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())
editorOpened(editor);
......@@ -125,9 +87,7 @@ void BaseTextMark::editorOpened(Core::IEditor *editor)
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
if (m_markableInterface == 0) { // We aren't added to something
m_markableInterface = textEditor->markableInterface();
m_internalMark = new Internal::InternalMark(this);
if (m_markableInterface->addMark(m_internalMark, m_line)) {
if (m_markableInterface->addMark(this, m_line)) {
// Handle reload of text documents, readding the mark as necessary
connect(textEditor->file(), SIGNAL(reloaded()),
this, SLOT(documentReloaded()), Qt::UniqueConnection);
......@@ -148,56 +108,37 @@ void BaseTextMark::documentReloaded()
return;
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();
}
void BaseTextMark::removeInternalMark()
{
delete m_internalMark;
m_internalMark = 0;
m_markableInterface = 0;
}
//#include <QDebug>
void BaseTextMark::updateMarker()
{
//qDebug()<<"BaseTextMark::updateMarker()"<<m_markableInterface<<m_internalMark;
//qDebug()<<"BaseTextMark::updateMarker()"<<m_markableInterface<<this;
if (m_markableInterface)
m_markableInterface->updateMark(m_internalMark);
m_markableInterface->updateMark(this);
}
void BaseTextMark::moveMark(const QString & /* filename */, int /* line */)
{
Core::EditorManager *em = Core::EditorManager::instance();
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;
}
if (m_markableInterface)
m_markableInterface->removeMark(m_internalMark);
// This is only necessary since m_internalMark is created in editorOpened
removeInternalMark();
m_markableInterface->removeMark(this);
foreach (Core::IEditor *editor, em->openedEditors())
editorOpened(editor);
}
} // namespace TextEditor
......@@ -37,63 +37,47 @@
#include "texteditor_global.h"
#include "itexteditor.h"
#include <QtCore/QPointer>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE
class QIcon;
class QTextBlock;
class QPainter;
QT_END_NAMESPACE
namespace TextEditor {
class ITextMarkable;
namespace Internal {
class InternalMark;
}
class TEXTEDITOR_EXPORT BaseTextMark : public QObject
class TEXTEDITOR_EXPORT BaseTextMark : public TextEditor::ITextMark
{
friend class Internal::InternalMark;
Q_OBJECT
public:
explicit BaseTextMark(const QString &filename, int line);
BaseTextMark();
virtual ~BaseTextMark();
// return your icon here
virtual QIcon icon() const = 0;
// 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;
// our location in the "owning" edtitor
virtual void setLocation(const QString &fileName, int lineNumber);
// 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.
void updateMarker();
// access to internal data
QString fileName() const { return m_fileName; }
int lineNumber() const { return m_line; }
void moveMark(const QString &filename, int line);
virtual TextEditor::ITextMark::Priority priority() const = 0;
private slots:
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;
QPointer<ITextMarkable> m_markableInterface;
QString m_fileName;
int m_line;
bool m_init;
......
......@@ -39,6 +39,40 @@
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> workingCopy;
......
......@@ -41,13 +41,15 @@
#include <QtCore/QObject>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE
class QMenu;
class QTextBlock;
class QIcon;
class QRect;
class QMenu;
class QPainter;
class QPoint;
class QRect;
class QTextBlock;
QT_END_NAMESPACE
namespace TextEditor {
......@@ -61,13 +63,6 @@ public:
ITextMark(QObject *parent = 0) : QObject(parent) {}
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.
enum Priority
{
......@@ -76,7 +71,18 @@ public:
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;
......
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