rename variables to fit better, emotes in capture groups from regex work

This commit is contained in:
hemirt 2018-07-28 19:53:55 +02:00
parent 00c9fa080a
commit f00d3da537
5 changed files with 92 additions and 57 deletions

View file

@ -29,8 +29,8 @@ void IgnoreModel::getRowFromItem(const IgnorePhrase &item, std::vector<QStandard
{ {
setStringItem(row[0], item.getPattern()); setStringItem(row[0], item.getPattern());
setBoolItem(row[1], item.isRegex()); setBoolItem(row[1], item.isRegex());
setBoolItem(row[2], item.caseInsensitive()); setBoolItem(row[2], item.isCaseSensitive());
setBoolItem(row[3], item.isReplace()); setBoolItem(row[3], item.isBlock());
setStringItem(row[4], item.getReplace()); setStringItem(row[4], item.getReplace());
} }

View file

@ -17,26 +17,26 @@ class IgnorePhrase
public: public:
bool operator==(const IgnorePhrase &other) const bool operator==(const IgnorePhrase &other) const
{ {
return std::tie(this->pattern_, this->isRegex_, this->isReplace_, this->replace_, return std::tie(this->pattern_, this->isRegex_, this->isBlock_, this->replace_,
this->caseInsensitive_) == std::tie(other.pattern_, other.isRegex_, this->isCaseSensitive_) == std::tie(other.pattern_, other.isRegex_,
other.isReplace_, other.replace_, other.isBlock_, other.replace_,
other.caseInsensitive_); other.isCaseSensitive_);
} }
IgnorePhrase(const QString &pattern, bool isRegex, bool isReplace, const QString &replace, IgnorePhrase(const QString &pattern, bool isRegex, bool isBlock, const QString &replace,
bool caseInsensitive) bool isCaseSensitive)
: pattern_(pattern) : pattern_(pattern)
, isRegex_(isRegex) , isRegex_(isRegex)
, regex_(pattern) , regex_(pattern)
, isReplace_(isReplace) , isBlock_(isBlock)
, replace_(replace) , replace_(replace)
, caseInsensitive_(caseInsensitive) , isCaseSensitive_(isCaseSensitive)
{ {
if (this->caseInsensitive_) { if (this->isCaseSensitive_) {
regex_.setPatternOptions(QRegularExpression::UseUnicodePropertiesOption);
} else {
regex_.setPatternOptions(QRegularExpression::CaseInsensitiveOption | regex_.setPatternOptions(QRegularExpression::CaseInsensitiveOption |
QRegularExpression::UseUnicodePropertiesOption); QRegularExpression::UseUnicodePropertiesOption);
} else {
regex_.setPatternOptions(QRegularExpression::UseUnicodePropertiesOption);
} }
} }
@ -44,11 +44,17 @@ public:
{ {
return this->pattern_; return this->pattern_;
} }
bool isRegex() const bool isRegex() const
{ {
return this->isRegex_; return this->isRegex_;
} }
bool isRegexValid() const
{
return this->regex_.isValid();
}
bool isMatch(const QString &subject) const bool isMatch(const QString &subject) const
{ {
return !this->pattern_.isEmpty() && return !this->pattern_.isEmpty() &&
@ -61,9 +67,9 @@ public:
return this->regex_; return this->regex_;
} }
bool isReplace() const bool isBlock() const
{ {
return this->isReplace_; return this->isBlock_;
} }
const QString &getReplace() const const QString &getReplace() const
@ -71,23 +77,23 @@ public:
return this->replace_; return this->replace_;
} }
bool caseInsensitive() const bool isCaseSensitive() const
{ {
return this->caseInsensitive_; return this->isCaseSensitive_;
} }
Qt::CaseSensitivity caseSensitivity() const Qt::CaseSensitivity caseSensitivity() const
{ {
return this->caseInsensitive_ ? Qt::CaseInsensitive : Qt::CaseSensitive; return this->isCaseSensitive_ ? Qt::CaseSensitive : Qt::CaseInsensitive;
} }
private: private:
QString pattern_; QString pattern_;
bool isRegex_; bool isRegex_;
QRegularExpression regex_; QRegularExpression regex_;
bool isReplace_; bool isBlock_;
QString replace_; QString replace_;
bool caseInsensitive_; bool isCaseSensitive_;
}; };
} // namespace chatterino } // namespace chatterino
@ -103,9 +109,9 @@ struct Serialize<chatterino::IgnorePhrase> {
AddMember(ret, "pattern", value.getPattern(), a); AddMember(ret, "pattern", value.getPattern(), a);
AddMember(ret, "regex", value.isRegex(), a); AddMember(ret, "regex", value.isRegex(), a);
AddMember(ret, "onlyWord", value.isReplace(), a); AddMember(ret, "isBlock", value.isBlock(), a);
AddMember(ret, "replace", value.getReplace(), a); AddMember(ret, "replaceWith", value.getReplace(), a);
AddMember(ret, "caseInsens", value.caseInsensitive(), a); AddMember(ret, "caseSensitive", value.isCaseSensitive(), a);
return ret; return ret;
} }
@ -118,22 +124,22 @@ struct Deserialize<chatterino::IgnorePhrase> {
if (!value.IsObject()) { if (!value.IsObject()) {
return chatterino::IgnorePhrase( return chatterino::IgnorePhrase(
QString(), false, false, QString(), false, false,
::chatterino::getSettings()->ignoredPhraseReplace.getValue(), false); ::chatterino::getSettings()->ignoredPhraseReplace.getValue(), true);
} }
QString _pattern; QString _pattern;
bool _isRegex = false; bool _isRegex = false;
bool _isReplace = false; bool _isBlock = false;
QString _replace; QString _replace;
bool _caseInsens = false; bool _caseSens = true;
chatterino::rj::getSafe(value, "pattern", _pattern); chatterino::rj::getSafe(value, "pattern", _pattern);
chatterino::rj::getSafe(value, "regex", _isRegex); chatterino::rj::getSafe(value, "regex", _isRegex);
chatterino::rj::getSafe(value, "onlyWord", _isReplace); chatterino::rj::getSafe(value, "isBlock", _isBlock);
chatterino::rj::getSafe(value, "replace", _replace); chatterino::rj::getSafe(value, "replaceWith", _replace);
chatterino::rj::getSafe(value, "caseInsens", _caseInsens); chatterino::rj::getSafe(value, "caseSensitive", _caseSens);
return chatterino::IgnorePhrase(_pattern, _isRegex, _isReplace, _replace, _caseInsens); return chatterino::IgnorePhrase(_pattern, _isRegex, _isBlock, _replace, _caseSens);
} }
}; };

