forked from qt-creator/qt-creator
Editor: reuse generic proposal widget
Do not close already visible proposal widget if we get new results for the same base position. Just replace the model of the widget and update the prefix. Change-Id: I298aba6eb8177edc17fea783189a2f987dbf15a2 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/executeondestruction.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QKeyEvent>
|
||||
@@ -157,7 +158,6 @@ void CodeAssistantPrivate::invoke(AssistKind kind, IAssistProvider *provider)
|
||||
m_proposal->basePosition(),
|
||||
m_editorWidget->position() - m_proposal->basePosition()));
|
||||
} else {
|
||||
destroyContext();
|
||||
requestProposal(ExplicitlyInvoked, kind, provider);
|
||||
}
|
||||
}
|
||||
@@ -166,8 +166,6 @@ bool CodeAssistantPrivate::requestActivationCharProposal()
|
||||
{
|
||||
if (m_assistKind == Completion && m_settings.m_completionTrigger != ManualCompletion) {
|
||||
if (CompletionAssistProvider *provider = identifyActivationSequence()) {
|
||||
if (isWaitingForProposal())
|
||||
cancelCurrentRequest();
|
||||
requestProposal(ActivationCharacter, Completion, provider);
|
||||
return true;
|
||||
}
|
||||
@@ -194,7 +192,10 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
|
||||
AssistKind kind,
|
||||
IAssistProvider *provider)
|
||||
{
|
||||
QTC_ASSERT(!isWaitingForProposal(), return);
|
||||
// make sure to cleanup old proposals if we cannot find a new assistant
|
||||
Utils::ExecuteOnDestruction earlyReturnContextClear([this]() { destroyContext(); });
|
||||
if (isWaitingForProposal())
|
||||
cancelCurrentRequest();
|
||||
|
||||
if (m_editorWidget->hasBlockSelection())
|
||||
return; // TODO
|
||||
@@ -215,6 +216,9 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
|
||||
if (!assistInterface)
|
||||
return;
|
||||
|
||||
// We got an assist provider and interface so no need to reset the current context anymore
|
||||
earlyReturnContextClear.reset({});
|
||||
|
||||
m_assistKind = kind;
|
||||
m_requestProvider = provider;
|
||||
IAssistProcessor *processor = provider->createProcessor();
|
||||
@@ -337,6 +341,15 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_proposalWidget
|
||||
&& basePosition == proposalCandidate->basePosition()
|
||||
&& m_proposalWidget->supportsModelUpdate(proposalCandidate->id())) {
|
||||
m_proposal.reset(proposalCandidate.take());
|
||||
m_proposalWidget->updateModel(m_proposal->model());
|
||||
m_proposalWidget->updateProposal(prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
destroyContext();
|
||||
|
||||
clearAbortedPosition();
|
||||
@@ -471,7 +484,6 @@ void CodeAssistantPrivate::notifyChange()
|
||||
if (!isDisplayingProposal())
|
||||
requestActivationCharProposal();
|
||||
} else {
|
||||
destroyContext();
|
||||
requestProposal(ExplicitlyInvoked, m_assistKind, m_requestProvider);
|
||||
}
|
||||
}
|
||||
|
@@ -27,10 +27,12 @@
|
||||
#include "ifunctionhintproposalmodel.h"
|
||||
#include "functionhintproposalwidget.h"
|
||||
|
||||
static const char functionHintId[] = "TextEditor.FunctionHintId";
|
||||
|
||||
using namespace TextEditor;
|
||||
|
||||
FunctionHintProposal::FunctionHintProposal(int cursorPos, FunctionHintProposalModelPtr model)
|
||||
: IAssistProposal(cursorPos)
|
||||
: IAssistProposal(functionHintId, cursorPos)
|
||||
, m_model(model)
|
||||
{
|
||||
setFragile(true);
|
||||
|
@@ -28,16 +28,17 @@
|
||||
#include "genericproposal.h"
|
||||
#include "genericproposalmodel.h"
|
||||
#include "genericproposalwidget.h"
|
||||
#include "../texteditorconstants.h"
|
||||
|
||||
namespace TextEditor {
|
||||
|
||||
GenericProposal::GenericProposal(int cursorPos, GenericProposalModelPtr model)
|
||||
: IAssistProposal(cursorPos)
|
||||
: IAssistProposal(Constants::GENERIC_PROPOSAL_ID, cursorPos)
|
||||
, m_model(model)
|
||||
{}
|
||||
|
||||
GenericProposal::GenericProposal(int cursorPos, const QList<AssistProposalItemInterface *> &items)
|
||||
: IAssistProposal(cursorPos)
|
||||
: IAssistProposal(Constants::GENERIC_PROPOSAL_ID, cursorPos)
|
||||
, m_model(new GenericProposalModel)
|
||||
{
|
||||
m_model->loadContent(items);
|
||||
@@ -45,7 +46,8 @@ GenericProposal::GenericProposal(int cursorPos, const QList<AssistProposalItemIn
|
||||
|
||||
GenericProposal::~GenericProposal() = default;
|
||||
|
||||
GenericProposal *GenericProposal::createProposal(const AssistInterface *interface, const QuickFixOperations &quickFixes)
|
||||
GenericProposal *GenericProposal::createProposal(const AssistInterface *interface,
|
||||
const QuickFixOperations &quickFixes)
|
||||
{
|
||||
if (quickFixes.isEmpty())
|
||||
return nullptr;
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <QHash>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
using namespace TextEditor;
|
||||
|
||||
@@ -417,3 +418,13 @@ AssistProposalItemInterface *GenericProposalModel::proposalItem(int index) const
|
||||
{
|
||||
return m_currentItems.at(index);
|
||||
}
|
||||
|
||||
int GenericProposalModel::indexOf(
|
||||
const std::function<bool(AssistProposalItemInterface *)> &predicate) const
|
||||
{
|
||||
for (int index = 0, end = m_currentItems.size(); index < end; ++index) {
|
||||
if (predicate(m_currentItems.at(index)))
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@@ -64,6 +64,7 @@ public:
|
||||
virtual QString proposalPrefix() const;
|
||||
virtual bool keepPerfectMatch(AssistReason reason) const;
|
||||
virtual AssistProposalItemInterface *proposalItem(int index) const;
|
||||
virtual int indexOf(const std::function<bool (AssistProposalItemInterface *)> &predicate) const;
|
||||
|
||||
void loadContent(const QList<AssistProposalItemInterface *> &items);
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <texteditor/codeassist/assistproposaliteminterface.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/faketooltip.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/utilsicons.h>
|
||||
@@ -414,6 +415,33 @@ void GenericProposalWidget::setIsSynchronized(bool isSync)
|
||||
d->m_isSynchronized = isSync;
|
||||
}
|
||||
|
||||
bool GenericProposalWidget::supportsModelUpdate(const Utils::Id &proposalId) const
|
||||
{
|
||||
return proposalId == Constants::GENERIC_PROPOSAL_ID;
|
||||
}
|
||||
|
||||
void GenericProposalWidget::updateModel(ProposalModelPtr model)
|
||||
{
|
||||
QString currentText;
|
||||
if (d->m_explicitlySelected)
|
||||
currentText = d->m_model->text(d->m_completionListView->currentIndex().row());
|
||||
d->m_model = model.staticCast<GenericProposalModel>();
|
||||
if (d->m_model->containsDuplicates())
|
||||
d->m_model->removeDuplicates();
|
||||
d->m_completionListView->setModel(new ModelAdapter(d->m_model, d->m_completionListView));
|
||||
connect(d->m_completionListView->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||
&d->m_infoTimer, QOverload<>::of(&QTimer::start));
|
||||
int currentRow = -1;
|
||||
if (!currentText.isEmpty()) {
|
||||
currentRow = d->m_model->indexOf(
|
||||
Utils::equal(&AssistProposalItemInterface::text, currentText));
|
||||
}
|
||||
if (currentRow >= 0)
|
||||
d->m_completionListView->selectRow(currentRow);
|
||||
else
|
||||
d->m_explicitlySelected = false;
|
||||
}
|
||||
|
||||
void GenericProposalWidget::showProposal(const QString &prefix)
|
||||
{
|
||||
ensurePolished();
|
||||
|
@@ -53,6 +53,9 @@ public:
|
||||
void setDisplayRect(const QRect &rect) override;
|
||||
void setIsSynchronized(bool isSync) override;
|
||||
|
||||
bool supportsModelUpdate(const Utils::Id &proposalId) const override;
|
||||
void updateModel(ProposalModelPtr model) override;
|
||||
|
||||
void showProposal(const QString &prefix) override;
|
||||
void updateProposal(const QString &prefix) override;
|
||||
void closeProposal() override;
|
||||
|
@@ -59,8 +59,9 @@ using namespace TextEditor;
|
||||
\sa IAssistProposalWidget, IAssistModel
|
||||
*/
|
||||
|
||||
IAssistProposal::IAssistProposal(int basePosition)
|
||||
: m_basePosition(basePosition)
|
||||
IAssistProposal::IAssistProposal(Utils::Id id, int basePosition)
|
||||
: m_id(id)
|
||||
, m_basePosition(basePosition)
|
||||
{}
|
||||
|
||||
IAssistProposal::~IAssistProposal() = default;
|
||||
|
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <texteditor/texteditor_global.h>
|
||||
|
||||
#include <utils/id.h>
|
||||
|
||||
namespace TextEditor {
|
||||
|
||||
class IAssistProposalWidget;
|
||||
@@ -38,7 +40,7 @@ class TextEditorWidget;
|
||||
class TEXTEDITOR_EXPORT IAssistProposal
|
||||
{
|
||||
public:
|
||||
IAssistProposal(int basePosition);
|
||||
IAssistProposal(Utils::Id id,int basePosition);
|
||||
virtual ~IAssistProposal();
|
||||
|
||||
int basePosition() const;
|
||||
@@ -52,7 +54,11 @@ public:
|
||||
|
||||
void setFragile(bool fragile);
|
||||
void setSupportsPrefix(bool supportsPrefix);
|
||||
|
||||
Utils::Id id() const { return m_id; }
|
||||
|
||||
protected:
|
||||
Utils::Id m_id;
|
||||
int m_basePosition;
|
||||
bool m_isFragile = false;
|
||||
bool m_supportsPrefix = true;
|
||||
|
@@ -32,6 +32,8 @@
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
namespace Utils { class Id; }
|
||||
|
||||
namespace TextEditor {
|
||||
|
||||
class CodeAssistant;
|
||||
@@ -58,6 +60,8 @@ public:
|
||||
virtual void closeProposal() = 0;
|
||||
|
||||
virtual bool proposalIsVisible() const { return isVisible(); }
|
||||
virtual bool supportsModelUpdate(const Utils::Id &/*proposalId*/) const { return false; }
|
||||
virtual void updateModel(ProposalModelPtr) {}
|
||||
|
||||
int basePosition() const;
|
||||
void setBasePosition(int basePosition);
|
||||
|
@@ -236,6 +236,7 @@ const char SNIPPET_EDITOR_ID[] = "TextEditor.SnippetEditor";
|
||||
const char TEXT_SNIPPET_GROUP_ID[] = "Text";
|
||||
|
||||
const char GLOBAL_SETTINGS_ID[] = "Global";
|
||||
const char GENERIC_PROPOSAL_ID[] = "TextEditor.GenericProposalId";
|
||||
|
||||
/**
|
||||
* Delay before tooltip will be shown near completion assistant proposal
|
||||
|
Reference in New Issue
Block a user