diff --git a/src/Gui/ExpressionCompleter.cpp b/src/Gui/ExpressionCompleter.cpp index f10975f1e9..59c53db1c8 100644 --- a/src/Gui/ExpressionCompleter.cpp +++ b/src/Gui/ExpressionCompleter.cpp @@ -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(&QCompleter::activated), this, - &ExpressionTextEdit::slotCompleteText + &ExpressionTextEdit::slotCompleteTextSelected ); connect( completer, qOverload(&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 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 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()); diff --git a/src/Gui/ExpressionCompleter.h b/src/Gui/ExpressionCompleter.h index 7db07b881e..3294aac78e 100644 --- a/src/Gui/ExpressionCompleter.h +++ b/src/Gui/ExpressionCompleter.h @@ -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: