Gui: Differentiate completion activation modes in Expression Editor
Currently if user tries to press TAB during Expression Editor, it inserts both the entry and its first subentry. Also, if user browses the dropdown with arrows keys, it inserts it's values. Root cause of that is the regression made in latest changes to chaining completion logic which is triggered for all completion modes including TAB, which already has its own refresh mechanism. Also, ExpressionTextEdit connected both activated (Enter/click) and highlight signals to the same slot, resulting in arrow key navigation inserting completions. So, this adds separate slots for ExpressionTextEdit to differentiate completion modes. And also updates tab handling to pass ActivationMode::Highlighted to prevent double chaining.
This commit is contained in:
@@ -1013,7 +1013,7 @@ void ExpressionLineEdit::slotTextChanged(const QString& text)
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionLineEdit::slotCompleteText(const QString& completionPrefix, bool isActivated)
|
||||
void ExpressionLineEdit::slotCompleteText(const QString& completionPrefix, ActivationMode mode)
|
||||
{
|
||||
int start, end;
|
||||
completer->getPrefixRange(start, end);
|
||||
@@ -1030,7 +1030,7 @@ void ExpressionLineEdit::slotCompleteText(const QString& completionPrefix, bool
|
||||
|
||||
// chain completions if we select an entry from the completer drop down
|
||||
// and that entry ends with '.' or '#'
|
||||
if (isActivated) {
|
||||
if (mode == ActivationMode::Activated) {
|
||||
std::string textToComplete = completionPrefix.toUtf8().constData();
|
||||
if (textToComplete.size()
|
||||
&& (*textToComplete.crbegin() == '.' || *textToComplete.crbegin() == '#')) {
|
||||
@@ -1042,12 +1042,12 @@ void ExpressionLineEdit::slotCompleteText(const QString& completionPrefix, bool
|
||||
|
||||
void ExpressionLineEdit::slotCompleteTextHighlighted(const QString& completionPrefix)
|
||||
{
|
||||
slotCompleteText(completionPrefix, false);
|
||||
slotCompleteText(completionPrefix, ActivationMode::Highlighted);
|
||||
}
|
||||
|
||||
void ExpressionLineEdit::slotCompleteTextSelected(const QString& completionPrefix)
|
||||
{
|
||||
slotCompleteText(completionPrefix, true);
|
||||
slotCompleteText(completionPrefix, ActivationMode::Activated);
|
||||
}
|
||||
|
||||
|
||||
@@ -1116,13 +1116,13 @@ void ExpressionTextEdit::setDocumentObject(const App::DocumentObject* currentDoc
|
||||
completer,
|
||||
qOverload<const QString&>(&QCompleter::activated),
|
||||
this,
|
||||
&ExpressionTextEdit::slotCompleteText
|
||||
&ExpressionTextEdit::slotCompleteTextSelected
|
||||
);
|
||||
connect(
|
||||
completer,
|
||||
qOverload<const QString&>(&QCompleter::highlighted),
|
||||
this,
|
||||
&ExpressionTextEdit::slotCompleteText
|
||||
&ExpressionTextEdit::slotCompleteTextHighlighted
|
||||
);
|
||||
connect(this, &ExpressionTextEdit::textChanged2, completer, &ExpressionCompleter::slotUpdate);
|
||||
connect(
|
||||
@@ -1155,7 +1155,7 @@ void ExpressionTextEdit::slotTextChanged()
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionTextEdit::slotCompleteText(const QString& completionPrefix)
|
||||
void ExpressionTextEdit::slotCompleteText(const QString& completionPrefix, ActivationMode mode)
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
int start, end;
|
||||
@@ -1165,17 +1165,31 @@ void ExpressionTextEdit::slotCompleteText(const QString& completionPrefix)
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, end - pos);
|
||||
}
|
||||
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, end - start);
|
||||
|
||||
Base::FlagToggler<bool> flag(block, false);
|
||||
cursor.insertText(completionPrefix);
|
||||
completer->updatePrefixEnd(cursor.positionInBlock());
|
||||
|
||||
std::string textToComplete = completionPrefix.toUtf8().constData();
|
||||
if (textToComplete.size()
|
||||
&& (*textToComplete.crbegin() == '.' || *textToComplete.crbegin() == '#')) {
|
||||
completer->slotUpdate(cursor.block().text(), cursor.positionInBlock());
|
||||
// chain completions only when activated (Enter/Click), not when highlighted (arrow keys)
|
||||
if (mode == ActivationMode::Activated) {
|
||||
std::string textToComplete = completionPrefix.toUtf8().constData();
|
||||
if (!textToComplete.empty()
|
||||
&& (*textToComplete.crbegin() == '.' || *textToComplete.crbegin() == '#')) {
|
||||
completer->slotUpdate(cursor.block().text(), cursor.positionInBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionTextEdit::slotCompleteTextHighlighted(const QString& completionPrefix)
|
||||
{
|
||||
slotCompleteText(completionPrefix, ActivationMode::Highlighted);
|
||||
}
|
||||
|
||||
void ExpressionTextEdit::slotCompleteTextSelected(const QString& completionPrefix)
|
||||
{
|
||||
slotCompleteText(completionPrefix, ActivationMode::Activated);
|
||||
}
|
||||
|
||||
void ExpressionTextEdit::keyPressEvent(QKeyEvent* e)
|
||||
{
|
||||
Base::FlagToggler<bool> flag(block, true);
|
||||
@@ -1208,9 +1222,8 @@ void ExpressionTextEdit::keyPressEvent(QKeyEvent* e)
|
||||
if (!completer->popup()->currentIndex().isValid()) {
|
||||
completer->popup()->setCurrentIndex(completer->popup()->model()->index(0, 0));
|
||||
}
|
||||
// insert completion
|
||||
completer->setCurrentRow(completer->popup()->currentIndex().row());
|
||||
slotCompleteText(completer->currentCompletion());
|
||||
slotCompleteText(completer->currentCompletion(), ActivationMode::Highlighted);
|
||||
|
||||
// refresh completion list
|
||||
completer->setCompletionPrefix(completer->currentCompletion());
|
||||
|
||||
@@ -44,6 +44,12 @@ class ObjectIdentifier;
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
enum class ActivationMode
|
||||
{
|
||||
Highlighted, // browsing with arrow keys
|
||||
Activated // confirmed selection (Enter/Click)
|
||||
};
|
||||
|
||||
class GuiExport ExpressionValidator: public QValidator
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -123,8 +129,7 @@ Q_SIGNALS:
|
||||
void textChanged2(QString text, int pos);
|
||||
public Q_SLOTS:
|
||||
void slotTextChanged(const QString& text);
|
||||
// activated == pressed enter on the completion item
|
||||
void slotCompleteText(const QString& completionPrefix, bool isActivated);
|
||||
void slotCompleteText(const QString& completionPrefix, ActivationMode mode);
|
||||
void slotCompleteTextHighlighted(const QString& completionPrefix);
|
||||
void slotCompleteTextSelected(const QString& completionPrefix);
|
||||
|
||||
@@ -159,7 +164,9 @@ Q_SIGNALS:
|
||||
void textChanged2(QString text, int pos);
|
||||
public Q_SLOTS:
|
||||
void slotTextChanged();
|
||||
void slotCompleteText(const QString& completionPrefix);
|
||||
void slotCompleteText(const QString& completionPrefix, ActivationMode mode);
|
||||
void slotCompleteTextHighlighted(const QString& completionPrefix);
|
||||
void slotCompleteTextSelected(const QString& completionPrefix);
|
||||
void adjustCompleterToCursor();
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user