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 <cpptools/cpptoolsreuse.h>
|
||||
#include <texteditor/convenience.h>
|
||||
|
||||
#include <QTextBlock>
|
||||
#include <QTextCursor>
|
||||
@@ -65,23 +66,6 @@ void CppUseSelectionsUpdater::abortSchedule()
|
||||
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)
|
||||
{
|
||||
auto *cppEditorWidget = qobject_cast<CppEditorWidget *>(m_editorWidget);
|
||||
@@ -92,7 +76,7 @@ void CppUseSelectionsUpdater::update(CallType callType)
|
||||
|
||||
CppTools::CursorInfoParams params;
|
||||
params.semanticInfo = cppEditorWidget->semanticInfo();
|
||||
params.textCursor = cursorAtWordStart(cppEditorWidget->textCursor());
|
||||
params.textCursor = TextEditor::Convenience::wordStartCursor(cppEditorWidget->textCursor());
|
||||
|
||||
if (callType == Asynchronous) {
|
||||
if (isSameIdentifierAsBefore(params.textCursor))
|
||||
@@ -150,8 +134,10 @@ void CppUseSelectionsUpdater::onFindUsesFinished()
|
||||
return;
|
||||
if (m_runnerRevision != m_editorWidget->document()->revision())
|
||||
return;
|
||||
if (m_runnerWordStartPosition != cursorAtWordStart(m_editorWidget->textCursor()).position())
|
||||
if (m_runnerWordStartPosition
|
||||
!= TextEditor::Convenience::wordStartCursor(m_editorWidget->textCursor()).position()) {
|
||||
return;
|
||||
}
|
||||
|
||||
processResults(m_runnerWatcher->result());
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ namespace TextEditor {
|
||||
BaseHoverHandler::~BaseHoverHandler()
|
||||
{}
|
||||
|
||||
void BaseHoverHandler::showToolTip(TextEditorWidget *widget, const QPoint &point)
|
||||
void BaseHoverHandler::showToolTip(TextEditorWidget *widget, const QPoint &point, bool decorate)
|
||||
{
|
||||
decorateToolTip();
|
||||
if (decorate)
|
||||
decorateToolTip();
|
||||
operateTooltip(widget, point);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
QString contextHelpId(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:
|
||||
enum {
|
||||
|
||||
@@ -86,5 +86,31 @@ QTextCursor flippedCursor(const QTextCursor &cursor)
|
||||
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
|
||||
} // 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 wordStartCursor(const QTextCursor &cursor);
|
||||
|
||||
} // Util
|
||||
} // TextEditor
|
||||
|
||||
@@ -468,6 +468,26 @@ public:
|
||||
|
||||
CodeAssistant m_codeAssistant;
|
||||
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
|
||||
|
||||
QPointer<QSequentialAnimationGroup> m_navigationAnimation;
|
||||
@@ -3161,6 +3181,15 @@ void TextEditorWidgetPrivate::processTooltipRequest(const QTextCursor &c)
|
||||
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;
|
||||
BaseHoverHandler *highest = 0;
|
||||
foreach (BaseHoverHandler *handler, m_hoverHandlers) {
|
||||
@@ -3171,8 +3200,11 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
bool TextEditorWidgetPrivate::processAnnotaionTooltipRequest(const QTextBlock &block,
|
||||
|
||||
Reference in New Issue
Block a user