From e4994864188747de381e3eab149f1676c8677347 Mon Sep 17 00:00:00 2001 From: apa420 <17131426+apa420@users.noreply.github.com> Date: Sun, 22 Aug 2021 13:30:17 +0200 Subject: [PATCH] Added regex option to Nicknames (#3146) Co-authored-by: Mm2PL Co-authored-by: Rasmus Karlsson --- CHANGELOG.md | 1 + src/controllers/nicknames/Nickname.hpp | 86 +++++++++++++++++-- src/controllers/nicknames/NicknamesModel.cpp | 8 +- src/providers/twitch/TwitchMessageBuilder.cpp | 4 +- src/widgets/settingspages/NicknamesPage.cpp | 11 ++- 5 files changed, 95 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 277fcd90..44e3e73e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Minor: Commands are now backed up. (#3168) - Minor: Added the ability to open an entire tab as a popup. (#3082) - Minor: Added optional parameter to /usercard command for opening a usercard in a different channel context. (#3172) +- Minor: Added regex option to Nicknames. (#3146) - Bugfix: Fixed colored usernames sometimes not working. (#3170) - Bugfix: Restored ability to send duplicate `/me` messages. (#3166) - Bugfix: Notifications for moderators about other moderators deleting messages can now be disabled. (#3121) diff --git a/src/controllers/nicknames/Nickname.hpp b/src/controllers/nicknames/Nickname.hpp index 67e7d3f4..3fb0b23b 100644 --- a/src/controllers/nicknames/Nickname.hpp +++ b/src/controllers/nicknames/Nickname.hpp @@ -1,7 +1,6 @@ #pragma once #include "controllers/accounts/AccountController.hpp" - #include "util/RapidJsonSerializeQString.hpp" #include "util/RapidjsonHelpers.hpp" @@ -15,24 +14,92 @@ namespace chatterino { class Nickname { public: - Nickname(const QString &name, const QString &replace) + Nickname(const QString &name, const QString &replace, const bool isRegex, + const bool isCaseSensitive) : name_(name) , replace_(replace) + , isRegex_(isRegex) + , isCaseSensitive_(isCaseSensitive) + , caseSensitivity_(this->isCaseSensitive_ ? Qt::CaseSensitive + : Qt::CaseInsensitive) { + if (this->isRegex()) + { + this->regex_ = QRegularExpression( + name, QRegularExpression::UseUnicodePropertiesOption | + (this->isCaseSensitive() + ? QRegularExpression::NoPatternOption + : QRegularExpression::CaseInsensitiveOption)); + } } - const QString &name() const + [[nodiscard]] const QString &name() const { return this->name_; } - const QString &replace() const + + [[nodiscard]] const QString &replace() const { return this->replace_; } + [[nodiscard]] bool isRegex() const + { + return this->isRegex_; + } + + [[nodiscard]] Qt::CaseSensitivity caseSensitivity() const + { + return this->caseSensitivity_; + } + + [[nodiscard]] const bool &isCaseSensitive() const + { + return this->isCaseSensitive_; + } + + [[nodiscard]] bool match(QString &usernameText) const + { + if (this->isRegex()) + { + if (!this->regex_.isValid()) + { + return false; + } + if (this->name().isEmpty()) + { + return false; + } + + auto workingCopy = usernameText; + workingCopy.replace(this->regex_, this->replace()); + if (workingCopy != usernameText) + { + usernameText = workingCopy; + return true; + } + } + else + { + auto res = + this->name().compare(usernameText, this->caseSensitivity()); + if (res == 0) + { + usernameText = this->replace(); + return true; + } + } + + return false; + } + private: QString name_; QString replace_; + bool isRegex_; + bool isCaseSensitive_; + Qt::CaseSensitivity caseSensitivity_; + QRegularExpression regex_{}; }; } // namespace chatterino @@ -48,6 +115,8 @@ struct Serialize { chatterino::rj::set(ret, "name", value.name(), a); chatterino::rj::set(ret, "replace", value.replace(), a); + chatterino::rj::set(ret, "isRegex", value.isRegex(), a); + chatterino::rj::set(ret, "isCaseSensitive", value.isCaseSensitive(), a); return ret; } @@ -61,16 +130,21 @@ struct Deserialize { if (!value.IsObject()) { PAJLADA_REPORT_ERROR(error) - return chatterino::Nickname(QString(), QString()); + return chatterino::Nickname(QString(), QString(), false, false); } QString _name; QString _replace; + bool _isRegex; + bool _isCaseSensitive; chatterino::rj::getSafe(value, "name", _name); chatterino::rj::getSafe(value, "replace", _replace); + chatterino::rj::getSafe(value, "isRegex", _isRegex); + chatterino::rj::getSafe(value, "isCaseSensitive", _isCaseSensitive); - return chatterino::Nickname(_name, _replace); + return chatterino::Nickname(_name, _replace, _isRegex, + _isCaseSensitive); } }; diff --git a/src/controllers/nicknames/NicknamesModel.cpp b/src/controllers/nicknames/NicknamesModel.cpp index 703c6661..2748f49b 100644 --- a/src/controllers/nicknames/NicknamesModel.cpp +++ b/src/controllers/nicknames/NicknamesModel.cpp @@ -8,7 +8,7 @@ namespace chatterino { NicknamesModel::NicknamesModel(QObject *parent) - : SignalVectorModel(2, parent) + : SignalVectorModel(4, parent) { } @@ -17,7 +17,9 @@ Nickname NicknamesModel::getItemFromRow(std::vector &row, const Nickname &original) { return Nickname{row[0]->data(Qt::DisplayRole).toString(), - row[1]->data(Qt::DisplayRole).toString()}; + row[1]->data(Qt::DisplayRole).toString(), + row[2]->data(Qt::CheckStateRole).toBool(), + row[3]->data(Qt::CheckStateRole).toBool()}; } // turns a row in the model into a vector item @@ -26,6 +28,8 @@ void NicknamesModel::getRowFromItem(const Nickname &item, { setStringItem(row[0], item.name()); setStringItem(row[1], item.replace()); + setBoolItem(row[2], item.isRegex()); + setBoolItem(row[3], item.isCaseSensitive()); } } // namespace chatterino diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index f91f2f74..42fd676a 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -639,13 +639,11 @@ void TwitchMessageBuilder::appendUsername() } auto nicknames = getCSettings().nicknames.readOnly(); - auto loginLower = this->message().loginName.toLower(); for (const auto &nickname : *nicknames) { - if (nickname.name().toLower() == loginLower) + if (nickname.match(usernameText)) { - usernameText = nickname.replace(); break; } } diff --git a/src/widgets/settingspages/NicknamesPage.cpp b/src/widgets/settingspages/NicknamesPage.cpp index 2a464d7c..3a34288b 100644 --- a/src/widgets/settingspages/NicknamesPage.cpp +++ b/src/widgets/settingspages/NicknamesPage.cpp @@ -29,19 +29,22 @@ NicknamesPage::NicknamesPage() ->initialized(&getSettings()->nicknames)) .getElement(); - view->setTitles({"Username", "Nickname"}); + view->setTitles({"Username", "Nickname", "Enable regex", "Case Sensitive"}); view->getTableView()->horizontalHeader()->setSectionResizeMode( - QHeaderView::Interactive); + QHeaderView::Fixed); + view->getTableView()->horizontalHeader()->setSectionResizeMode( + 0, QHeaderView::Stretch); view->getTableView()->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch); view->addButtonPressed.connect([] { - getSettings()->nicknames.append(Nickname{"Username", "Nickname"}); + getSettings()->nicknames.append( + Nickname{"Username", "Nickname", false, false}); }); QTimer::singleShot(1, [view] { view->getTableView()->resizeColumnsToContents(); - view->getTableView()->setColumnWidth(0, 250); + view->getTableView()->setColumnWidth(0, 200); }); }