Better Highlights (#1320)
* Support for user-defined sounds and colors * Make color & sound columns selectable * Add custom row for subscription highlights * Add subscriptions to custom highlights and centrally manage highlight colors * Dynamically update message highlight colors
This commit is contained in:
@@ -18,16 +18,17 @@ HighlightBlacklistUser HighlightBlacklistModel::getItemFromRow(
|
||||
{
|
||||
// key, regex
|
||||
|
||||
return HighlightBlacklistUser{row[0]->data(Qt::DisplayRole).toString(),
|
||||
row[1]->data(Qt::CheckStateRole).toBool()};
|
||||
return HighlightBlacklistUser{
|
||||
row[Column::Pattern]->data(Qt::DisplayRole).toString(),
|
||||
row[Column::UseRegex]->data(Qt::CheckStateRole).toBool()};
|
||||
}
|
||||
|
||||
// turns a row in the model into a vector item
|
||||
void HighlightBlacklistModel::getRowFromItem(const HighlightBlacklistUser &item,
|
||||
std::vector<QStandardItem *> &row)
|
||||
{
|
||||
setStringItem(row[0], item.getPattern());
|
||||
setBoolItem(row[1], item.isRegex());
|
||||
setStringItem(row[Column::Pattern], item.getPattern());
|
||||
setBoolItem(row[Column::UseRegex], item.isRegex());
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -13,6 +13,12 @@ class HighlightBlacklistModel : public SignalVectorModel<HighlightBlacklistUser>
|
||||
{
|
||||
explicit HighlightBlacklistModel(QObject *parent);
|
||||
|
||||
public:
|
||||
enum Column {
|
||||
Pattern = 0,
|
||||
UseRegex = 1,
|
||||
};
|
||||
|
||||
protected:
|
||||
// turn a vector item into a model row
|
||||
virtual HighlightBlacklistUser getItemFromRow(
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace chatterino {
|
||||
|
||||
// commandmodel
|
||||
HighlightModel::HighlightModel(QObject *parent)
|
||||
: SignalVectorModel<HighlightPhrase>(5, parent)
|
||||
: SignalVectorModel<HighlightPhrase>(7, parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -16,52 +16,103 @@ HighlightModel::HighlightModel(QObject *parent)
|
||||
HighlightPhrase HighlightModel::getItemFromRow(
|
||||
std::vector<QStandardItem *> &row, const HighlightPhrase &original)
|
||||
{
|
||||
// key, alert, sound, regex, case-sensitivity
|
||||
// In order for old messages to update their highlight color, we need to
|
||||
// update the highlight color here.
|
||||
auto highlightColor = original.getColor();
|
||||
*highlightColor =
|
||||
row[Column::Color]->data(Qt::DecorationRole).value<QColor>();
|
||||
|
||||
return HighlightPhrase{row[0]->data(Qt::DisplayRole).toString(),
|
||||
row[1]->data(Qt::CheckStateRole).toBool(),
|
||||
row[2]->data(Qt::CheckStateRole).toBool(),
|
||||
row[3]->data(Qt::CheckStateRole).toBool(),
|
||||
row[4]->data(Qt::CheckStateRole).toBool()};
|
||||
return HighlightPhrase{
|
||||
row[Column::Pattern]->data(Qt::DisplayRole).toString(),
|
||||
row[Column::FlashTaskbar]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::PlaySound]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::UseRegex]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::CaseSensitive]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::SoundPath]->data(Qt::UserRole).toString(),
|
||||
highlightColor};
|
||||
}
|
||||
|
||||
// turns a row in the model into a vector item
|
||||
void HighlightModel::getRowFromItem(const HighlightPhrase &item,
|
||||
std::vector<QStandardItem *> &row)
|
||||
{
|
||||
setStringItem(row[0], item.getPattern());
|
||||
setBoolItem(row[1], item.getAlert());
|
||||
setBoolItem(row[2], item.getSound());
|
||||
setBoolItem(row[3], item.isRegex());
|
||||
setBoolItem(row[4], item.isCaseSensitive());
|
||||
setStringItem(row[Column::Pattern], item.getPattern());
|
||||
setBoolItem(row[Column::FlashTaskbar], item.hasAlert());
|
||||
setBoolItem(row[Column::PlaySound], item.hasSound());
|
||||
setBoolItem(row[Column::UseRegex], item.isRegex());
|
||||
setBoolItem(row[Column::CaseSensitive], item.isCaseSensitive());
|
||||
setFilePathItem(row[Column::SoundPath], item.getSoundUrl());
|
||||
setColorItem(row[Column::Color], *item.getColor());
|
||||
}
|
||||
|
||||
void HighlightModel::afterInit()
|
||||
{
|
||||
// Highlight settings for own username
|
||||
std::vector<QStandardItem *> usernameRow = this->createRow();
|
||||
setBoolItem(usernameRow[0], getSettings()->enableSelfHighlight.getValue(),
|
||||
true, false);
|
||||
usernameRow[0]->setData("Your username (automatic)", Qt::DisplayRole);
|
||||
setBoolItem(usernameRow[1],
|
||||
setBoolItem(usernameRow[Column::Pattern],
|
||||
getSettings()->enableSelfHighlight.getValue(), true, false);
|
||||
usernameRow[Column::Pattern]->setData("Your username (automatic)",
|
||||
Qt::DisplayRole);
|
||||
setBoolItem(usernameRow[Column::FlashTaskbar],
|
||||
getSettings()->enableSelfHighlightTaskbar.getValue(), true,
|
||||
false);
|
||||
setBoolItem(usernameRow[2],
|
||||
setBoolItem(usernameRow[Column::PlaySound],
|
||||
getSettings()->enableSelfHighlightSound.getValue(), true,
|
||||
false);
|
||||
usernameRow[3]->setFlags(0);
|
||||
usernameRow[Column::UseRegex]->setFlags(0);
|
||||
usernameRow[Column::CaseSensitive]->setFlags(0);
|
||||
|
||||
QUrl selfSound = QUrl(getSettings()->selfHighlightSoundUrl.getValue());
|
||||
setFilePathItem(usernameRow[Column::SoundPath], selfSound);
|
||||
|
||||
auto selfColor = ColorProvider::instance().color(ColorType::SelfHighlight);
|
||||
setColorItem(usernameRow[Column::Color], *selfColor);
|
||||
|
||||
this->insertCustomRow(usernameRow, 0);
|
||||
|
||||
// Highlight settings for whispers
|
||||
std::vector<QStandardItem *> whisperRow = this->createRow();
|
||||
setBoolItem(whisperRow[0], getSettings()->enableWhisperHighlight.getValue(),
|
||||
true, false);
|
||||
whisperRow[0]->setData("Whispers", Qt::DisplayRole);
|
||||
setBoolItem(whisperRow[1],
|
||||
setBoolItem(whisperRow[Column::Pattern],
|
||||
getSettings()->enableWhisperHighlight.getValue(), true, false);
|
||||
whisperRow[Column::Pattern]->setData("Whispers", Qt::DisplayRole);
|
||||
setBoolItem(whisperRow[Column::FlashTaskbar],
|
||||
getSettings()->enableWhisperHighlightTaskbar.getValue(), true,
|
||||
false);
|
||||
setBoolItem(whisperRow[2],
|
||||
setBoolItem(whisperRow[Column::PlaySound],
|
||||
getSettings()->enableWhisperHighlightSound.getValue(), true,
|
||||
false);
|
||||
whisperRow[3]->setFlags(0);
|
||||
whisperRow[Column::UseRegex]->setFlags(0);
|
||||
whisperRow[Column::CaseSensitive]->setFlags(0);
|
||||
|
||||
QUrl whisperSound =
|
||||
QUrl(getSettings()->whisperHighlightSoundUrl.getValue());
|
||||
setFilePathItem(whisperRow[Column::SoundPath], whisperSound);
|
||||
|
||||
auto whisperColor = ColorProvider::instance().color(ColorType::Whisper);
|
||||
setColorItem(whisperRow[Column::Color], *whisperColor);
|
||||
|
||||
this->insertCustomRow(whisperRow, 1);
|
||||
|
||||
// Highlight settings for subscription messages
|
||||
std::vector<QStandardItem *> subRow = this->createRow();
|
||||
setBoolItem(subRow[Column::Pattern],
|
||||
getSettings()->enableSubHighlight.getValue(), true, false);
|
||||
subRow[Column::Pattern]->setData("Subscriptions", Qt::DisplayRole);
|
||||
setBoolItem(subRow[Column::FlashTaskbar],
|
||||
getSettings()->enableSubHighlightTaskbar.getValue(), true,
|
||||
false);
|
||||
setBoolItem(subRow[Column::PlaySound],
|
||||
getSettings()->enableSubHighlightSound.getValue(), true, false);
|
||||
subRow[Column::UseRegex]->setFlags(0);
|
||||
subRow[Column::CaseSensitive]->setFlags(0);
|
||||
|
||||
QUrl subSound = QUrl(getSettings()->subHighlightSoundUrl.getValue());
|
||||
setFilePathItem(subRow[Column::SoundPath], subSound);
|
||||
|
||||
auto subColor = ColorProvider::instance().color(ColorType::Subscription);
|
||||
setColorItem(subRow[Column::Color], *subColor);
|
||||
|
||||
this->insertCustomRow(subRow, 2);
|
||||
}
|
||||
|
||||
void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||
@@ -70,7 +121,7 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0: {
|
||||
case Column::Pattern: {
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
if (rowIndex == 0)
|
||||
@@ -82,10 +133,14 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||
getSettings()->enableWhisperHighlight.setValue(
|
||||
value.toBool());
|
||||
}
|
||||
else if (rowIndex == 2)
|
||||
{
|
||||
getSettings()->enableSubHighlight.setValue(value.toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: {
|
||||
case Column::FlashTaskbar: {
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
if (rowIndex == 0)
|
||||
@@ -98,10 +153,15 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||
getSettings()->enableWhisperHighlightTaskbar.setValue(
|
||||
value.toBool());
|
||||
}
|
||||
else if (rowIndex == 2)
|
||||
{
|
||||
getSettings()->enableSubHighlightTaskbar.setValue(
|
||||
value.toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
case Column::PlaySound: {
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
if (rowIndex == 0)
|
||||
@@ -114,11 +174,62 @@ void HighlightModel::customRowSetData(const std::vector<QStandardItem *> &row,
|
||||
getSettings()->enableWhisperHighlightSound.setValue(
|
||||
value.toBool());
|
||||
}
|
||||
else if (rowIndex == 2)
|
||||
{
|
||||
getSettings()->enableSubHighlightSound.setValue(
|
||||
value.toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3: {
|
||||
// empty element
|
||||
case Column::UseRegex: {
|
||||
// Regex --> empty
|
||||
}
|
||||
break;
|
||||
case Column::CaseSensitive: {
|
||||
// Case-sensitivity --> empty
|
||||
}
|
||||
break;
|
||||
case Column::SoundPath: {
|
||||
// Custom sound file
|
||||
if (role == Qt::UserRole)
|
||||
{
|
||||
if (rowIndex == 0)
|
||||
{
|
||||
getSettings()->selfHighlightSoundUrl.setValue(
|
||||
value.toString());
|
||||
}
|
||||
else if (rowIndex == 1)
|
||||
{
|
||||
getSettings()->whisperHighlightSoundUrl.setValue(
|
||||
value.toString());
|
||||
}
|
||||
else if (rowIndex == 2)
|
||||
{
|
||||
getSettings()->subHighlightSoundUrl.setValue(
|
||||
value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Column::Color: {
|
||||
// Custom color
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
auto colorName = value.value<QColor>().name(QColor::HexArgb);
|
||||
if (rowIndex == 0)
|
||||
{
|
||||
getSettings()->selfHighlightColor.setValue(colorName);
|
||||
}
|
||||
else if (rowIndex == 1)
|
||||
{
|
||||
getSettings()->whisperHighlightColor.setValue(colorName);
|
||||
}
|
||||
else if (rowIndex == 2)
|
||||
{
|
||||
getSettings()->subHighlightColor.setValue(colorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,18 @@ class HighlightModel : public SignalVectorModel<HighlightPhrase>
|
||||
{
|
||||
explicit HighlightModel(QObject *parent);
|
||||
|
||||
public:
|
||||
// Used here, in HighlightingPage and in UserHighlightModel
|
||||
enum Column {
|
||||
Pattern = 0,
|
||||
FlashTaskbar = 1,
|
||||
PlaySound = 2,
|
||||
UseRegex = 3,
|
||||
CaseSensitive = 4,
|
||||
SoundPath = 5,
|
||||
Color = 6
|
||||
};
|
||||
|
||||
protected:
|
||||
// turn a vector item into a model row
|
||||
virtual HighlightPhrase getItemFromRow(
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "controllers/highlights/HighlightPhrase.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
bool HighlightPhrase::operator==(const HighlightPhrase &other) const
|
||||
{
|
||||
return std::tie(this->pattern_, this->hasSound_, this->hasAlert_,
|
||||
this->isRegex_, this->isCaseSensitive_, this->soundUrl_,
|
||||
this->color_) == std::tie(other.pattern_, other.hasSound_,
|
||||
other.hasAlert_, other.isRegex_,
|
||||
other.isCaseSensitive_,
|
||||
other.soundUrl_, other.color_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new HighlightPhrase.
|
||||
*
|
||||
* Use this constructor when updating an existing HighlightPhrase's color.
|
||||
*/
|
||||
HighlightPhrase::HighlightPhrase(const QString &pattern, bool hasAlert,
|
||||
bool hasSound, bool isRegex,
|
||||
bool isCaseSensitive, const QString &soundUrl,
|
||||
QColor color)
|
||||
: pattern_(pattern)
|
||||
, hasAlert_(hasAlert)
|
||||
, hasSound_(hasSound)
|
||||
, isRegex_(isRegex)
|
||||
, isCaseSensitive_(isCaseSensitive)
|
||||
, soundUrl_(soundUrl)
|
||||
, regex_(isRegex_ ? pattern
|
||||
: "\\b" + QRegularExpression::escape(pattern) + "\\b",
|
||||
QRegularExpression::UseUnicodePropertiesOption |
|
||||
(isCaseSensitive_ ? QRegularExpression::NoPatternOption
|
||||
: QRegularExpression::CaseInsensitiveOption))
|
||||
{
|
||||
this->color_ = std::make_shared<QColor>(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new HighlightPhrase.
|
||||
*
|
||||
* Use this constructor when creating a new HighlightPhrase.
|
||||
*/
|
||||
HighlightPhrase::HighlightPhrase(const QString &pattern, bool hasAlert,
|
||||
bool hasSound, bool isRegex,
|
||||
bool isCaseSensitive, const QString &soundUrl,
|
||||
std::shared_ptr<QColor> color)
|
||||
: pattern_(pattern)
|
||||
, hasAlert_(hasAlert)
|
||||
, hasSound_(hasSound)
|
||||
, isRegex_(isRegex)
|
||||
, isCaseSensitive_(isCaseSensitive)
|
||||
, soundUrl_(soundUrl)
|
||||
, color_(color)
|
||||
, regex_(isRegex_ ? pattern
|
||||
: "\\b" + QRegularExpression::escape(pattern) + "\\b",
|
||||
QRegularExpression::UseUnicodePropertiesOption |
|
||||
(isCaseSensitive_ ? QRegularExpression::NoPatternOption
|
||||
: QRegularExpression::CaseInsensitiveOption))
|
||||
{
|
||||
}
|
||||
|
||||
const QString &HighlightPhrase::getPattern() const
|
||||
{
|
||||
return this->pattern_;
|
||||
}
|
||||
|
||||
bool HighlightPhrase::hasAlert() const
|
||||
{
|
||||
return this->hasAlert_;
|
||||
}
|
||||
|
||||
bool HighlightPhrase::hasSound() const
|
||||
{
|
||||
return this->hasSound_;
|
||||
}
|
||||
|
||||
bool HighlightPhrase::hasCustomSound() const
|
||||
{
|
||||
return !this->soundUrl_.isEmpty();
|
||||
}
|
||||
|
||||
bool HighlightPhrase::isRegex() const
|
||||
{
|
||||
return this->isRegex_;
|
||||
}
|
||||
|
||||
bool HighlightPhrase::isValid() const
|
||||
{
|
||||
return !this->pattern_.isEmpty() && this->regex_.isValid();
|
||||
}
|
||||
|
||||
bool HighlightPhrase::isMatch(const QString &subject) const
|
||||
{
|
||||
return this->isValid() && this->regex_.match(subject).hasMatch();
|
||||
}
|
||||
|
||||
bool HighlightPhrase::isCaseSensitive() const
|
||||
{
|
||||
return this->isCaseSensitive_;
|
||||
}
|
||||
|
||||
const QUrl &HighlightPhrase::getSoundUrl() const
|
||||
{
|
||||
return this->soundUrl_;
|
||||
}
|
||||
|
||||
const std::shared_ptr<QColor> HighlightPhrase::getColor() const
|
||||
{
|
||||
return this->color_;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "providers/colors/ColorProvider.hpp"
|
||||
#include "util/RapidJsonSerializeQString.hpp"
|
||||
#include "util/RapidjsonHelpers.hpp"
|
||||
|
||||
@@ -12,70 +13,64 @@ namespace chatterino {
|
||||
class HighlightPhrase
|
||||
{
|
||||
public:
|
||||
bool operator==(const HighlightPhrase &other) const
|
||||
{
|
||||
return std::tie(this->pattern_, this->sound_, this->alert_,
|
||||
this->isRegex_, this->caseSensitive_) ==
|
||||
std::tie(other.pattern_, other.sound_, other.alert_,
|
||||
other.isRegex_, other.caseSensitive_);
|
||||
}
|
||||
bool operator==(const HighlightPhrase &other) const;
|
||||
|
||||
HighlightPhrase(const QString &pattern, bool alert, bool sound,
|
||||
bool isRegex, bool caseSensitive)
|
||||
: pattern_(pattern)
|
||||
, alert_(alert)
|
||||
, sound_(sound)
|
||||
, isRegex_(isRegex)
|
||||
, caseSensitive_(caseSensitive)
|
||||
, regex_(
|
||||
isRegex_ ? pattern
|
||||
: "\\b" + QRegularExpression::escape(pattern) + "\\b",
|
||||
QRegularExpression::UseUnicodePropertiesOption |
|
||||
(caseSensitive_ ? QRegularExpression::NoPatternOption
|
||||
: QRegularExpression::CaseInsensitiveOption))
|
||||
{
|
||||
}
|
||||
HighlightPhrase(const QString &pattern, bool hasAlert, bool hasSound,
|
||||
bool isRegex, bool isCaseSensitive, const QString &soundUrl,
|
||||
QColor color);
|
||||
|
||||
const QString &getPattern() const
|
||||
{
|
||||
return this->pattern_;
|
||||
}
|
||||
bool getAlert() const
|
||||
{
|
||||
return this->alert_;
|
||||
}
|
||||
bool getSound() const
|
||||
{
|
||||
return this->sound_;
|
||||
}
|
||||
bool isRegex() const
|
||||
{
|
||||
return this->isRegex_;
|
||||
}
|
||||
HighlightPhrase(const QString &pattern, bool hasAlert, bool hasSound,
|
||||
bool isRegex, bool isCaseSensitive, const QString &soundUrl,
|
||||
std::shared_ptr<QColor> color);
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return !this->pattern_.isEmpty() && this->regex_.isValid();
|
||||
}
|
||||
const QString &getPattern() const;
|
||||
bool hasAlert() const;
|
||||
|
||||
bool isMatch(const QString &subject) const
|
||||
{
|
||||
return this->isValid() && this->regex_.match(subject).hasMatch();
|
||||
}
|
||||
/**
|
||||
* @brief Check if this highlight phrase should play a sound when
|
||||
* triggered.
|
||||
*
|
||||
* In distinction from `HighlightPhrase::hasCustomSound`, this method only
|
||||
* checks whether or not ANY sound should be played when the phrase is
|
||||
* triggered.
|
||||
*
|
||||
* To check whether a custom sound is set, use
|
||||
* `HighlightPhrase::hasCustomSound` instead.
|
||||
*
|
||||
* @return true, if this highlight phrase should play a sound when
|
||||
* triggered, false otherwise
|
||||
*/
|
||||
bool hasSound() const;
|
||||
|
||||
bool isCaseSensitive() const
|
||||
{
|
||||
return this->caseSensitive_;
|
||||
}
|
||||
/**
|
||||
* @brief Check if this highlight phrase has a custom sound set.
|
||||
*
|
||||
* Note that this method only checks whether the path to the custom sound
|
||||
* is not empty. It does not check whether the file still exists, is a
|
||||
* sound file, or anything else.
|
||||
*
|
||||
* @return true, if the custom sound file path is not empty, false otherwise
|
||||
*/
|
||||
bool hasCustomSound() const;
|
||||
|
||||
bool isRegex() const;
|
||||
bool isValid() const;
|
||||
bool isMatch(const QString &subject) const;
|
||||
bool isCaseSensitive() const;
|
||||
const QUrl &getSoundUrl() const;
|
||||
const std::shared_ptr<QColor> getColor() const;
|
||||
|
||||
private:
|
||||
QString pattern_;
|
||||
bool alert_;
|
||||
bool sound_;
|
||||
bool hasAlert_;
|
||||
bool hasSound_;
|
||||
bool isRegex_;
|
||||
bool caseSensitive_;
|
||||
bool isCaseSensitive_;
|
||||
QUrl soundUrl_;
|
||||
std::shared_ptr<QColor> color_;
|
||||
QRegularExpression regex_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
namespace pajlada {
|
||||
@@ -88,10 +83,13 @@ struct Serialize<chatterino::HighlightPhrase> {
|
||||
rapidjson::Value ret(rapidjson::kObjectType);
|
||||
|
||||
chatterino::rj::set(ret, "pattern", value.getPattern(), a);
|
||||
chatterino::rj::set(ret, "alert", value.getAlert(), a);
|
||||
chatterino::rj::set(ret, "sound", value.getSound(), a);
|
||||
chatterino::rj::set(ret, "alert", value.hasAlert(), a);
|
||||
chatterino::rj::set(ret, "sound", value.hasSound(), a);
|
||||
chatterino::rj::set(ret, "regex", value.isRegex(), a);
|
||||
chatterino::rj::set(ret, "case", value.isCaseSensitive(), a);
|
||||
chatterino::rj::set(ret, "soundUrl", value.getSoundUrl().toString(), a);
|
||||
chatterino::rj::set(ret, "color",
|
||||
value.getColor()->name(QColor::HexArgb), a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -104,23 +102,30 @@ struct Deserialize<chatterino::HighlightPhrase> {
|
||||
if (!value.IsObject())
|
||||
{
|
||||
return chatterino::HighlightPhrase(QString(), true, false, false,
|
||||
false);
|
||||
false, "", QColor());
|
||||
}
|
||||
|
||||
QString _pattern;
|
||||
bool _alert = true;
|
||||
bool _sound = false;
|
||||
bool _hasAlert = true;
|
||||
bool _hasSound = false;
|
||||
bool _isRegex = false;
|
||||
bool _caseSensitive = false;
|
||||
bool _isCaseSensitive = false;
|
||||
QString _soundUrl;
|
||||
QString encodedColor;
|
||||
|
||||
chatterino::rj::getSafe(value, "pattern", _pattern);
|
||||
chatterino::rj::getSafe(value, "alert", _alert);
|
||||
chatterino::rj::getSafe(value, "sound", _sound);
|
||||
chatterino::rj::getSafe(value, "alert", _hasAlert);
|
||||
chatterino::rj::getSafe(value, "sound", _hasSound);
|
||||
chatterino::rj::getSafe(value, "regex", _isRegex);
|
||||
chatterino::rj::getSafe(value, "case", _caseSensitive);
|
||||
chatterino::rj::getSafe(value, "case", _isCaseSensitive);
|
||||
chatterino::rj::getSafe(value, "soundUrl", _soundUrl);
|
||||
chatterino::rj::getSafe(value, "color", encodedColor);
|
||||
|
||||
return chatterino::HighlightPhrase(_pattern, _alert, _sound, _isRegex,
|
||||
_caseSensitive);
|
||||
auto _color = QColor(encodedColor);
|
||||
|
||||
return chatterino::HighlightPhrase(_pattern, _hasAlert, _hasSound,
|
||||
_isRegex, _isCaseSensitive,
|
||||
_soundUrl, _color);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "UserHighlightModel.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "controllers/highlights/HighlightModel.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "util/StandardItemHelper.hpp"
|
||||
|
||||
@@ -8,7 +9,7 @@ namespace chatterino {
|
||||
|
||||
// commandmodel
|
||||
UserHighlightModel::UserHighlightModel(QObject *parent)
|
||||
: SignalVectorModel<HighlightPhrase>(5, parent)
|
||||
: SignalVectorModel<HighlightPhrase>(7, parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -16,24 +17,37 @@ UserHighlightModel::UserHighlightModel(QObject *parent)
|
||||
HighlightPhrase UserHighlightModel::getItemFromRow(
|
||||
std::vector<QStandardItem *> &row, const HighlightPhrase &original)
|
||||
{
|
||||
// key, regex
|
||||
using Column = HighlightModel::Column;
|
||||
|
||||
return HighlightPhrase{row[0]->data(Qt::DisplayRole).toString(),
|
||||
row[1]->data(Qt::CheckStateRole).toBool(),
|
||||
row[2]->data(Qt::CheckStateRole).toBool(),
|
||||
row[3]->data(Qt::CheckStateRole).toBool(),
|
||||
row[4]->data(Qt::CheckStateRole).toBool()};
|
||||
// In order for old messages to update their highlight color, we need to
|
||||
// update the highlight color here.
|
||||
auto highlightColor = original.getColor();
|
||||
*highlightColor =
|
||||
row[Column::Color]->data(Qt::DecorationRole).value<QColor>();
|
||||
|
||||
return HighlightPhrase{
|
||||
row[Column::Pattern]->data(Qt::DisplayRole).toString(),
|
||||
row[Column::FlashTaskbar]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::PlaySound]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::UseRegex]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::CaseSensitive]->data(Qt::CheckStateRole).toBool(),
|
||||
row[Column::SoundPath]->data(Qt::UserRole).toString(),
|
||||
highlightColor};
|
||||
}
|
||||
|
||||
// row into vector item
|
||||
void UserHighlightModel::getRowFromItem(const HighlightPhrase &item,
|
||||
std::vector<QStandardItem *> &row)
|
||||
{
|
||||
setStringItem(row[0], item.getPattern());
|
||||
setBoolItem(row[1], item.getAlert());
|
||||
setBoolItem(row[2], item.getSound());
|
||||
setBoolItem(row[3], item.isRegex());
|
||||
setBoolItem(row[4], item.isCaseSensitive());
|
||||
using Column = HighlightModel::Column;
|
||||
|
||||
setStringItem(row[Column::Pattern], item.getPattern());
|
||||
setBoolItem(row[Column::FlashTaskbar], item.hasAlert());
|
||||
setBoolItem(row[Column::PlaySound], item.hasSound());
|
||||
setBoolItem(row[Column::UseRegex], item.isRegex());
|
||||
setBoolItem(row[Column::CaseSensitive], item.isCaseSensitive());
|
||||
setFilePathItem(row[Column::SoundPath], item.getSoundUrl());
|
||||
setColorItem(row[Column::Color], *item.getColor());
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
Reference in New Issue
Block a user