Commit b267027c authored by Daniel Teske's avatar Daniel Teske

Optimize BaseTextMark

Instead of each BaseTextMark being a QObject and being connected
to editorOpened, centralize that and distribute the signal
to only the BaseTextMarks that need it.

Change-Id: I3f2783c34a25d78aa335418236850436028bfdf3
Reviewed-by: default avatarEike Ziller <eike.ziller@nokia.com>
parent cf4c1315
......@@ -39,6 +39,7 @@
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),
......@@ -46,7 +47,6 @@ Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *man
m_path(m_fileInfo.path()),
m_lineNumber(lineNumber)
{
setLocation(fileName, lineNumber),
setPriority(TextEditor::ITextMark::LowPriority);
setIcon(m_manager->bookmarkIcon());
}
......
......@@ -49,7 +49,6 @@ class BookmarkManager;
class Bookmark : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
Bookmark(const QString &fileName, int lineNumber, BookmarkManager *manager);
......
......@@ -48,9 +48,8 @@ namespace Internal {
BreakpointMarker::BreakpointMarker(BreakpointModelId id,
const QString &fileName, int lineNumber)
: m_id(id)
: BaseTextMark(fileName, lineNumber), m_id(id)
{
setLocation(fileName, lineNumber);
setIcon(breakHandler()->icon(m_id));
setPriority(TextEditor::ITextMark::NormalPriority);
//qDebug() << "CREATE MARKER " << fileName << lineNumber;
......
......@@ -43,8 +43,6 @@ namespace Internal {
// The red blob on the left side in the cpp editor.
class BreakpointMarker : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
BreakpointMarker(BreakpointModelId id, const QString &fileName, int lineNumber);
~BreakpointMarker();
......
......@@ -621,8 +621,7 @@ void DebuggerEngine::gotoLocation(const Location &loc)
texteditor->gotoLine(line, 0);
if (loc.needsMarker()) {
d->m_locationMark.reset(new TextEditor::BaseTextMark);
d->m_locationMark->setLocation(file, line);
d->m_locationMark.reset(new TextEditor::BaseTextMark(file, line));
d->m_locationMark->setIcon(debuggerCore()->locationMarkIcon());
d->m_locationMark->setPriority(TextEditor::ITextMark::HighPriority);
}
......
......@@ -41,8 +41,8 @@ using namespace ProjectExplorer;
class TaskMark : public TextEditor::BaseTextMark
{
public:
TaskMark(unsigned int id)
: m_id(id)
TaskMark(unsigned int id, const QString &fileName, int lineNumber)
: BaseTextMark(fileName, lineNumber), m_id(id)
{}
void updateLineNumber(int lineNumber);
......@@ -82,13 +82,11 @@ void TaskHub::addCategory(const Core::Id &categoryId, const QString &displayName
void TaskHub::addTask(Task task)
{
if (task.line != -1 && !task.file.isEmpty()) {
TaskMark *mark = new TaskMark(task.taskId);
TaskMark *mark = new TaskMark(task.taskId, task.file.toString(), task.line);
mark->setIcon(taskTypeIcon(task.type));
mark->setLocation(task.file.toString(), task.line);
mark->setPriority(TextEditor::ITextMark::HighPriority);
task.addMark(mark);
}
emit taskAdded(task);
}
......
......@@ -33,94 +33,97 @@
#include "basetextmark.h"
#include "itexteditor.h"
#include "basetextdocument.h"
#include "texteditorplugin.h"
#include <coreplugin/editormanager/editormanager.h>
#include <extensionsystem/pluginmanager.h>
#include <QtCore/QTimer>
#include <QtGui/QIcon>
using namespace TextEditor;
using namespace TextEditor::Internal;
namespace TextEditor {
BaseTextMark::BaseTextMark()
: m_markableInterface(0)
{}
BaseTextMark::~BaseTextMark()
{
// oha we are deleted
if (m_markableInterface)
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()
BaseTextMarkRegistry::BaseTextMarkRegistry(QObject *parent)
: QObject(parent)
{
Core::EditorManager *em = Core::EditorManager::instance();
connect(em, SIGNAL(editorOpened(Core::IEditor *)),
SLOT(editorOpened(Core::IEditor *)));
foreach (Core::IEditor *editor, em->openedEditors())
editorOpened(editor);
}
void BaseTextMark::editorOpened(Core::IEditor *editor)
void BaseTextMarkRegistry::add(BaseTextMark *mark)
{
#ifdef Q_OS_WIN
if (m_fileName.compare(editor->file()->fileName(), Qt::CaseInsensitive))
return;
#else
if (editor->file()->fileName() != m_fileName)
return;
#endif
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
if (m_markableInterface == 0) { // We aren't added to something
m_markableInterface = textEditor->markableInterface();
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);
} else {
removeInternalMark();
m_marks[Utils::FileName::fromString(mark->fileName())].append(mark);
Core::EditorManager *em = Core::EditorManager::instance();
foreach (Core::IEditor *editor, em->editorsForFileName(mark->fileName())) {
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
if (mark->m_markableInterface == 0) { // We aren't added to something
ITextMarkable *markableInterface = textEditor->markableInterface();
if (markableInterface->addMark(mark, mark->m_line)) {
mark->m_markableInterface = markableInterface;
// Handle reload of text documents, readding the mark as necessary
connect(textEditor->file(), SIGNAL(reloaded()),
this, SLOT(documentReloaded()), Qt::UniqueConnection);
break;
}
}
}
}
}
void BaseTextMark::documentReloaded()
void BaseTextMarkRegistry::editorOpened(Core::IEditor *editor)
{
if (m_markableInterface)
ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
if (!textEditor)
return;
if (!m_marks.contains(Utils::FileName::fromString(editor->file()->fileName())))
return;
// Handle reload of text documents, readding the mark as necessary
connect(textEditor->file(), SIGNAL(reloaded()),
this, SLOT(documentReloaded()), Qt::UniqueConnection);
foreach (BaseTextMark *mark, m_marks.value(Utils::FileName::fromString(editor->file()->fileName()))) {
if (mark->m_markableInterface == 0) { // We aren't added to something
ITextMarkable *markableInterface = textEditor->markableInterface();
if (markableInterface->addMark(mark, mark->m_line))
mark->m_markableInterface = markableInterface;
}
}
}
void BaseTextMarkRegistry::documentReloaded()
{
BaseTextDocument *doc = qobject_cast<BaseTextDocument*>(sender());
if (!doc)
return;
m_markableInterface = doc->documentMarker();
if (!m_marks.contains(Utils::FileName::fromString(doc->fileName())))
return;
foreach (BaseTextMark *mark, m_marks.value(Utils::FileName::fromString(doc->fileName()))) {
if (mark->m_markableInterface)
return;
ITextMarkable *markableInterface = doc->documentMarker();
if (markableInterface->addMark(mark, mark->m_line))
mark->m_markableInterface = markableInterface;
}
}
if (!m_markableInterface->addMark(this, m_line))
removeInternalMark();
BaseTextMark::BaseTextMark(const QString &fileName, int lineNumber)
: m_fileName(fileName), m_line(lineNumber)
{
Internal::TextEditorPlugin::instance()->baseTextMarkRegistry()->add(this);
}
void BaseTextMark::removeInternalMark()
BaseTextMark::~BaseTextMark()
{
m_markableInterface = 0;
// oha we are deleted
if (m_markableInterface)
m_markableInterface.data()->removeMark(this);
m_markableInterface.clear();
}
void BaseTextMark::updateMarker()
{
//qDebug()<<"BaseTextMark::updateMarker()"<<m_markableInterface<<this;
if (m_markableInterface)
m_markableInterface->updateMark(this);
m_markableInterface.data()->updateMark(this);
}
} // namespace TextEditor
......@@ -36,7 +36,10 @@
#include "texteditor_global.h"
#include "itexteditor.h"
#include <QtCore/QPointer>
#include <utils/fileutils.h>
#include <QtCore/QWeakPointer>
#include <QtCore/QHash>
QT_BEGIN_NAMESPACE
class QTextBlock;
......@@ -44,20 +47,20 @@ class QPainter;
QT_END_NAMESPACE
namespace TextEditor {
namespace Internal {
class BaseTextMarkRegistry;
}
class ITextMarkable;
class TEXTEDITOR_EXPORT BaseTextMark : public TextEditor::ITextMark
{
Q_OBJECT
friend class Internal::BaseTextMarkRegistry;
public:
BaseTextMark();
BaseTextMark(const QString &fileName, int lineNumber);
virtual ~BaseTextMark();
// our location in the "owning" edtitor
void setLocation(const QString &fileName, int lineNumber);
// call this if the icon has changed.
void updateMarker();
......@@ -65,18 +68,27 @@ public:
QString fileName() const { return m_fileName; }
int lineNumber() const { return m_line; }
private:
QWeakPointer<ITextMarkable> m_markableInterface;
QString m_fileName;
int m_line;
};
namespace Internal {
class BaseTextMarkRegistry : public QObject
{
Q_OBJECT
public:
BaseTextMarkRegistry(QObject *parent);
void add(BaseTextMark *mark);
private slots:
void init();
void editorOpened(Core::IEditor *editor);
void documentReloaded();
private:
void removeInternalMark();
QPointer<ITextMarkable> m_markableInterface;
QString m_fileName;
int m_line;
QHash<Utils::FileName, QList<BaseTextMark *> > m_marks;
};
}
} // namespace TextEditor
......
......@@ -38,6 +38,11 @@
using namespace TextEditor;
ITextMark::~ITextMark()
{
}
void ITextMark::paint(QPainter *painter, const QRect &rect) const
{
m_icon.paint(painter, rect, Qt::AlignCenter);
......
......@@ -55,11 +55,11 @@ namespace TextEditor {
class ITextEditor;
class TEXTEDITOR_EXPORT ITextMark : public QObject
class TEXTEDITOR_EXPORT ITextMark
{
Q_OBJECT
public:
ITextMark() : m_priority(NormalPriority) {}
virtual ~ITextMark();
// determine order on markers on the same line.
enum Priority
......
......@@ -46,6 +46,7 @@
#include "outlinefactory.h"
#include "snippets/plaintextsnippetprovider.h"
#include "codeassist/assistenums.h"
#include "basetextmark.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
......@@ -168,6 +169,8 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
// registered in the action manager at plugin initialization time.
m_editorFactory->actionHandler()->initializeActions();
m_baseTextMarkRegistry = new BaseTextMarkRegistry(this);
return true;
}
......
......@@ -50,6 +50,7 @@ namespace Internal {
class LineNumberFilter;
class PlainTextEditorFactory;
class OutlineFactory;
class BaseTextMarkRegistry;
class TextEditorPlugin : public ExtensionSystem::IPlugin
{
......@@ -69,6 +70,7 @@ public:
PlainTextEditorFactory *editorFactory() { return m_editorFactory; }
LineNumberFilter *lineNumberFilter() { return m_lineNumberFilter; }
BaseTextMarkRegistry *baseTextMarkRegistry() { return m_baseTextMarkRegistry; }
private slots:
void invokeCompletion();
......@@ -84,6 +86,7 @@ private:
LineNumberFilter *m_lineNumberFilter;
Find::SearchResultWindow *m_searchResultWindow;
OutlineFactory *m_outlineFactory;
BaseTextMarkRegistry *m_baseTextMarkRegistry;
};
} // namespace Internal
......
......@@ -47,9 +47,8 @@ using namespace Valgrind::Callgrind;
CallgrindTextMark::CallgrindTextMark(const QPersistentModelIndex &index,
const QString &fileName, int lineNumber)
: m_modelIndex(index)
: TextEditor::BaseTextMark(fileName, lineNumber), m_modelIndex(index)
{
setLocation(fileName, lineNumber);
setPriority(TextEditor::ITextMark::HighPriority);
}
......
......@@ -47,8 +47,6 @@ namespace Internal {
class CallgrindTextMark : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
/**
* This creates a callgrind text mark for a specific Function
......
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