This commit is contained in:
fourtf 2018-01-04 02:59:44 +01:00
commit 871195265a
19 changed files with 286 additions and 313 deletions

View file

@ -34,7 +34,7 @@ Building using MSYS2 can be quite easier process. Check out MSYS2 at [msys2.org]
#### Ubuntu 16.04.2 LTS #### Ubuntu 16.04.2 LTS
*most likely works the same for other Debian-like distros* *most likely works the same for other Debian-like distros*
1. install QT Creator `sudo apt-get install qtcreator qtmultimedia5-dev` 1. install QT Creator `sudo apt-get install qtcreator qtmultimedia5-dev`
2. install boost-dev `sudo apt-get install libboost-all-dev` 2. install boost-dev `sudo apt-get install libboost-dev`
3. copy `include/rapidjson` from [rapidjson](https://github.com/miloyip/rapidjson/releases/latest) into the chatterino directory so that the file `<chatterino2 directory>/rapidjson/document.h` exists 3. copy `include/rapidjson` from [rapidjson](https://github.com/miloyip/rapidjson/releases/latest) into the chatterino directory so that the file `<chatterino2 directory>/rapidjson/document.h` exists
4. open `chatterino.pro` with QT Creator and build 4. open `chatterino.pro` with QT Creator and build

View file

@ -126,7 +126,6 @@ HEADERS += \
src/messages/message.hpp \ src/messages/message.hpp \
src/messages/word.hpp \ src/messages/word.hpp \
src/messages/wordpart.hpp \ src/messages/wordpart.hpp \
src/setting.hpp \
src/twitch/emotevalue.hpp \ src/twitch/emotevalue.hpp \
src/widgets/notebook.hpp \ src/widgets/notebook.hpp \
src/widgets/helper/notebookbutton.hpp \ src/widgets/helper/notebookbutton.hpp \
@ -138,7 +137,6 @@ HEADERS += \
src/widgets/helper/signallabel.hpp \ src/widgets/helper/signallabel.hpp \
src/widgets/textinputdialog.hpp \ src/widgets/textinputdialog.hpp \
src/widgets/helper/resizingtextedit.hpp \ src/widgets/helper/resizingtextedit.hpp \
src/settingssnapshot.hpp \
src/messages/limitedqueue.hpp \ src/messages/limitedqueue.hpp \
src/messages/limitedqueuesnapshot.hpp \ src/messages/limitedqueuesnapshot.hpp \
src/messages/messageref.hpp \ src/messages/messageref.hpp \
@ -195,7 +193,9 @@ HEADERS += \
src/singletons/helper/chatterinosetting.hpp \ src/singletons/helper/chatterinosetting.hpp \
src/singletons/resourcemanager.hpp \ src/singletons/resourcemanager.hpp \
src/util/emotemap.hpp \ src/util/emotemap.hpp \
src/singletons/helper/ircmessagehandler.hpp src/singletons/helper/ircmessagehandler.hpp \
src/util/serialize-custom.hpp \
src/messages/highlightphrase.hpp
PRECOMPILED_HEADER = PRECOMPILED_HEADER =

@ -1 +1 @@
Subproject commit 75aca034359fc0e2145908beb459267e8be3d7ca Subproject commit 2fa3adf42da988dc2a34b9b625654aa08e906d4f

View file

@ -35,8 +35,6 @@ Application::Application()
Application::~Application() Application::~Application()
{ {
this->save(); this->save();
chatterino::singletons::SettingManager::getInstance().save();
} }
int Application::run(QApplication &qtApp) int Application::run(QApplication &qtApp)

View file

@ -0,0 +1,78 @@
#pragma once
#include "util/serialize-custom.hpp"
#include <QString>
#include <pajlada/settings/serialize.hpp>
namespace chatterino {
namespace messages {
struct HighlightPhrase {
QString key;
bool sound;
bool alert;
bool operator==(const HighlightPhrase &rhs) const
{
return std::tie(this->key, this->sound, this->alert) ==
std::tie(rhs.key, rhs.sound, rhs.alert);
}
};
} // namespace messages
} // namespace chatterino
namespace pajlada {
namespace Settings {
template <>
struct Serialize<chatterino::messages::HighlightPhrase> {
static rapidjson::Value get(const chatterino::messages::HighlightPhrase &value,
rapidjson::Document::AllocatorType &a)
{
rapidjson::Value ret(rapidjson::kObjectType);
AddMember(ret, "key", value.key, a);
AddMember(ret, "alert", value.alert, a);
AddMember(ret, "sound", value.sound, a);
return ret;
}
};
template <>
struct Deserialize<chatterino::messages::HighlightPhrase> {
static chatterino::messages::HighlightPhrase get(const rapidjson::Value &value)
{
chatterino::messages::HighlightPhrase ret;
if (!value.IsObject()) {
return ret;
}
if (value.HasMember("key")) {
const rapidjson::Value &key = value["key"];
if (key.IsString()) {
ret.key = key.GetString();
}
}
if (value.HasMember("alert")) {
const rapidjson::Value &alert = value["alert"];
if (alert.IsBool()) {
ret.alert = alert.GetBool();
}
}
if (value.HasMember("sound")) {
const rapidjson::Value &sound = value["sound"];
if (sound.IsBool()) {
ret.sound = sound.GetBool();
}
}
return ret;
}
};
} // namespace Settings
} // namespace pajlada

View file

@ -67,7 +67,7 @@ QSize Word::getSize(float scale) const
const int mediumTextLineHeight = const int mediumTextLineHeight =
singletons::FontManager::getInstance().getFontMetrics(this->font, scale).height(); singletons::FontManager::getInstance().getFontMetrics(this->font, scale).height();
const qreal emoteScale = const qreal emoteScale =
singletons::SettingManager::getInstance().emoteScale.get() * scale; singletons::SettingManager::getInstance().emoteScale.getValue() * scale;
const bool scaleEmotesByLineHeight = const bool scaleEmotesByLineHeight =
singletons::SettingManager::getInstance().scaleEmotesByLineHeight; singletons::SettingManager::getInstance().scaleEmotesByLineHeight;

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "singletons/fontmanager.hpp"
#include "messages/lazyloadedimage.hpp" #include "messages/lazyloadedimage.hpp"
#include "messages/link.hpp" #include "messages/link.hpp"
#include "messages/messagecolor.hpp" #include "messages/messagecolor.hpp"
#include "singletons/fontmanager.hpp"
//#include "wordflags.hpp" //#include "wordflags.hpp"
#include <stdint.h> #include <stdint.h>
@ -96,8 +96,8 @@ public:
explicit Word(LazyLoadedImage *_image, Flags getFlags, const QString &copytext, explicit Word(LazyLoadedImage *_image, Flags getFlags, const QString &copytext,
const QString &tooltip, const Link &getLink = Link()); const QString &tooltip, const Link &getLink = Link());
explicit Word(const QString &_text, Flags getFlags, const MessageColor &textColor, explicit Word(const QString &_text, Flags getFlags, const MessageColor &textColor,
singletons::FontManager::Type font, const QString &copytext, const QString &tooltip, singletons::FontManager::Type font, const QString &copytext,
const Link &getLink = Link()); const QString &tooltip, const Link &getLink = Link());
bool isImage() const; bool isImage() const;
bool isText() const; bool isText() const;

View file

@ -1,85 +0,0 @@
#pragma once
#include <QSettings>
#include <QString>
#include <boost/signals2.hpp>
namespace chatterino {
class BaseSetting
{
public:
BaseSetting(const QString &_name)
: name(_name)
{
}
virtual QVariant getVariant() = 0;
virtual void setVariant(QVariant value) = 0;
const QString &getName() const
{
return this->name;
}
private:
QString name;
};
template <typename T>
class Setting : public BaseSetting
{
public:
Setting(std::vector<std::reference_wrapper<BaseSetting>> &settingItems, const QString &_name,
const T &defaultValue)
: BaseSetting(_name)
, value(defaultValue)
{
settingItems.push_back(*this);
}
const T &get() const
{
return this->value;
}
T &getnonConst()
{
return this->value;
}
void set(const T &newValue)
{
if (this->value != newValue) {
this->value = newValue;
valueChanged(newValue);
}
}
virtual QVariant getVariant() final
{
return QVariant::fromValue(this->value);
}
virtual void setVariant(QVariant newValue) final
{
if (newValue.isValid()) {
assert(newValue.canConvert<T>());
set(newValue.value<T>());
}
}
void insertMap(QString id, bool sound, bool task)
{
QPair<bool, bool> pair(sound, task);
this->value.insert(id, pair);
}
boost::signals2::signal<void(const T &newValue)> valueChanged;
private:
T value;
};
} // namespace chatterino

View file

@ -1,38 +0,0 @@
#pragma once
#include "setting.hpp"
namespace chatterino {
struct SettingsSnapshot {
public:
SettingsSnapshot()
{
}
void addItem(std::reference_wrapper<BaseSetting> setting, const QVariant &value)
{
this->items.push_back(
std::pair<std::reference_wrapper<BaseSetting>, QVariant>(setting.get(), value));
}
void addMapItem(QString string, QPair<bool, bool> pair)
{
QMap<QString, QPair<bool, bool>> map;
this->mapItems.insert(string, pair);
}
void apply()
{
for (auto &item : this->items) {
item.first.get().setVariant(item.second);
}
}
QMap<QString, QPair<bool, bool>> mapItems;
private:
std::vector<std::pair<std::reference_wrapper<BaseSetting>, QVariant>> items;
};
} // namespace chatterino

View file

@ -8,6 +8,12 @@ template <typename Type>
class ChatterinoSetting : public pajlada::Settings::Setting<Type> class ChatterinoSetting : public pajlada::Settings::Setting<Type>
{ {
public: public:
ChatterinoSetting(const std::string &_path)
: pajlada::Settings::Setting<Type>(_path)
{
_registerSetting(this->data);
}
ChatterinoSetting(const std::string &_path, const Type &_defaultValue) ChatterinoSetting(const std::string &_path, const Type &_defaultValue)
: pajlada::Settings::Setting<Type>(_path, _defaultValue) : pajlada::Settings::Setting<Type>(_path, _defaultValue)
{ {

View file

@ -200,14 +200,19 @@ void IrcManager::disconnect()
void IrcManager::sendMessage(const QString &channelName, QString message) void IrcManager::sendMessage(const QString &channelName, QString message)
{ {
QString trimmedMessage = message.trimmed();
if (trimmedMessage.isEmpty()) {
return;
}
this->connectionMutex.lock(); this->connectionMutex.lock();
static int i = 0; static int i = 0;
if (this->writeConnection) { if (this->writeConnection) {
if (singletons::SettingManager::getInstance().allowDuplicateMessages && (++i % 2) == 0) { if (singletons::SettingManager::getInstance().allowDuplicateMessages && (++i % 2) == 0) {
message.append(this->messageSuffix); trimmedMessage.append(this->messageSuffix);
} }
this->writeConnection->sendRaw("PRIVMSG #" + channelName + " :" + message); this->writeConnection->sendRaw("PRIVMSG #" + channelName + " :" + trimmedMessage);
} }
this->connectionMutex.unlock(); this->connectionMutex.unlock();
@ -399,5 +404,5 @@ Communi::IrcConnection *IrcManager::getReadConnection()
return this->readConnection.get(); return this->readConnection.get();
} }
} // namespace singletons
} // namespace chatterino } // namespace chatterino
}

View file

@ -18,15 +18,7 @@ void _registerSetting(std::weak_ptr<pajlada::Settings::ISettingData> setting)
} }
SettingManager::SettingManager() SettingManager::SettingManager()
: streamlinkPath("/behaviour/streamlink/path", "") : snapshot(nullptr)
, preferredQuality("/behaviour/streamlink/quality", "Choose")
, emoteScale(this->settingsItems, "emoteScale", 1.0)
, pathHighlightSound(this->settingsItems, "pathHighlightSound", "qrc:/sounds/ping2.wav")
, highlightProperties(this->settingsItems, "highlightProperties",
QMap<QString, QPair<bool, bool>>())
, highlightUserBlacklist(this->settingsItems, "highlightUserBlacklist", "")
, snapshot(nullptr)
, settings(Path::getAppdataPath() + "settings.ini", QSettings::IniFormat)
{ {
this->wordMaskListener.addSetting(this->showTimestamps); this->wordMaskListener.addSetting(this->showTimestamps);
this->wordMaskListener.addSetting(this->showTimestampSeconds); this->wordMaskListener.addSetting(this->showTimestampSeconds);
@ -40,49 +32,6 @@ SettingManager::SettingManager()
}; };
} }
void SettingManager::save()
{
for (auto &item : this->settingsItems) {
if (item.get().getName() != "highlightProperties") {
this->settings.setValue(item.get().getName(), item.get().getVariant());
} else {
this->settings.beginGroup("Highlights");
QStringList list = highlightProperties.get().keys();
list.removeAll("");
this->settings.remove("");
for (auto string : list) {
this->settings.beginGroup(string);
this->settings.setValue("highlightSound",
highlightProperties.get().value(string).first);
this->settings.setValue("highlightTask",
highlightProperties.get().value(string).second);
this->settings.endGroup();
}
this->settings.endGroup();
}
}
}
void SettingManager::load()
{
for (auto &item : this->settingsItems) {
if (item.get().getName() != "highlightProperties") {
item.get().setVariant(this->settings.value(item.get().getName()));
} else {
this->settings.beginGroup("Highlights");
QStringList list = this->settings.childGroups();
for (auto string : list) {
this->settings.beginGroup(string);
highlightProperties.insertMap(string,
this->settings.value("highlightSound").toBool(),
this->settings.value("highlightTask").toBool());
this->settings.endGroup();
}
this->settings.endGroup();
}
}
}
Word::Flags SettingManager::getWordTypeMask() Word::Flags SettingManager::getWordTypeMask()
{ {
return this->wordTypeMask; return this->wordTypeMask;
@ -93,9 +42,10 @@ bool SettingManager::isIgnoredEmote(const QString &)
return false; return false;
} }
QSettings &SettingManager::getQSettings() void SettingManager::load()
{ {
return this->settings; // Just to make sure the singleton is initialized
debug::Log(".");
} }
void SettingManager::updateWordTypeMask() void SettingManager::updateWordTypeMask()
@ -184,5 +134,5 @@ void SettingManager::recallSnapshot()
} }
} }
} // namespace singletons
} // namespace chatterino } // namespace chatterino
}

