Commit beef4807 authored by hjk's avatar hjk

TextEditor: Simplify HoverHandler handling

The editor factories are already a central place to associate
hover handlers with editors, no need to retrieve them later from
the object pool again. This also allows for easy handling of
more than one active handler per editor.

Change-Id: Ie716b96f5ce6b526ee897468635e03e909d81538
Reviewed-by: default avatarDavid Schulz <david.schulz@digia.com>
parent b1cc98f7
......@@ -97,6 +97,8 @@ public:
| TextEditorActionHandler::UnCollapseAll
| TextEditorActionHandler::FollowSymbolUnderCursor);
addHoverHandler(new CppHoverHandler);
if (!Utils::HostOsInfo::isMacHost() && !Utils::HostOsInfo::isWindowsHost()) {
FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_cpp.png", Constants::CPP_SOURCE_MIMETYPE);
FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_c.png", Constants::C_SOURCE_MIMETYPE);
......@@ -153,7 +155,6 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
return false;
addAutoReleasedObject(new CppEditorFactory);
addAutoReleasedObject(new CppHoverHandler);
addAutoReleasedObject(new CppOutlineWidgetFactory);
addAutoReleasedObject(new CppTypeHierarchyFactory);
addAutoReleasedObject(new CppIncludeHierarchyFactory);
......
......@@ -49,14 +49,6 @@ namespace Internal {
CppHoverHandler::CppHoverHandler()
{}
CppHoverHandler::~CppHoverHandler()
{}
bool CppHoverHandler::acceptEditor(IEditor *editor)
{
return editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID;
}
void CppHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos)
{
if (!editorWidget->extraSelectionTooltip(pos).isEmpty()) {
......
......@@ -39,10 +39,8 @@ class CppHoverHandler : public TextEditor::BaseHoverHandler
{
public:
CppHoverHandler();
virtual ~CppHoverHandler();
private:
virtual bool acceptEditor(Core::IEditor *editor);
virtual void identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos);
virtual void decorateToolTip();
};
......
......@@ -31,6 +31,7 @@
#include "glsleditorconstants.h"
#include "glsleditorplugin.h"
#include "glslhighlighter.h"
#include "glslhoverhandler.h"
#include "glslautocompleter.h"
#include "glslcompletionassist.h"
#include "glslindenter.h"
......@@ -347,6 +348,7 @@ GlslEditorFactory::GlslEditorFactory()
| TextEditorActionHandler::UnCommentSelection
| TextEditorActionHandler::UnCollapseAll);
addHoverHandler(new GlslHoverHandler);
}
} // namespace Internal
......
......@@ -33,7 +33,6 @@
#include "glsleditorconstants.h"
#include "glslfilewizard.h"
#include "glslhighlighter.h"
#include "glslhoverhandler.h"
#include <glsl/glslengine.h>
#include <glsl/glslparser.h>
......@@ -128,7 +127,6 @@ bool GlslEditorPlugin::initialize(const QStringList & /*arguments*/, QString *er
if (!MimeDatabase::addMimeTypes(QLatin1String(":/glsleditor/GLSLEditor.mimetypes.xml"), errorMessage))
return false;
addAutoReleasedObject(new GlslHoverHandler(this));
addAutoReleasedObject(new GlslEditorFactory);
addAutoReleasedObject(new GlslCompletionAssistProvider);
......
......@@ -29,30 +29,10 @@
#include "glslhoverhandler.h"
#include "glsleditor.h"
#include "glsleditorconstants.h"
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/helpmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/texteditor.h>
using namespace Core;
namespace GlslEditor {
namespace Internal {
GlslHoverHandler::GlslHoverHandler(QObject *parent) : BaseHoverHandler(parent)
{}
GlslHoverHandler::~GlslHoverHandler()
{}
bool GlslHoverHandler::acceptEditor(IEditor *editor)
{
return editor->context().contains(Constants::C_GLSLEDITOR_ID);
}
void GlslHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos)
{
if (!editorWidget->extraSelectionTooltip(pos).isEmpty())
......
......@@ -32,24 +32,15 @@
#include <texteditor/basehoverhandler.h>
#include <QObject>
namespace Core { class IEditor; }
namespace TextEditor { class BaseTextEditor; }
namespace GlslEditor {
namespace Internal {
class GlslHoverHandler : public TextEditor::BaseHoverHandler
{
Q_OBJECT
public:
GlslHoverHandler(QObject *parent = 0);
virtual ~GlslHoverHandler();
GlslHoverHandler() {}
private:
virtual bool acceptEditor(Core::IEditor *editor);
virtual void identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos);
virtual void decorateToolTip();
};
......
......@@ -31,6 +31,7 @@
#include "profilecompletionassist.h"
#include "profilehighlighter.h"
#include "profilehoverhandler.h"
#include "qmakeprojectmanager.h"
#include "qmakeprojectmanagerconstants.h"
#include "qmakeprojectmanagerconstants.h"
......@@ -215,6 +216,8 @@ ProFileEditorFactory::ProFileEditorFactory()
setEditorActionHandlers(TextEditorActionHandler::UnCommentSelection
| TextEditorActionHandler::JumpToFileUnderCursor);
addHoverHandler(new ProFileHoverHandler);
Core::FileIconProvider::registerIconOverlayForSuffix(QtSupport::Constants::ICON_QT_PROJECT, "pro");
Core::FileIconProvider::registerIconOverlayForSuffix(QtSupport::Constants::ICON_QT_PROJECT, "pri");
Core::FileIconProvider::registerIconOverlayForSuffix(QtSupport::Constants::ICON_QT_PROJECT, "prf");
......
......@@ -53,11 +53,6 @@ ProFileHoverHandler::ProFileHoverHandler()
m_keywords = TextEditor::Keywords(pcap->variables(), pcap->functions(), QMap<QString, QStringList>());
}
bool ProFileHoverHandler::acceptEditor(IEditor *editor)
{
return editor->context().contains(Constants::PROFILE_EDITOR_ID);
}
void ProFileHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos)
{
m_docFragment.clear();
......
......@@ -42,6 +42,7 @@ namespace Internal {
class ProFileHoverHandler : public TextEditor::BaseHoverHandler
{
Q_OBJECT
public:
ProFileHoverHandler();
......@@ -49,8 +50,7 @@ signals:
void creatorHelpRequested(const QUrl &url);
private:
virtual bool acceptEditor(Core::IEditor *editor);
virtual void identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos);
void identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos);
void identifyQMakeKeyword(const QString &text, int pos);
enum ManualKind {
......
......@@ -44,7 +44,6 @@
#include "wizards/subdirsprojectwizard.h"
#include "wizards/qtquickappwizard.h"
#include "customwidgetwizard/customwidgetwizard.h"
#include "profilehoverhandler.h"
#include "qmakeprojectmanagerconstants.h"
#include "qmakeproject.h"
#include "externaleditors.h"
......@@ -111,7 +110,6 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
ProjectExplorer::KitManager::registerKitInformation(new QmakeKitInformation);
addAutoReleasedObject(new ProFileEditorFactory);
addAutoReleasedObject(new EmptyProjectWizard);
addAutoReleasedObject(new SubdirsProjectWizard);
addAutoReleasedObject(new GuiAppWizard);
......@@ -137,7 +135,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
addAutoReleasedObject(new LinguistExternalEditor);
addAutoReleasedObject(new ProFileCompletionAssistProvider);
addAutoReleasedObject(new ProFileHoverHandler);
addAutoReleasedObject(new ProFileEditorFactory);
auto hf = new TextEditor::HighlighterFactory;
hf->setProductType<ProFileHighlighter>();
......
......@@ -35,6 +35,7 @@
#include "qmljseditordocument.h"
#include "qmljseditorplugin.h"
#include "qmljsfindreferences.h"
#include "qmljshoverhandler.h"
#include "qmljsquickfixassist.h"
#include "qmloutlinemodel.h"
......@@ -901,6 +902,8 @@ QmlJSEditorFactory::QmlJSEditorFactory()
setAutoCompleterCreator([]() { return new AutoCompleter; });
setCommentStyle(Utils::CommentDefinition::CppStyle);
addHoverHandler(new QmlJSHoverHandler);
setEditorActionHandlers(TextEditorActionHandler::Format
| TextEditorActionHandler::UnCommentSelection
| TextEditorActionHandler::UnCollapseAll
......
......@@ -32,7 +32,6 @@
#include "qmljseditor.h"
#include "qmljseditorconstants.h"
#include "qmljseditordocument.h"
#include "qmljshoverhandler.h"
#include "qmlfilewizard.h"
#include "jsfilewizard.h"
#include "qmljsoutline.h"
......@@ -224,7 +223,6 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e
m_quickFixAssistProvider = new QmlJSQuickFixAssistProvider;
addAutoReleasedObject(m_quickFixAssistProvider);
addAutoReleasedObject(new QmlJSCompletionAssistProvider);
addAutoReleasedObject(new QmlJSHoverHandler);
errorMessage->clear();
......
......@@ -92,16 +92,11 @@ namespace {
}
}
QmlJSHoverHandler::QmlJSHoverHandler(QObject *parent) : BaseHoverHandler(parent), m_modelManager(0)
QmlJSHoverHandler::QmlJSHoverHandler() : m_modelManager(0)
{
m_modelManager = QmlJS::ModelManagerInterface::instance();
}
bool QmlJSHoverHandler::acceptEditor(IEditor *editor)
{
return editor->context().contains(Constants::C_QMLJSEDITOR_ID);
}
static inline QString getModuleName(const ScopeChain &scopeChain, const Document::Ptr &qmlDocument,
const ObjectValue *value)
{
......
......@@ -39,10 +39,6 @@ QT_BEGIN_NAMESPACE
template <class> class QList;
QT_END_NAMESPACE
namespace Core { class IEditor; }
namespace TextEditor { class BaseTextEditor; }
namespace QmlJS {
class ScopeChain;
class Context;
......@@ -59,13 +55,13 @@ class QmlJSEditorWidget;
class QmlJSHoverHandler : public TextEditor::BaseHoverHandler
{
Q_OBJECT
public:
QmlJSHoverHandler(QObject *parent = 0);
QmlJSHoverHandler();
private:
void reset();
bool acceptEditor(Core::IEditor *editor);
void identifyMatch(TextEditor::TextEditorWidget *editorWidget, int pos);
void operateTooltip(TextEditor::TextEditorWidget *editorWidget, const QPoint &point);
......
......@@ -40,51 +40,31 @@ using namespace Core;
namespace TextEditor {
BaseHoverHandler::BaseHoverHandler(QObject *parent) : QObject(parent), m_diagnosticTooltip(false)
BaseHoverHandler::BaseHoverHandler() : m_diagnosticTooltip(false)
{
// Listen for editor opened events in order to connect to tooltip/helpid requests
connect(EditorManager::instance(), &EditorManager::editorOpened,
this, &BaseHoverHandler::editorOpened);
}
BaseHoverHandler::~BaseHoverHandler()
{}
void BaseHoverHandler::editorOpened(Core::IEditor *editor)
void BaseHoverHandler::showToolTip(TextEditorWidget *widget, const QPoint &point, int pos)
{
if (acceptEditor(editor)) {
BaseTextEditor *textEditor = qobject_cast<BaseTextEditor *>(editor);
if (textEditor) {
connect(textEditor, &BaseTextEditor::tooltipRequested,
this, &BaseHoverHandler::showToolTip);
connect(textEditor, &BaseTextEditor::contextHelpIdRequested,
this, &BaseHoverHandler::updateContextHelpId);
}
}
}
widget->setContextHelpId(QString());
void BaseHoverHandler::showToolTip(BaseTextEditor *editor, const QPoint &point, int pos)
{
TextEditorWidget *editorWidget = editor->editorWidget();
editor->setContextHelpId(QString());
process(editor, pos);
operateTooltip(editorWidget, point);
process(widget, pos);
operateTooltip(widget, point);
}
void BaseHoverHandler::updateContextHelpId(BaseTextEditor *editor, int pos)
QString BaseHoverHandler::contextHelpId(TextEditorWidget *widget, int pos)
{
// If the tooltip is visible and there is a help match, this match is used to update
// the help id. Otherwise, let the identification process happen.
if (!Utils::ToolTip::isVisible() || !lastHelpItemIdentified().isValid())
process(editor, pos);
process(widget, pos);
if (lastHelpItemIdentified().isValid())
editor->setContextHelpId(lastHelpItemIdentified().helpId());
else
editor->setContextHelpId(QString()); // Make sure it's an empty string.
return lastHelpItemIdentified().helpId();
return QString();
}
void BaseHoverHandler::setToolTip(const QString &tooltip)
......@@ -136,10 +116,10 @@ void BaseHoverHandler::clear()
m_lastHelpItemIdentified = HelpItem();
}
void BaseHoverHandler::process(BaseTextEditor *editor, int pos)
void BaseHoverHandler::process(TextEditorWidget *widget, int pos)
{
clear();
identifyMatch(editor->editorWidget(), pos);
identifyMatch(widget, pos);
decorateToolTip();
}
......
......@@ -46,9 +46,12 @@ class TEXTEDITOR_EXPORT BaseHoverHandler : public QObject
Q_OBJECT
public:
BaseHoverHandler(QObject *parent = 0);
BaseHoverHandler();
~BaseHoverHandler();
QString contextHelpId(TextEditorWidget *widget, int pos);
void showToolTip(TextEditorWidget *widget, const QPoint &point, int pos);
protected:
void setToolTip(const QString &tooltip);
void appendToolTip(const QString &extension);
......@@ -63,14 +66,9 @@ protected:
const HelpItem &lastHelpItemIdentified() const;
private:
void editorOpened(Core::IEditor *editor);
void showToolTip(BaseTextEditor *editor, const QPoint &point, int pos);
void updateContextHelpId(BaseTextEditor *editor, int pos);
void clear();
void process(BaseTextEditor *editor, int pos);
void process(TextEditorWidget *widget, int pos);
virtual bool acceptEditor(Core::IEditor *editor) = 0;
virtual void identifyMatch(TextEditorWidget *editorWidget, int pos) = 0;
virtual void decorateToolTip();
virtual void operateTooltip(TextEditorWidget *editorWidget, const QPoint &point);
......
......@@ -31,6 +31,7 @@
#include "texteditor_p.h"
#include "autocompleter.h"
#include "basehoverhandler.h"
#include "behaviorsettings.h"
#include "circularclipboard.h"
#include "circularclipboardassist.h"
......@@ -355,6 +356,7 @@ public:
void snippetTabOrBacktab(bool forward);
RefactorOverlay *m_refactorOverlay;
QString m_contextHelpId;
QBasicTimer foldedBlockTimer;
int visibleFoldedBlockNumber;
......@@ -420,6 +422,7 @@ public:
CodeAssistant m_codeAssistant;
bool m_assistRelevantContentAdded;
QList<BaseHoverHandler *> m_hoverHandlers; // Not owned
QPointer<TextEditorAnimator> m_animator;
int m_cursorBlockNumber;
......@@ -2965,8 +2968,13 @@ void TextEditorWidgetPrivate::processTooltipRequest(const QTextCursor &c)
const QPoint toolTipPoint = q->toolTipPosition(c);
bool handled = false;
emit q->tooltipOverrideRequested(q, toolTipPoint, c.position(), &handled);
if (!handled)
emit q->tooltipRequested(toolTipPoint, c.position());
if (handled)
return;
if (!m_hoverHandlers.isEmpty()) {
m_hoverHandlers.first()->showToolTip(q, toolTipPoint, c.position());
return;
}
emit q->tooltipRequested(toolTipPoint, c.position());
}
bool TextEditorWidget::viewportEvent(QEvent *event)
......@@ -6737,7 +6745,7 @@ void TextEditorWidgetPrivate::updateCursorPosition()
.arg(q->textDocument()->tabSettings().columnAt(block.text(),
column)+1),
tr("Line: 9999, Col: 999"));
q->clearContentsHelpId();
m_contextHelpId.clear();
if (!block.isVisible())
q->ensureCursorVisible();
......@@ -6745,10 +6753,25 @@ void TextEditorWidgetPrivate::updateCursorPosition()
QString BaseTextEditor::contextHelpId() const
{
if (m_contextHelpId.isEmpty())
emit const_cast<BaseTextEditor*>(this)->contextHelpIdRequested(const_cast<BaseTextEditor*>(this),
editorWidget()->textCursor().position());
return m_contextHelpId;
return editorWidget()->contextHelpId();
}
void BaseTextEditor::setContextHelpId(const QString &id)
{
IEditor::setContextHelpId(id);
editorWidget()->setContextHelpId(id);
}
QString TextEditorWidget::contextHelpId()
{
if (d->m_contextHelpId.isEmpty() && !d->m_hoverHandlers.isEmpty())
d->m_contextHelpId = d->m_hoverHandlers.first()->contextHelpId(this, textCursor().position());
return d->m_contextHelpId;
}
void TextEditorWidget::setContextHelpId(const QString &id)
{
d->m_contextHelpId = id;
}
RefactorMarkers TextEditorWidget::refactorMarkers() const
......@@ -7209,6 +7232,11 @@ TextEditorFactory::TextEditorFactory(QObject *parent)
m_duplicatedSupported = true;
}
TextEditorFactory::~TextEditorFactory()
{
qDeleteAll(m_hoverHandlers);
}
void TextEditorFactory::setDocumentCreator(const DocumentCreator &creator)
{
m_documentCreator = creator;
......@@ -7258,6 +7286,11 @@ void TextEditorFactory::setEditorActionHandlers(uint optionalActions)
new TextEditorActionHandler(this, id(), optionalActions);
}
void TextEditorFactory::addHoverHandler(BaseHoverHandler *handler)
{
m_hoverHandlers.append(handler);
}
void TextEditorFactory::setCommentStyle(CommentDefinition::Style style)
{
m_commentStyle = style;
......@@ -7306,6 +7339,7 @@ BaseTextEditor *TextEditorFactory::createEditorHelper(const TextDocumentPtr &doc
widget->setAutoCompleter(m_autoCompleterCreator());
widget->setTextDocument(document);
widget->d->m_hoverHandlers = m_hoverHandlers;
widget->d->m_codeAssistant.configure(widget);
widget->d->m_commentDefinition.setStyle(m_commentStyle);
......@@ -7320,11 +7354,6 @@ BaseTextEditor *TextEditorFactory::createEditorHelper(const TextDocumentPtr &doc
editor->markContextMenuRequested(editor, line, menu);
});
connect(widget, &TextEditorWidget::tooltipRequested, editor,
[editor](const QPoint &globalPos, int position) {
editor->tooltipRequested(editor, globalPos, position);
});
connect(widget, &TextEditorWidget::markTooltipRequested, editor,
[editor](const QPoint &globalPos, int line) {
editor->markTooltipRequested(editor, globalPos, line);
......@@ -7333,9 +7362,6 @@ BaseTextEditor *TextEditorFactory::createEditorHelper(const TextDocumentPtr &doc
connect(widget, &TextEditorWidget::activateEditor,
[editor]() { Core::EditorManager::activateEditor(editor); });
connect(widget, &TextEditorWidget::clearContentsHelpId,
[editor]() { editor->setContextHelpId(QString()); });
widget->finalizeInitialization();
editor->finalizeInitialization();
......
......@@ -61,6 +61,7 @@ namespace Core { class MimeType; }
namespace TextEditor {
class BaseHoverHandler;
class TabSettings;
class RefactorOverlay;
struct RefactorMarker;
......@@ -160,6 +161,7 @@ public:
QWidget *toolBar();
QString contextHelpId() const; // from IContext
void setContextHelpId(const QString &id);
int currentLine() const;
int currentColumn() const;
......@@ -196,9 +198,7 @@ public:
signals:
void markRequested(TextEditor::BaseTextEditor *editor, int line, TextEditor::BaseTextEditor::MarkRequestKind kind);
void markContextMenuRequested(TextEditor::BaseTextEditor *editor, int line, QMenu *menu);
void tooltipRequested(TextEditor::BaseTextEditor *editor, const QPoint &globalPos, int position);
void markTooltipRequested(TextEditor::BaseTextEditor *editor, const QPoint &globalPos, int line);
void contextHelpIdRequested(TextEditor::BaseTextEditor *editor, int position);
private:
friend class TextEditorFactory;
......@@ -569,6 +569,9 @@ public:
QChar characterAt(int pos) const;
QString textAt(int from, int to) const;
QString contextHelpId();
void setContextHelpId(const QString &id);
protected:
/*!
Reimplement this function to enable code navigation.
......@@ -603,7 +606,6 @@ signals:
void tooltipRequested(const QPoint &globalPos, int position);
void markTooltipRequested(const QPoint &globalPos, int line);
void activateEditor();
void clearContentsHelpId();
protected slots:
virtual void slotCursorPositionChanged(); // Used in VcsBase
......@@ -626,6 +628,7 @@ class TEXTEDITOR_EXPORT TextEditorFactory : public Core::IEditorFactory
public:
TextEditorFactory(QObject *parent = 0);
~TextEditorFactory();
typedef std::function<BaseTextEditor *()> EditorCreator;
typedef std::function<TextDocument *()> DocumentCreator;
......@@ -645,6 +648,8 @@ public:
void setEditorActionHandlers(Core::Id contextId, uint optionalActions);
void setEditorActionHandlers(uint optionalActions);
void addHoverHandler(BaseHoverHandler *handler);
void setCommentStyle(Utils::CommentDefinition::Style style);
void setDuplicatedSupported(bool on);
......@@ -664,6 +669,7 @@ private:
IndenterCreator m_indenterCreator;
SyntaxHighLighterCreator m_syntaxHighlighterCreator;
Utils::CommentDefinition::Style m_commentStyle;
QList<BaseHoverHandler *> m_hoverHandlers; // owned
bool m_duplicatedSupported;
};
......
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