forked from qt-creator/qt-creator
TextEditor: Reduce BaseHoverHandler::identifyMatch() calls
...because they are potentially expensive. Change-Id: Iaa235ea1fa864a0a67f3ed10b7f89d23179c642b Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
#include "cppeditordocument.h"
|
#include "cppeditordocument.h"
|
||||||
|
|
||||||
#include <cpptools/cpptoolsreuse.h>
|
#include <cpptools/cpptoolsreuse.h>
|
||||||
|
#include <texteditor/convenience.h>
|
||||||
|
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
@@ -65,23 +66,6 @@ void CppUseSelectionsUpdater::abortSchedule()
|
|||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
static QTextCursor cursorAtWordStart(const QTextCursor &textCursor)
|
|
||||||
{
|
|
||||||
const int originalPosition = textCursor.position();
|
|
||||||
QTextCursor cursor(textCursor);
|
|
||||||
cursor.movePosition(QTextCursor::StartOfWord);
|
|
||||||
const int wordStartPosition = cursor.position();
|
|
||||||
|
|
||||||
if (originalPosition == wordStartPosition) {
|
|
||||||
// Cursor is not on an identifier, check whether we are right after one.
|
|
||||||
const QChar c = textCursor.document()->characterAt(originalPosition - 1);
|
|
||||||
if (CppTools::isValidIdentifierChar(c))
|
|
||||||
cursor.movePosition(QTextCursor::PreviousWord);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppUseSelectionsUpdater::update(CallType callType)
|
void CppUseSelectionsUpdater::update(CallType callType)
|
||||||
{
|
{
|
||||||
auto *cppEditorWidget = qobject_cast<CppEditorWidget *>(m_editorWidget);
|
auto *cppEditorWidget = qobject_cast<CppEditorWidget *>(m_editorWidget);
|
||||||
@@ -92,7 +76,7 @@ void CppUseSelectionsUpdater::update(CallType callType)
|
|||||||
|
|
||||||
CppTools::CursorInfoParams params;
|
CppTools::CursorInfoParams params;
|
||||||
params.semanticInfo = cppEditorWidget->semanticInfo();
|
params.semanticInfo = cppEditorWidget->semanticInfo();
|
||||||
params.textCursor = cursorAtWordStart(cppEditorWidget->textCursor());
|
params.textCursor = TextEditor::Convenience::wordStartCursor(cppEditorWidget->textCursor());
|
||||||
|
|
||||||
if (callType == Asynchronous) {
|
if (callType == Asynchronous) {
|
||||||
if (isSameIdentifierAsBefore(params.textCursor))
|
if (isSameIdentifierAsBefore(params.textCursor))
|
||||||
@@ -150,8 +134,10 @@ void CppUseSelectionsUpdater::onFindUsesFinished()
|
|||||||
return;
|
return;
|
||||||
if (m_runnerRevision != m_editorWidget->document()->revision())
|
if (m_runnerRevision != m_editorWidget->document()->revision())
|
||||||
return;
|
return;
|
||||||
if (m_runnerWordStartPosition != cursorAtWordStart(m_editorWidget->textCursor()).position())
|
if (m_runnerWordStartPosition
|
||||||
|
!= TextEditor::Convenience::wordStartCursor(m_editorWidget->textCursor()).position()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
processResults(m_runnerWatcher->result());
|
processResults(m_runnerWatcher->result());
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ namespace TextEditor {
|
|||||||
BaseHoverHandler::~BaseHoverHandler()
|
BaseHoverHandler::~BaseHoverHandler()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void BaseHoverHandler::showToolTip(TextEditorWidget *widget, const QPoint &point)
|
void BaseHoverHandler::showToolTip(TextEditorWidget *widget, const QPoint &point, bool decorate)
|
||||||
{
|
{
|
||||||
|
if (decorate)
|
||||||
decorateToolTip();
|
decorateToolTip();
|
||||||
operateTooltip(widget, point);
|
operateTooltip(widget, point);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
QString contextHelpId(TextEditorWidget *widget, int pos);
|
QString contextHelpId(TextEditorWidget *widget, int pos);
|
||||||
|
|
||||||
int checkToolTip(TextEditorWidget *widget, int pos);
|
int checkToolTip(TextEditorWidget *widget, int pos);
|
||||||
void showToolTip(TextEditorWidget *widget, const QPoint &point);
|
void showToolTip(TextEditorWidget *widget, const QPoint &point, bool decorate = true);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -86,5 +86,31 @@ QTextCursor flippedCursor(const QTextCursor &cursor)
|
|||||||
return flipped;
|
return flipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isValidIdentifierChar(const QChar &c)
|
||||||
|
{
|
||||||
|
return c.isLetter()
|
||||||
|
|| c.isNumber()
|
||||||
|
|| c == QLatin1Char('_')
|
||||||
|
|| c.isHighSurrogate()
|
||||||
|
|| c.isLowSurrogate();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor wordStartCursor(const QTextCursor &textCursor)
|
||||||
|
{
|
||||||
|
const int originalPosition = textCursor.position();
|
||||||
|
QTextCursor cursor(textCursor);
|
||||||
|
cursor.movePosition(QTextCursor::StartOfWord);
|
||||||
|
const int wordStartPosition = cursor.position();
|
||||||
|
|
||||||
|
if (originalPosition == wordStartPosition) {
|
||||||
|
// Cursor is not on an identifier, check whether we are right after one.
|
||||||
|
const QChar c = textCursor.document()->characterAt(originalPosition - 1);
|
||||||
|
if (isValidIdentifierChar(c))
|
||||||
|
cursor.movePosition(QTextCursor::PreviousWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
} // Util
|
} // Util
|
||||||
} // TextEditor
|
} // TextEditor
|
||||||
|
|||||||
@@ -47,5 +47,7 @@ TEXTEDITOR_EXPORT QTextCursor selectAt(QTextCursor textCursor, uint line, uint c
|
|||||||
|
|
||||||
TEXTEDITOR_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
|
TEXTEDITOR_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
|
||||||
|
|
||||||
|
TEXTEDITOR_EXPORT QTextCursor wordStartCursor(const QTextCursor &cursor);
|
||||||
|
|
||||||
} // Util
|
} // Util
|
||||||
} // TextEditor
|
} // TextEditor
|
||||||
|
|||||||
@@ -468,6 +468,26 @@ public:
|
|||||||
|
|
||||||
CodeAssistant m_codeAssistant;
|
CodeAssistant m_codeAssistant;
|
||||||
bool m_assistRelevantContentAdded = false;
|
bool m_assistRelevantContentAdded = false;
|
||||||
|
|
||||||
|
struct LastHoverHandlerInfo {
|
||||||
|
LastHoverHandlerInfo() = default;
|
||||||
|
LastHoverHandlerInfo(BaseHoverHandler *handler, int documentRevision, int cursorPosition)
|
||||||
|
: handler(handler)
|
||||||
|
, documentRevision(documentRevision)
|
||||||
|
, cursorPosition(cursorPosition)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool applies(int documentRevision, int cursorPosition) const
|
||||||
|
{
|
||||||
|
return handler
|
||||||
|
&& documentRevision == this->documentRevision
|
||||||
|
&& cursorPosition == this->cursorPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseHoverHandler *handler = nullptr;
|
||||||
|
int documentRevision = -1;
|
||||||
|
int cursorPosition = -1;
|
||||||
|
} m_lastHoverHandlerInfo;
|
||||||
QList<BaseHoverHandler *> m_hoverHandlers; // Not owned
|
QList<BaseHoverHandler *> m_hoverHandlers; // Not owned
|
||||||
|
|
||||||
QPointer<QSequentialAnimationGroup> m_navigationAnimation;
|
QPointer<QSequentialAnimationGroup> m_navigationAnimation;
|
||||||
@@ -3161,6 +3181,15 @@ void TextEditorWidgetPrivate::processTooltipRequest(const QTextCursor &c)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does the last handler still applies?
|
||||||
|
const int documentRevision = m_document->document()->revision();
|
||||||
|
const int cursorPosition = Convenience::wordStartCursor(c).position();
|
||||||
|
if (m_lastHoverHandlerInfo.applies(documentRevision, cursorPosition)) {
|
||||||
|
m_lastHoverHandlerInfo.handler->showToolTip(q, toolTipPoint, /*decorate=*/ false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine best handler
|
||||||
int highestPriority = -1;
|
int highestPriority = -1;
|
||||||
BaseHoverHandler *highest = 0;
|
BaseHoverHandler *highest = 0;
|
||||||
foreach (BaseHoverHandler *handler, m_hoverHandlers) {
|
foreach (BaseHoverHandler *handler, m_hoverHandlers) {
|
||||||
@@ -3171,9 +3200,12 @@ void TextEditorWidgetPrivate::processTooltipRequest(const QTextCursor &c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highest)
|
// Let the best handler show the tooltip
|
||||||
|
if (highest) {
|
||||||
|
m_lastHoverHandlerInfo = LastHoverHandlerInfo{highest, documentRevision, cursorPosition};
|
||||||
highest->showToolTip(q, toolTipPoint);
|
highest->showToolTip(q, toolTipPoint);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TextEditorWidgetPrivate::processAnnotaionTooltipRequest(const QTextBlock &block,
|
bool TextEditorWidgetPrivate::processAnnotaionTooltipRequest(const QTextBlock &block,
|
||||||
const QPoint &pos) const
|
const QPoint &pos) const
|
||||||
|
|||||||
Reference in New Issue
Block a user