View file

@ -56,7 +56,7 @@ bool TwitchMessageBuilder::isIgnored() const
// TODO(pajlada): Do we need to check if the phrase is valid first? // TODO(pajlada): Do we need to check if the phrase is valid first?
for (const auto &phrase : app->ignores->phrases.getVector()) { for (const auto &phrase : app->ignores->phrases.getVector()) {
if (!phrase.isReplace() && phrase.isMatch(this->originalMessage_)) { if (phrase.isBlock() && phrase.isMatch(this->originalMessage_)) {
Log("Blocking message because it contains ignored phrase {}", phrase.getPattern()); Log("Blocking message because it contains ignored phrase {}", phrase.getPattern());
return true; return true;
} }
@ -152,7 +152,7 @@ MessagePtr TwitchMessageBuilder::build()
} }
// twitch emotes // twitch emotes
std::vector<std::pair<long, EmoteData>> twitchEmotes; std::vector<std::tuple<long, EmoteData, QString>> twitchEmotes;
iterator = this->tags.find("emotes"); iterator = this->tags.find("emotes");
if (iterator != this->tags.end()) { if (iterator != this->tags.end()) {
@ -161,32 +161,31 @@ MessagePtr TwitchMessageBuilder::build()
for (QString emote : emoteString) { for (QString emote : emoteString) {
this->appendTwitchEmote(ircMessage, emote, twitchEmotes); this->appendTwitchEmote(ircMessage, emote, twitchEmotes);
} }
std::sort(twitchEmotes.begin(), twitchEmotes.end(),
[](const auto &a, const auto &b) { return a.first < b.first; });
} }
const auto &phrases = app->ignores->phrases.getVector(); const auto &phrases = app->ignores->phrases.getVector();
auto removeEmotesInRange = [&twitchEmotes](int pos, int len) mutable { auto removeEmotesInRange = [&twitchEmotes](int pos, int len) mutable {
twitchEmotes.erase( auto it = std::remove_if(
std::remove_if(twitchEmotes.begin(), twitchEmotes.end(), twitchEmotes.begin(), twitchEmotes.end(), [&pos, &len](const auto &item) {
[&pos, &len](const auto &item) { return ((std::get<0>(item) >= pos) && std::get<0>(item) < (pos + len));
return ((item.first >= pos) && item.first < (pos + len)); });
}),
twitchEmotes.end()); std::vector<std::tuple<long, EmoteData, QString>> v(it, twitchEmotes.end());
twitchEmotes.erase(it, twitchEmotes.end());
return v;
}; };
auto shiftIndicesAfter = [&twitchEmotes](int pos, int by) mutable { auto shiftIndicesAfter = [&twitchEmotes](int pos, int by) mutable {
auto it = std::find_if(twitchEmotes.begin(), twitchEmotes.end(), auto it = std::find_if(twitchEmotes.begin(), twitchEmotes.end(),
[&pos](const auto &item) { return item.first >= pos; }); [&pos](const auto &item) { return std::get<0>(item) >= pos; });
while (it != twitchEmotes.end()) { while (it != twitchEmotes.end()) {
it->first += by; std::get<0>(*it) += by;
++it; ++it;
} }
}; };
for (const auto &phrase : phrases) { for (const auto &phrase : phrases) {
if (!phrase.isReplace()) { if (phrase.isBlock()) {
continue; continue;
} }
if (phrase.isRegex()) { if (phrase.isRegex()) {
@ -198,9 +197,23 @@ MessagePtr TwitchMessageBuilder::build()
int from = 0; int from = 0;
while ((from = this->originalMessage_.indexOf(regex, from, &match)) != -1) { while ((from = this->originalMessage_.indexOf(regex, from, &match)) != -1) {
int len = match.capturedLength(); int len = match.capturedLength();
removeEmotesInRange(from, len); auto vret = removeEmotesInRange(from, len);
auto mid = this->originalMessage_.mid(from, len); auto mid = this->originalMessage_.mid(from, len);
mid.replace(regex, phrase.getReplace()); mid.replace(regex, phrase.getReplace());
// hemirt
// doesnt check for own emotes in the Replace part
// mb in IgnoredPhrase ??
for (auto &tup : vret) {
int index = 0;
const auto &emote = std::get<2>(tup);
while ((index = mid.indexOf(emote, index)) != -1) {
std::get<0>(tup) = from + index;
index += emote.size();
twitchEmotes.push_back(tup);
}
}
this->originalMessage_.replace(from, len, mid); this->originalMessage_.replace(from, len, mid);
int midsize = mid.size(); int midsize = mid.size();
from += midsize; from += midsize;
@ -215,8 +228,22 @@ MessagePtr TwitchMessageBuilder::build()
while ((from = this->originalMessage_.indexOf(pattern, from, while ((from = this->originalMessage_.indexOf(pattern, from,
phrase.caseSensitivity())) != -1) { phrase.caseSensitivity())) != -1) {
int len = pattern.size(); int len = pattern.size();
removeEmotesInRange(from, len); auto vret = removeEmotesInRange(from, len);
const auto &replace = phrase.getReplace(); auto replace = phrase.getReplace();
// hemirt
// doesnt check for own emotes in the Replace part
// mb in IgnoredPhrase ??
for (auto &tup : vret) {
int index = 0;
const auto &emote = std::get<2>(tup);
while ((index = replace.indexOf(emote, index)) != -1) {
std::get<0>(tup) = from + index;
index += emote.size();
twitchEmotes.push_back(tup);
}
}
this->originalMessage_.replace(from, len, replace); this->originalMessage_.replace(from, len, replace);
int replacesize = replace.size(); int replacesize = replace.size();
from += replacesize; from += replacesize;
@ -225,6 +252,8 @@ MessagePtr TwitchMessageBuilder::build()
} }
} }
std::sort(twitchEmotes.begin(), twitchEmotes.end(),
[](const auto &a, const auto &b) { return std::get<0>(a) < std::get<0>(b); });
auto currentTwitchEmote = twitchEmotes.begin(); auto currentTwitchEmote = twitchEmotes.begin();
// words // words
@ -238,8 +267,8 @@ MessagePtr TwitchMessageBuilder::build()
this->action_ ? MessageColor(this->usernameColor_) : MessageColor(MessageColor::Text); this->action_ ? MessageColor(this->usernameColor_) : MessageColor(MessageColor::Text);
// twitch emote // twitch emote
if (currentTwitchEmote != twitchEmotes.end() && currentTwitchEmote->first == i) { if (currentTwitchEmote != twitchEmotes.end() && std::get<0>(*currentTwitchEmote) == i) {
auto emoteImage = currentTwitchEmote->second; auto emoteImage = std::get<1>(*currentTwitchEmote);
this->emplace<EmoteElement>(emoteImage, MessageElement::TwitchEmote); this->emplace<EmoteElement>(emoteImage, MessageElement::TwitchEmote);
i += split.length() + 1; i += split.length() + 1;
@ -586,9 +615,9 @@ void TwitchMessageBuilder::parseHighlights()
} }
} }
void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcMessage *ircMessage, void TwitchMessageBuilder::appendTwitchEmote(
const QString &emote, const Communi::IrcMessage *ircMessage, const QString &emote,
std::vector<std::pair<long int, EmoteData>> &vec) std::vector<std::tuple<long int, EmoteData, QString>> &vec)
{ {
auto app = getApp(); auto app = getApp();
if (!emote.contains(':')) { if (!emote.contains(':')) {
@ -621,8 +650,8 @@ void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcMessage *ircMessa
QString name = this->originalMessage_.mid(start, end - start + 1); QString name = this->originalMessage_.mid(start, end - start + 1);
vec.push_back( vec.push_back(std::tuple<long int, EmoteData, QString>(
std::pair<long int, EmoteData>(start, app->emotes->twitch.getEmoteById(id, name))); start, app->emotes->twitch.getEmoteById(id, name), name));
} }
} }

View file

@ -51,7 +51,7 @@ private:
void parseHighlights(); void parseHighlights();
void appendTwitchEmote(const Communi::IrcMessage *ircMessage, const QString &emote, void appendTwitchEmote(const Communi::IrcMessage *ircMessage, const QString &emote,
std::vector<std::pair<long, EmoteData>> &vec); std::vector<std::tuple<long, EmoteData, QString> > &vec);
bool tryAppendEmote(QString &emoteString); bool tryAppendEmote(QString &emoteString);
void appendTwitchBadges(); void appendTwitchBadges();

View file

@ -45,7 +45,7 @@ void addPhrasesTab(LayoutCreator<QVBoxLayout> layout)
{ {
EditableModelView *view = EditableModelView *view =
layout.emplace<EditableModelView>(getApp()->ignores->createModel(nullptr)).getElement(); layout.emplace<EditableModelView>(getApp()->ignores->createModel(nullptr)).getElement();
view->setTitles({"Pattern", "Regex", "Case Insensitive", "Replace", "Pattern"}); view->setTitles({"Pattern", "Regex", "Case Sensitive", "Block", "Pattern"});
view->getTableView()->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); view->getTableView()->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
view->getTableView()->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); view->getTableView()->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
@ -56,7 +56,7 @@ void addPhrasesTab(LayoutCreator<QVBoxLayout> layout)
view->addButtonPressed.connect([] { view->addButtonPressed.connect([] {
getApp()->ignores->phrases.appendItem(IgnorePhrase{ getApp()->ignores->phrases.appendItem(IgnorePhrase{
"my phrase", false, false, getSettings()->ignoredPhraseReplace.getValue(), false}); "my phrase", false, false, getSettings()->ignoredPhraseReplace.getValue(), true});
}); });
} }