From be5318f275cacf231aa14be555e9e121796c941f Mon Sep 17 00:00:00 2001 From: Leon Richardt Date: Sat, 17 Aug 2019 19:12:58 +0200 Subject: [PATCH 1/3] Fix emote completion bug This commit fixes a bug that would occur when changing the completion mode from prefix-only to substring while mid-completion. In that case, the suggestion list was not updated until the next completion attempt. This is fixed by forcing a suggestion list refresh whenever the setting's checkbox is updated. --- src/common/CompletionModel.hpp | 1 + src/widgets/helper/ResizingTextEdit.cpp | 5 +++++ src/widgets/helper/ResizingTextEdit.hpp | 2 ++ src/widgets/settingspages/GeneralPage.cpp | 22 +++++++++++++++++++--- src/widgets/splits/Split.cpp | 17 +++++++++++++++++ src/widgets/splits/Split.hpp | 3 +-- 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/common/CompletionModel.hpp b/src/common/CompletionModel.hpp index f4f216cd..41cc4a5d 100644 --- a/src/common/CompletionModel.hpp +++ b/src/common/CompletionModel.hpp @@ -48,6 +48,7 @@ public: virtual int rowCount(const QModelIndex &) const override; void refresh(const QString &prefix); + void updateEmoteCompletionMethod(); private: TaggedString createUser(const QString &str); diff --git a/src/widgets/helper/ResizingTextEdit.cpp b/src/widgets/helper/ResizingTextEdit.cpp index 92b5b8ef..22f66d55 100644 --- a/src/widgets/helper/ResizingTextEdit.cpp +++ b/src/widgets/helper/ResizingTextEdit.cpp @@ -260,6 +260,11 @@ void ResizingTextEdit::insertFromMimeData(const QMimeData *source) } } +void ResizingTextEdit::resetCompletionInProgress() +{ + this->completionInProgress_ = false; +} + QCompleter *ResizingTextEdit::getCompleter() const { return this->completer_; diff --git a/src/widgets/helper/ResizingTextEdit.hpp b/src/widgets/helper/ResizingTextEdit.hpp index ff79cddb..7f4907d0 100644 --- a/src/widgets/helper/ResizingTextEdit.hpp +++ b/src/widgets/helper/ResizingTextEdit.hpp @@ -20,6 +20,8 @@ public: pajlada::Signals::NoArgSignal focused; pajlada::Signals::NoArgSignal focusLost; + void resetCompletionInProgress(); + void setCompleter(QCompleter *c); QCompleter *getCompleter() const; diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index aec81113..10aa2ace 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -8,10 +8,12 @@ #include "singletons/Fonts.hpp" #include "singletons/Paths.hpp" #include "singletons/Theme.hpp" -#include "singletons/WindowManager.hpp" #include "util/FuzzyConvert.hpp" #include "util/Helpers.hpp" +#include "widgets/Notebook.hpp" +#include "widgets/Window.hpp" #include "widgets/helper/Line.hpp" +#include "widgets/splits/Split.hpp" #define CHROME_EXTENSION_LINK \ "https://chrome.google.com/webstore/detail/chatterino-native-host/" \ @@ -283,8 +285,22 @@ void GeneralPage::initLayout(SettingsLayout &layout) {"Don't show", "Always show", "Hold shift"}, s.emotesTooltipPreview, [](int index) { return index; }, [](auto args) { return args.index; }, false); - layout.addCheckbox("Only search for emote autocompletion at the start of emote names", - s.prefixOnlyEmoteCompletion); + + auto emoteCompletionCheckbox = layout.addCheckbox( + "Only search for emote autocompletion at the start of emote names", + s.prefixOnlyEmoteCompletion); + + // Get the currently active split + // XXX: Is there a better way to do this? + auto selectedSplit = + static_cast( + getApp()->windows->getMainWindow().getNotebook().getSelectedPage()) + ->getBaseNode() + ->getSplit(); + + // Update emote completion mode when checkbox state is changed + QObject::connect(emoteCompletionCheckbox, &QCheckBox::stateChanged, + selectedSplit, &Split::updateEmoteCompletion); layout.addSpacing(16); layout.addSeperator(); diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index d610b522..13670b5f 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -669,6 +669,23 @@ void Split::reloadChannelAndSubscriberEmotes() twitchChannel->refreshChannelEmotes(); } +void Split::updateEmoteCompletion() +{ + if (getSettings()->prefixOnlyEmoteCompletion) + { + this->input_->ui_.textEdit->getCompleter()->setFilterMode( + Qt::MatchStartsWith); + } + else + { + this->input_->ui_.textEdit->getCompleter()->setFilterMode( + Qt::MatchContains); + } + + // Reset the completion status so a refresh will be triggered on next "Tab" + this->input_->ui_.textEdit->resetCompletionInProgress(); +} + template static Iter select_randomly(Iter start, Iter end, RandomGenerator &g) { diff --git a/src/widgets/splits/Split.hpp b/src/widgets/splits/Split.hpp index edfca352..894da1a0 100644 --- a/src/widgets/splits/Split.hpp +++ b/src/widgets/splits/Split.hpp @@ -8,8 +8,6 @@ #include #include #include -#include - namespace chatterino { class ChannelView; @@ -131,6 +129,7 @@ public slots: void showViewerList(); void openSubPage(); void reloadChannelAndSubscriberEmotes(); + void updateEmoteCompletion(); }; } // namespace chatterino From 23a5f0bfb209bbe30c29c0e4e388fa8cac256f9c Mon Sep 17 00:00:00 2001 From: Leon Richardt Date: Sat, 17 Aug 2019 22:10:27 +0200 Subject: [PATCH 2/3] Remove unused method declaration --- src/common/CompletionModel.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/CompletionModel.hpp b/src/common/CompletionModel.hpp index 41cc4a5d..f4f216cd 100644 --- a/src/common/CompletionModel.hpp +++ b/src/common/CompletionModel.hpp @@ -48,7 +48,6 @@ public: virtual int rowCount(const QModelIndex &) const override; void refresh(const QString &prefix); - void updateEmoteCompletionMethod(); private: TaggedString createUser(const QString &str); From f2b2e3142fc700f3a92a62e723dfb4e5da27869f Mon Sep 17 00:00:00 2001 From: Leon Richardt Date: Sun, 18 Aug 2019 21:37:20 +0200 Subject: [PATCH 3/3] Implement simpler fix for emote completion bug This commit implements a simpler fix for the problem described in #1209. The setting's signal is connected to a reset of `completionInProgress_` so that the completion model is updated on the next word already. This commit also removes the older approach tackling this issue. --- src/widgets/helper/ResizingTextEdit.cpp | 10 +++++----- src/widgets/helper/ResizingTextEdit.hpp | 2 -- src/widgets/settingspages/GeneralPage.cpp | 18 ++---------------- src/widgets/splits/Split.cpp | 17 ----------------- src/widgets/splits/Split.hpp | 3 ++- 5 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/widgets/helper/ResizingTextEdit.cpp b/src/widgets/helper/ResizingTextEdit.cpp index 22f66d55..cee49139 100644 --- a/src/widgets/helper/ResizingTextEdit.cpp +++ b/src/widgets/helper/ResizingTextEdit.cpp @@ -16,6 +16,11 @@ ResizingTextEdit::ResizingTextEdit() QObject::connect(this, &QTextEdit::textChanged, this, &QWidget::updateGeometry); + // Whenever the setting for emote completion changes, force a + // refresh on the completion model the next time "Tab" is pressed + getSettings()->prefixOnlyEmoteCompletion.connect( + [this] { this->completionInProgress_ = false; }); + this->setFocusPolicy(Qt::ClickFocus); } @@ -260,11 +265,6 @@ void ResizingTextEdit::insertFromMimeData(const QMimeData *source) } } -void ResizingTextEdit::resetCompletionInProgress() -{ - this->completionInProgress_ = false; -} - QCompleter *ResizingTextEdit::getCompleter() const { return this->completer_; diff --git a/src/widgets/helper/ResizingTextEdit.hpp b/src/widgets/helper/ResizingTextEdit.hpp index 7f4907d0..ff79cddb 100644 --- a/src/widgets/helper/ResizingTextEdit.hpp +++ b/src/widgets/helper/ResizingTextEdit.hpp @@ -20,8 +20,6 @@ public: pajlada::Signals::NoArgSignal focused; pajlada::Signals::NoArgSignal focusLost; - void resetCompletionInProgress(); - void setCompleter(QCompleter *c); QCompleter *getCompleter() const; diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index 10aa2ace..64365e0a 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -8,12 +8,10 @@ #include "singletons/Fonts.hpp" #include "singletons/Paths.hpp" #include "singletons/Theme.hpp" +#include "singletons/WindowManager.hpp" #include "util/FuzzyConvert.hpp" #include "util/Helpers.hpp" -#include "widgets/Notebook.hpp" -#include "widgets/Window.hpp" #include "widgets/helper/Line.hpp" -#include "widgets/splits/Split.hpp" #define CHROME_EXTENSION_LINK \ "https://chrome.google.com/webstore/detail/chatterino-native-host/" \ @@ -286,22 +284,10 @@ void GeneralPage::initLayout(SettingsLayout &layout) [](int index) { return index; }, [](auto args) { return args.index; }, false); - auto emoteCompletionCheckbox = layout.addCheckbox( + layout.addCheckbox( "Only search for emote autocompletion at the start of emote names", s.prefixOnlyEmoteCompletion); - // Get the currently active split - // XXX: Is there a better way to do this? - auto selectedSplit = - static_cast( - getApp()->windows->getMainWindow().getNotebook().getSelectedPage()) - ->getBaseNode() - ->getSplit(); - - // Update emote completion mode when checkbox state is changed - QObject::connect(emoteCompletionCheckbox, &QCheckBox::stateChanged, - selectedSplit, &Split::updateEmoteCompletion); - layout.addSpacing(16); layout.addSeperator(); diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index 13670b5f..d610b522 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -669,23 +669,6 @@ void Split::reloadChannelAndSubscriberEmotes() twitchChannel->refreshChannelEmotes(); } -void Split::updateEmoteCompletion() -{ - if (getSettings()->prefixOnlyEmoteCompletion) - { - this->input_->ui_.textEdit->getCompleter()->setFilterMode( - Qt::MatchStartsWith); - } - else - { - this->input_->ui_.textEdit->getCompleter()->setFilterMode( - Qt::MatchContains); - } - - // Reset the completion status so a refresh will be triggered on next "Tab" - this->input_->ui_.textEdit->resetCompletionInProgress(); -} - template static Iter select_randomly(Iter start, Iter end, RandomGenerator &g) { diff --git a/src/widgets/splits/Split.hpp b/src/widgets/splits/Split.hpp index 894da1a0..edfca352 100644 --- a/src/widgets/splits/Split.hpp +++ b/src/widgets/splits/Split.hpp @@ -8,6 +8,8 @@ #include #include #include +#include + namespace chatterino { class ChannelView; @@ -129,7 +131,6 @@ public slots: void showViewerList(); void openSubPage(); void reloadChannelAndSubscriberEmotes(); - void updateEmoteCompletion(); }; } // namespace chatterino