View file

@ -1,10 +1,9 @@
#pragma once #pragma once
#include "messages/highlightphrase.hpp"
#include "messages/word.hpp" #include "messages/word.hpp"
#include "setting.hpp"
#include "singletons/helper/chatterinosetting.hpp" #include "singletons/helper/chatterinosetting.hpp"
#include <QSettings>
#include <pajlada/settings/setting.hpp> #include <pajlada/settings/setting.hpp>
#include <pajlada/settings/settinglistener.hpp> #include <pajlada/settings/settinglistener.hpp>
@ -19,14 +18,14 @@ class SettingManager : public QObject
using BoolSetting = ChatterinoSetting<bool>; using BoolSetting = ChatterinoSetting<bool>;
using FloatSetting = ChatterinoSetting<float>; using FloatSetting = ChatterinoSetting<float>;
using StringSetting = ChatterinoSetting<std::string>;
using QStringSetting = ChatterinoSetting<QString>;
public: public:
void load();
void save();
messages::Word::Flags getWordTypeMask(); messages::Word::Flags getWordTypeMask();
bool isIgnoredEmote(const QString &emote); bool isIgnoredEmote(const QString &emote);
QSettings &getQSettings();
void load();
/// Appearance /// Appearance
BoolSetting showTimestamps = {"/appearance/messages/showTimestamps", true}; BoolSetting showTimestamps = {"/appearance/messages/showTimestamps", true};
@ -47,6 +46,8 @@ public:
BoolSetting allowDuplicateMessages = {"/behaviour/allowDuplicateMessages", true}; BoolSetting allowDuplicateMessages = {"/behaviour/allowDuplicateMessages", true};
BoolSetting mentionUsersWithAt = {"/behaviour/mentionUsersWithAt", false}; BoolSetting mentionUsersWithAt = {"/behaviour/mentionUsersWithAt", false};
FloatSetting mouseScrollMultiplier = {"/behaviour/mouseScrollMultiplier", 1.0}; FloatSetting mouseScrollMultiplier = {"/behaviour/mouseScrollMultiplier", 1.0};
StringSetting streamlinkPath = {"/behaviour/streamlink/path", ""};
StringSetting preferredQuality = {"/behaviour/streamlink/quality", "Choose"};
/// Commands /// Commands
BoolSetting allowCommandsAtEnd = {"/commands/allowCommandsAtEnd", false}; BoolSetting allowCommandsAtEnd = {"/commands/allowCommandsAtEnd", false};
@ -58,6 +59,7 @@ public:
BoolSetting enableFfzEmotes = {"/emotes/enableFFZEmotes", true}; BoolSetting enableFfzEmotes = {"/emotes/enableFFZEmotes", true};
BoolSetting enableEmojis = {"/emotes/enableEmojis", true}; BoolSetting enableEmojis = {"/emotes/enableEmojis", true};
BoolSetting enableGifAnimations = {"/emotes/enableGifAnimations", true}; BoolSetting enableGifAnimations = {"/emotes/enableGifAnimations", true};
FloatSetting emoteScale = {"/emotes/scale", 1.f};
/// Links /// Links
BoolSetting linksDoubleClickOnly = {"/links/doubleClickToOpen", false}; BoolSetting linksDoubleClickOnly = {"/links/doubleClickToOpen", false};
@ -69,14 +71,12 @@ public:
BoolSetting enableHighlightTaskbar = {"/highlighting/enableTaskbarFlashing", true}; BoolSetting enableHighlightTaskbar = {"/highlighting/enableTaskbarFlashing", true};
BoolSetting customHighlightSound = {"/highlighting/useCustomSound", false}; BoolSetting customHighlightSound = {"/highlighting/useCustomSound", false};
pajlada::Settings::Setting<std::string> streamlinkPath; ChatterinoSetting<std::vector<messages::HighlightPhrase>> highlightProperties = {
pajlada::Settings::Setting<std::string> preferredQuality; "/highlighting/highlights"};
Setting<float> emoteScale; QStringSetting pathHighlightSound = {"/highlighting/highlightSoundPath",
"qrc:/sounds/ping2.wav"};
Setting<QString> pathHighlightSound; QStringSetting highlightUserBlacklist = {"/highlighting/blacklistedUsers", ""};
Setting<QMap<QString, QPair<bool, bool>>> highlightProperties;
Setting<QString> highlightUserBlacklist;
BoolSetting highlightAlwaysPlaySound = {"/highlighting/alwaysPlaySound", false}; BoolSetting highlightAlwaysPlaySound = {"/highlighting/alwaysPlaySound", false};
@ -100,12 +100,10 @@ private:
SettingManager(); SettingManager();
QSettings settings;
std::vector<std::reference_wrapper<BaseSetting>> settingsItems;
messages::Word::Flags wordTypeMask = messages::Word::Default; messages::Word::Flags wordTypeMask = messages::Word::Default;
pajlada::Settings::SettingListener wordMaskListener; pajlada::Settings::SettingListener wordMaskListener;
}; };
} // namespace singletons
} // namespace chatterino } // namespace chatterino
}

