Added regex option to Nicknames (#3146)

Co-authored-by: Mm2PL <miau@mail.kotmisia.pl>
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
apa420 2021-08-22 13:30:17 +02:00 committed by GitHub
parent fe8aa33980
commit e499486418
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 15 deletions

View file

@ -11,6 +11,7 @@
- Minor: Commands are now backed up. (#3168) - Minor: Commands are now backed up. (#3168)
- Minor: Added the ability to open an entire tab as a popup. (#3082) - 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 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: Fixed colored usernames sometimes not working. (#3170)
- Bugfix: Restored ability to send duplicate `/me` messages. (#3166) - Bugfix: Restored ability to send duplicate `/me` messages. (#3166)
- Bugfix: Notifications for moderators about other moderators deleting messages can now be disabled. (#3121) - Bugfix: Notifications for moderators about other moderators deleting messages can now be disabled. (#3121)

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "controllers/accounts/AccountController.hpp" #include "controllers/accounts/AccountController.hpp"
#include "util/RapidJsonSerializeQString.hpp" #include "util/RapidJsonSerializeQString.hpp"
#include "util/RapidjsonHelpers.hpp" #include "util/RapidjsonHelpers.hpp"
@ -15,24 +14,92 @@ namespace chatterino {
class Nickname class Nickname
{ {
public: public:
Nickname(const QString &name, const QString &replace) Nickname(const QString &name, const QString &replace, const bool isRegex,
const bool isCaseSensitive)
: name_(name) : name_(name)
, replace_(replace) , 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_; return this->name_;
} }
const QString &replace() const
[[nodiscard]] const QString &replace() const
{ {
return this->replace_; 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: private:
QString name_; QString name_;
QString replace_; QString replace_;
bool isRegex_;
bool isCaseSensitive_;
Qt::CaseSensitivity caseSensitivity_;
QRegularExpression regex_{};
}; };
} // namespace chatterino } // namespace chatterino
@ -48,6 +115,8 @@ struct Serialize<chatterino::Nickname> {
chatterino::rj::set(ret, "name", value.name(), a); chatterino::rj::set(ret, "name", value.name(), a);
chatterino::rj::set(ret, "replace", value.replace(), 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; return ret;
} }
@ -61,16 +130,21 @@ struct Deserialize<chatterino::Nickname> {
if (!value.IsObject()) if (!value.IsObject())
{ {
PAJLADA_REPORT_ERROR(error) PAJLADA_REPORT_ERROR(error)
return chatterino::Nickname(QString(), QString()); return chatterino::Nickname(QString(), QString(), false, false);
} }
QString _name; QString _name;
QString _replace; QString _replace;
bool _isRegex;
bool _isCaseSensitive;
chatterino::rj::getSafe(value, "name", _name); chatterino::rj::getSafe(value, "name", _name);
chatterino::rj::getSafe(value, "replace", _replace); 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);
} }
}; };

View file

@ -8,7 +8,7 @@
namespace chatterino { namespace chatterino {
NicknamesModel::NicknamesModel(QObject *parent) NicknamesModel::NicknamesModel(QObject *parent)
: SignalVectorModel<Nickname>(2, parent) : SignalVectorModel<Nickname>(4, parent)
{ {
} }
@ -17,7 +17,9 @@ Nickname NicknamesModel::getItemFromRow(std::vector<QStandardItem *> &row,
const Nickname &original) const Nickname &original)
{ {
return Nickname{row[0]->data(Qt::DisplayRole).toString(), 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 // 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[0], item.name());
setStringItem(row[1], item.replace()); setStringItem(row[1], item.replace());
setBoolItem(row[2], item.isRegex());
setBoolItem(row[3], item.isCaseSensitive());
} }
} // namespace chatterino } // namespace chatterino

View file

@ -639,13 +639,11 @@ void TwitchMessageBuilder::appendUsername()
} }
auto nicknames = getCSettings().nicknames.readOnly(); auto nicknames = getCSettings().nicknames.readOnly();
auto loginLower = this->message().loginName.toLower();
for (const auto &nickname : *nicknames) for (const auto &nickname : *nicknames)
{ {
if (nickname.name().toLower() == loginLower) if (nickname.match(usernameText))
{ {
usernameText = nickname.replace();
break; break;
} }
} }

View file

@ -29,19 +29,22 @@ NicknamesPage::NicknamesPage()
->initialized(&getSettings()->nicknames)) ->initialized(&getSettings()->nicknames))
.getElement(); .getElement();
view->setTitles({"Username", "Nickname"}); view->setTitles({"Username", "Nickname", "Enable regex", "Case Sensitive"});
view->getTableView()->horizontalHeader()->setSectionResizeMode( view->getTableView()->horizontalHeader()->setSectionResizeMode(
QHeaderView::Interactive); QHeaderView::Fixed);
view->getTableView()->horizontalHeader()->setSectionResizeMode(
0, QHeaderView::Stretch);
view->getTableView()->horizontalHeader()->setSectionResizeMode( view->getTableView()->horizontalHeader()->setSectionResizeMode(
1, QHeaderView::Stretch); 1, QHeaderView::Stretch);
view->addButtonPressed.connect([] { view->addButtonPressed.connect([] {
getSettings()->nicknames.append(Nickname{"Username", "Nickname"}); getSettings()->nicknames.append(
Nickname{"Username", "Nickname", false, false});
}); });
QTimer::singleShot(1, [view] { QTimer::singleShot(1, [view] {
view->getTableView()->resizeColumnsToContents(); view->getTableView()->resizeColumnsToContents();
view->getTableView()->setColumnWidth(0, 250); view->getTableView()->setColumnWidth(0, 200);
}); });
} }