View file

@ -396,7 +396,7 @@ void TwitchMessageBuilder::parseHighlights()
// update the media player url if necessary // update the media player url if necessary
QUrl highlightSoundUrl; QUrl highlightSoundUrl;
if (settings.customHighlightSound) { if (settings.customHighlightSound) {
highlightSoundUrl = QUrl(settings.pathHighlightSound.get()); highlightSoundUrl = QUrl(settings.pathHighlightSound.getValue());
} else { } else {
highlightSoundUrl = QUrl("qrc:/sounds/ping2.wav"); highlightSoundUrl = QUrl("qrc:/sounds/ping2.wav");
} }
@ -407,35 +407,18 @@ void TwitchMessageBuilder::parseHighlights()
currentPlayerUrl = highlightSoundUrl; currentPlayerUrl = highlightSoundUrl;
} }
struct Highlight {
Highlight(const QString &_target, bool _sound, bool _alert)
: target(_target)
, sound(_sound)
, alert(_alert)
{
}
QString target;
bool sound;
bool alert;
};
QStringList blackList = QStringList blackList =
settings.highlightUserBlacklist.get().split("\n", QString::SkipEmptyParts); settings.highlightUserBlacklist.getValue().split("\n", QString::SkipEmptyParts);
// TODO: This vector should only be rebuilt upon highlights being changed // TODO: This vector should only be rebuilt upon highlights being changed
std::vector<Highlight> activeHighlights; auto activeHighlights = settings.highlightProperties.getValue();
if (settings.enableHighlightsSelf && currentUsername.size() > 0) { if (settings.enableHighlightsSelf && currentUsername.size() > 0) {
activeHighlights.emplace_back(currentUsername, settings.enableHighlightSound, messages::HighlightPhrase selfHighlight;
settings.enableHighlightTaskbar); selfHighlight.key = currentUsername;
} selfHighlight.sound = settings.enableHighlightSound;
selfHighlight.alert = settings.enableHighlightTaskbar;
const auto &highlightProperties = settings.highlightProperties.get(); activeHighlights.emplace_back(std::move(selfHighlight));
for (auto it = highlightProperties.begin(); it != highlightProperties.end(); ++it) {
auto properties = it.value();
activeHighlights.emplace_back(it.key(), properties.first, properties.second);
} }
bool doHighlight = false; bool doHighlight = false;
@ -445,10 +428,10 @@ void TwitchMessageBuilder::parseHighlights()
bool hasFocus = (QApplication::focusWidget() != nullptr); bool hasFocus = (QApplication::focusWidget() != nullptr);
if (!blackList.contains(this->ircMessage->nick(), Qt::CaseInsensitive)) { if (!blackList.contains(this->ircMessage->nick(), Qt::CaseInsensitive)) {
for (const Highlight &highlight : activeHighlights) { for (const messages::HighlightPhrase &highlight : activeHighlights) {
if (this->originalMessage.contains(highlight.target, Qt::CaseInsensitive)) { if (this->originalMessage.contains(highlight.key, Qt::CaseInsensitive)) {
debug::Log("Highlight because {} contains {}", this->originalMessage, debug::Log("Highlight because {} contains {}", this->originalMessage,
highlight.target); highlight.key);
doHighlight = true; doHighlight = true;
if (highlight.sound) { if (highlight.sound) {

View file

@ -0,0 +1,32 @@
#pragma once
#include <QString>
#include <pajlada/settings/serialize.hpp>
namespace pajlada {
namespace Settings {
template <>
struct Serialize<QString> {
static rapidjson::Value get(const QString &value, rapidjson::Document::AllocatorType &a)
{
rapidjson::Value ret(qPrintable(value), a);
return ret;
}
};
template <>
struct Deserialize<QString> {
static QString get(const rapidjson::Value &value)
{
if (!value.IsString()) {
throw std::runtime_error("Deserialized rapidjson::Value is not a string");
}
return value.GetString();
}
};
} // namespace Settings
} // namespace pajlada

View file

@ -95,18 +95,18 @@ AccountPopupWidget::AccountPopupWidget(std::shared_ptr<Channel> _channel)
}); });
QObject::connect(this->ui->disableHighlights, &QPushButton::clicked, this, [=, &settings]() { QObject::connect(this->ui->disableHighlights, &QPushButton::clicked, this, [=, &settings]() {
QString str = settings.highlightUserBlacklist.getnonConst(); QString str = settings.highlightUserBlacklist;
str.append(this->ui->lblUsername->text() + "\n"); str.append(this->ui->lblUsername->text() + "\n");
settings.highlightUserBlacklist.set(str); settings.highlightUserBlacklist = str;
this->ui->disableHighlights->hide(); this->ui->disableHighlights->hide();
this->ui->enableHighlights->show(); this->ui->enableHighlights->show();
}); });
QObject::connect(this->ui->enableHighlights, &QPushButton::clicked, this, [=, &settings]() { QObject::connect(this->ui->enableHighlights, &QPushButton::clicked, this, [=, &settings]() {
QString str = settings.highlightUserBlacklist.getnonConst(); QString str = settings.highlightUserBlacklist;
QStringList list = str.split("\n"); QStringList list = str.split("\n");
list.removeAll(this->ui->lblUsername->text()); list.removeAll(this->ui->lblUsername->text());
settings.highlightUserBlacklist.set(list.join("\n")); settings.highlightUserBlacklist = list.join("\n");
this->ui->enableHighlights->hide(); this->ui->enableHighlights->hide();
this->ui->disableHighlights->show(); this->ui->disableHighlights->show();
}); });
@ -267,8 +267,7 @@ void AccountPopupWidget::showEvent(QShowEvent *)
this->updateButtons(this->ui->ownerLayout, false); this->updateButtons(this->ui->ownerLayout, false);
} }
QString blacklisted = QString blacklisted = singletons::SettingManager::getInstance().highlightUserBlacklist;
singletons::SettingManager::getInstance().highlightUserBlacklist.getnonConst();
QStringList list = blacklisted.split("\n", QString::SkipEmptyParts); QStringList list = blacklisted.split("\n", QString::SkipEmptyParts);
if (list.contains(this->ui->lblUsername->text(), Qt::CaseInsensitive)) { if (list.contains(this->ui->lblUsername->text(), Qt::CaseInsensitive)) {
this->ui->disableHighlights->hide(); this->ui->disableHighlights->hide();

View file

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "basewidget.hpp" #include "basewidget.hpp"
#include "util/concurrentmap.hpp"
#include "twitch/twitchchannel.hpp" #include "twitch/twitchchannel.hpp"
#include "util/concurrentmap.hpp"
#include <QPushButton> #include <QPushButton>
#include <QWidget> #include <QWidget>

View file

@ -418,9 +418,11 @@ QVBoxLayout *SettingsDialog::createHighlightingTab()
auto highlights = new QListWidget(); auto highlights = new QListWidget();
auto highlightUserBlacklist = new QTextEdit(); auto highlightUserBlacklist = new QTextEdit();
globalHighlights = highlights; globalHighlights = highlights;
QStringList items = settings.highlightProperties.get().keys(); const auto highlightProperties = settings.highlightProperties.getValue();
highlights->addItems(items); for (const auto &highlightProperty : highlightProperties) {
highlightUserBlacklist->setText(settings.highlightUserBlacklist.getnonConst()); highlights->addItem(highlightProperty.key);
}
highlightUserBlacklist->setText(settings.highlightUserBlacklist);
auto highlightTab = new QTabWidget(); auto highlightTab = new QTabWidget();
auto customSound = new QHBoxLayout(); auto customSound = new QHBoxLayout();
auto soundForm = new QFormLayout(); auto soundForm = new QFormLayout();
@ -437,7 +439,7 @@ QVBoxLayout *SettingsDialog::createHighlightingTab()
QObject::connect(selectBtn, &QPushButton::clicked, this, [&settings, this] { QObject::connect(selectBtn, &QPushButton::clicked, this, [&settings, this] {
auto fileName = QFileDialog::getOpenFileName(this, tr("Open Sound"), "", auto fileName = QFileDialog::getOpenFileName(this, tr("Open Sound"), "",
tr("Audio Files (*.mp3 *.wav)")); tr("Audio Files (*.mp3 *.wav)"));
settings.pathHighlightSound.set(fileName); settings.pathHighlightSound = fileName;
}); });
customSound->addWidget(selectBtn); customSound->addWidget(selectBtn);
} }
@ -450,6 +452,7 @@ QVBoxLayout *SettingsDialog::createHighlightingTab()
auto editBtn = new QPushButton("Edit"); auto editBtn = new QPushButton("Edit");
auto delBtn = new QPushButton("Remove"); auto delBtn = new QPushButton("Remove");
// Open "Add new highlight" dialog
QObject::connect(addBtn, &QPushButton::clicked, this, [highlights, this, &settings] { QObject::connect(addBtn, &QPushButton::clicked, this, [highlights, this, &settings] {
auto show = new QWidget(); auto show = new QWidget();
auto box = new QBoxLayout(QBoxLayout::TopToBottom); auto box = new QBoxLayout(QBoxLayout::TopToBottom);
@ -460,11 +463,23 @@ QVBoxLayout *SettingsDialog::createHighlightingTab()
auto sound = new QCheckBox("Play sound"); auto sound = new QCheckBox("Play sound");
auto task = new QCheckBox("Flash taskbar"); auto task = new QCheckBox("Flash taskbar");
// Save highlight
QObject::connect(add, &QPushButton::clicked, this, [=, &settings] { QObject::connect(add, &QPushButton::clicked, this, [=, &settings] {
if (edit->text().length()) { if (edit->text().length()) {
highlights->addItem(edit->text()); QString highlightKey = edit->text();
settings.highlightProperties.insertMap(edit->text(), sound->isChecked(), highlights->addItem(highlightKey);
task->isChecked());
auto properties = settings.highlightProperties.getValue();
messages::HighlightPhrase newHighlightProperty;
newHighlightProperty.key = highlightKey;
newHighlightProperty.sound = sound->isChecked();
newHighlightProperty.alert = task->isChecked();
properties.push_back(newHighlightProperty);
settings.highlightProperties = properties;
show->close(); show->close();
} }
}); });
@ -475,50 +490,103 @@ QVBoxLayout *SettingsDialog::createHighlightingTab()
show->setLayout(box); show->setLayout(box);
show->show(); show->show();
}); });
// Open "Edit selected highlight" dialog
QObject::connect(editBtn, &QPushButton::clicked, this, [highlights, this, &settings] { QObject::connect(editBtn, &QPushButton::clicked, this, [highlights, this, &settings] {
if (!highlights->selectedItems().isEmpty()) { if (highlights->selectedItems().isEmpty()) {
// No item selected
return;
}
QListWidgetItem *selectedHighlight = highlights->selectedItems().first();
QString highlightKey = selectedHighlight->text();
auto properties = settings.highlightProperties.getValue();
auto highlightIt = std::find_if(properties.begin(), properties.end(),
[highlightKey](const auto &highlight) {
return highlight.key == highlightKey; //
});
if (highlightIt == properties.end()) {
debug::Log("Unable to find highlight key {} in highlight properties. "
"This is weird",
highlightKey);
return;
}
messages::HighlightPhrase &selectedSetting = *highlightIt;
auto show = new QWidget(); auto show = new QWidget();
auto box = new QBoxLayout(QBoxLayout::TopToBottom); auto box = new QBoxLayout(QBoxLayout::TopToBottom);
auto edit = new QLineEdit(); auto edit = new QLineEdit(highlightKey);
edit->setText(highlights->selectedItems().first()->text()); auto apply = new QPushButton("Apply");
auto add = new QPushButton("Apply");
auto sound = new QCheckBox("Play sound"); auto sound = new QCheckBox("Play sound");
sound->setChecked(selectedSetting.sound);
auto task = new QCheckBox("Flash taskbar"); auto task = new QCheckBox("Flash taskbar");
task->setChecked(selectedSetting.alert);
QObject::connect(add, &QPushButton::clicked, this, [=, &settings] { // Apply edited changes
if (edit->text().length()) { QObject::connect(apply, &QPushButton::clicked, this, [=, &settings] {
settings.highlightProperties.getnonConst().remove( QString newHighlightKey = edit->text();
highlights->selectedItems().first()->text());
delete highlights->selectedItems().first(); if (newHighlightKey.length() == 0) {
highlights->addItem(edit->text()); return;
settings.highlightProperties.insertMap(edit->text(), sound->isChecked(),
task->isChecked());
show->close();
} }
auto properties = settings.highlightProperties.getValue();
auto highlightIt =
std::find_if(properties.begin(), properties.end(), [=](const auto &highlight) {
return highlight.key == highlightKey; //
}); });
if (highlightIt == properties.end()) {
debug::Log("Unable to find highlight key {} in highlight properties. "
"This is weird",
highlightKey);
return;
}
auto &highlightProperty = *highlightIt;
highlightProperty.key = newHighlightKey;
highlightProperty.sound = sound->isCheckable();
highlightProperty.alert = task->isCheckable();
settings.highlightProperties = properties;
selectedHighlight->setText(newHighlightKey);
show->close();
});
box->addWidget(edit); box->addWidget(edit);
box->addWidget(add); box->addWidget(apply);
box->addWidget(sound); box->addWidget(sound);
sound->setChecked(settings.highlightProperties.get()
.value(highlights->selectedItems().first()->text())
.first);
box->addWidget(task); box->addWidget(task);
task->setChecked(settings.highlightProperties.get()
.value(highlights->selectedItems().first()->text())
.second);
show->setLayout(box); show->setLayout(box);
show->show(); show->show();
}
}); });
// Delete selected highlight
QObject::connect(delBtn, &QPushButton::clicked, this, [highlights, &settings] { QObject::connect(delBtn, &QPushButton::clicked, this, [highlights, &settings] {
if (!highlights->selectedItems().isEmpty()) { if (highlights->selectedItems().isEmpty()) {
settings.highlightProperties.getnonConst().remove( // No highlight selected
highlights->selectedItems().first()->text()); return;
delete highlights->selectedItems().first();
} }
QListWidgetItem *selectedHighlight = highlights->selectedItems().first();
QString highlightKey = selectedHighlight->text();
auto properties = settings.highlightProperties.getValue();
properties.erase(std::remove_if(properties.begin(), properties.end(),
[highlightKey](const auto &highlight) {
return highlight.key == highlightKey; //
}),
properties.end());
settings.highlightProperties = properties;
delete selectedHighlight;
}); });
layout->addLayout(soundForm); layout->addLayout(soundForm);
layout->addWidget( layout->addWidget(
createCheckbox("Always play highlight sound (Even if Chatterino is focused)", createCheckbox("Always play highlight sound (Even if Chatterino is focused)",
@ -549,11 +617,12 @@ QVBoxLayout *SettingsDialog::createHighlightingTab()
QStringList list = QStringList list =
highlightUserBlacklist->toPlainText().split("\n", QString::SkipEmptyParts); highlightUserBlacklist->toPlainText().split("\n", QString::SkipEmptyParts);
list.removeDuplicates(); list.removeDuplicates();
settings.highlightUserBlacklist.set(list.join("\n") + "\n"); settings.highlightUserBlacklist = list.join("\n") + "\n";
}); });
settings.highlightUserBlacklist.valueChanged.connect( settings.highlightUserBlacklist.connect([=](const QString &str, auto) {
[=](const QString &str) { highlightUserBlacklist->setPlainText(str); }); highlightUserBlacklist->setPlainText(str); //
});
return layout; return layout;
} }
@ -671,20 +740,6 @@ QVBoxLayout *SettingsDialog::createTabLayout()
return layout; return layout;
} }
QCheckBox *SettingsDialog::createCheckbox(const QString &title, Setting<bool> &setting)
{
auto checkbox = new QCheckBox(title);
// Set checkbox initial state
checkbox->setChecked(setting.get());
QObject::connect(checkbox, &QCheckBox::toggled, this, [&setting](bool state) {
setting.set(state); //
});
return checkbox;
}
QCheckBox *SettingsDialog::createCheckbox(const QString &title, QCheckBox *SettingsDialog::createCheckbox(const QString &title,
pajlada::Settings::Setting<bool> &setting) pajlada::Settings::Setting<bool> &setting)
{ {
@ -765,13 +820,6 @@ void SettingsDialog::cancelButtonClicked()
settings.recallSnapshot(); settings.recallSnapshot();
QStringList list = settings.highlightProperties.get().keys();
list.removeDuplicates();
while (globalHighlights->count() > 0) {
delete globalHighlights->takeItem(0);
}
globalHighlights->addItems(list);
this->close(); this->close();
} }

View file

@ -88,7 +88,6 @@ private:
/// Widget creation helpers /// Widget creation helpers
QVBoxLayout *createTabLayout(); QVBoxLayout *createTabLayout();
QCheckBox *createCheckbox(const QString &title, Setting<bool> &setting);
QCheckBox *createCheckbox(const QString &title, pajlada::Settings::Setting<bool> &setting); QCheckBox *createCheckbox(const QString &title, pajlada::Settings::Setting<bool> &setting);
QHBoxLayout *createCombobox(const QString &title, pajlada::Settings::Setting<int> &setting, QHBoxLayout *createCombobox(const QString &title, pajlada::Settings::Setting<int> &setting,
QStringList items, QStringList items,