improved the highlights settings page

This commit is contained in:
fourtf 2018-04-26 23:07:02 +02:00
parent ea7fcf260c
commit e23ce31e05
8 changed files with 528 additions and 449 deletions

View file

@ -311,7 +311,8 @@ HEADERS += \
src/widgets/attachedwindow.hpp \
src/widgets/settingspages/externaltoolspage.hpp \
src/util/removescrollareabackground.hpp \
src/util/assertinguithread.h
src/util/assertinguithread.h \
src/util/standarditemhelper.hpp
RESOURCES += \
resources/resources.qrc

View file

@ -0,0 +1,33 @@
#pragma once
#include <QStandardItem>
namespace chatterino {
namespace util {
QStandardItem *boolItem(bool value, bool userCheckable = true, bool selectable = true)
{
auto *item = new QStandardItem();
item->setFlags((Qt::ItemFlags)(Qt::ItemIsEnabled | (selectable ? Qt::ItemIsSelectable : 0) |
(userCheckable ? Qt::ItemIsUserCheckable : 0)));
item->setCheckState(value ? Qt::Checked : Qt::Unchecked);
return item;
}
QStandardItem *stringItem(const QString &value, bool editable = true, bool selectable = true)
{
auto *item = new QStandardItem(value);
item->setFlags((Qt::ItemFlags)(Qt::ItemIsEnabled | (selectable ? Qt::ItemIsSelectable : 0) |
(editable ? (Qt::ItemIsEditable) : 0)));
return item;
}
QStandardItem *emptyItem()
{
auto *item = new QStandardItem();
item->setFlags((Qt::ItemFlags)0);
return item;
}
} // namespace util
} // namespace chatterino

View file

@ -77,23 +77,23 @@ void SettingsDialog::addTabs()
this->addTab(new settingspages::AccountsPage);
this->ui.tabContainer->addStretch(1);
this->ui.tabContainer->addSpacing(16);
this->addTab(new settingspages::AppearancePage);
this->addTab(new settingspages::BehaviourPage);
this->ui.tabContainer->addStretch(1);
this->ui.tabContainer->addSpacing(16);
this->addTab(new settingspages::CommandPage);
// this->addTab(new settingspages::EmotesPage);
this->addTab(new settingspages::HighlightingPage);
this->ui.tabContainer->addStretch(1);
this->addTab(new settingspages::IgnoreMessagesPage);
// this->addTab(new settingspages::IgnoreMessagesPage);
this->addTab(new settingspages::IgnoreUsersPage);
this->addTab(new settingspages::KeyboardSettingsPage);
this->addTab(new settingspages::LogsPage);
this->ui.tabContainer->addSpacing(16);
// this->addTab(new settingspages::KeyboardSettingsPage);
// this->addTab(new settingspages::LogsPage);
this->addTab(new settingspages::ModerationPage);
// this->addTab(new settingspages::SpecialChannelsPage);
this->addTab(new settingspages::ExternalToolsPage);

View file

@ -19,7 +19,7 @@ namespace widgets {
namespace settingspages {
CommandPage::CommandPage()
: SettingsPage("Macros", ":/images/commands.svg")
: SettingsPage("Commands", ":/images/commands.svg")
{
util::LayoutCreator<CommandPage> layoutCreator(this);
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();

View file

@ -15,7 +15,7 @@ ExternalToolsPage::ExternalToolsPage()
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<ExternalToolsPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>().withoutMargin();
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
{
auto group = layout.emplace<QGroupBox>("Streamlink");
@ -25,6 +25,8 @@ ExternalToolsPage::ExternalToolsPage()
this->createComboBox({STREAMLINK_QUALITY}, settings.preferredQuality));
groupLayout->addRow("Additional options:", this->createLineEdit(settings.streamlinkOpts));
}
layout->addStretch(1);
}
} // namespace settingspages

View file

@ -11,6 +11,7 @@
#include "debug/log.hpp"
#include "singletons/settingsmanager.hpp"
#include "util/layoutcreator.hpp"
#include "util/standarditemhelper.hpp"
#define ENABLE_HIGHLIGHTS "Enable Highlighting"
#define HIGHLIGHT_MSG "Highlight messages containing your name"
@ -32,23 +33,6 @@ HighlightingPage::HighlightingPage()
{
// GENERAL
layout.append(this->createCheckBox(ENABLE_HIGHLIGHTS, settings.enableHighlights));
layout.append(this->createCheckBox(HIGHLIGHT_MSG, settings.enableHighlightsSelf));
layout.append(this->createCheckBox(PLAY_SOUND, settings.enableHighlightSound));
layout.append(this->createCheckBox(FLASH_TASKBAR, settings.enableHighlightTaskbar));
auto customSound = layout.emplace<QHBoxLayout>().withoutMargin();
{
customSound.append(this->createCheckBox("Custom sound", settings.customHighlightSound));
auto selectFile = customSound.emplace<QPushButton>("Select custom sound file");
QObject::connect(selectFile.getElement(), &QPushButton::clicked, this,
[&settings, this] {
auto fileName = QFileDialog::getOpenFileName(
this, tr("Open Sound"), "", tr("Audio Files (*.mp3 *.wav)"));
settings.pathHighlightSound = fileName;
});
}
layout.append(createCheckBox(ALWAYS_PLAY, settings.highlightAlwaysPlaySound));
// TABS
auto tabs = layout.emplace<QTabWidget>();
@ -58,29 +42,35 @@ HighlightingPage::HighlightingPage()
{
QTableView *view = *highlights.emplace<QTableView>();
auto *model = new QStandardItemModel(0, 4, view);
// model->setTitles({"Pattern", "Flash taskbar", "Play sound", "Regex"});
model->setHeaderData(0, Qt::Horizontal, "Pattern");
model->setHeaderData(1, Qt::Horizontal, "Flash taskbar");
model->setHeaderData(2, Qt::Horizontal, "Play sound");
model->setHeaderData(3, Qt::Horizontal, "Regex");
view->setModel(model);
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
// own name
auto *yourName = util::stringItem("Your name (automatic)", false, false);
yourName->setData(QBrush("#666"), Qt::ForegroundRole);
yourName->setFlags(yourName->flags() | Qt::ItemIsUserCheckable |
Qt::ItemIsUserCheckable);
yourName->setData(settings.enableHighlightsSelf ? 2 : 0, Qt::CheckStateRole);
model->appendRow(
{yourName,
util::boolItem(settings.enableHighlightTaskbar.getValue(), true, false),
util::boolItem(settings.enableHighlightSound.getValue(), true, false),
util::emptyItem()});
// highlight phrases
// fourtf: could crash
for (const messages::HighlightPhrase &phrase :
settings.highlightProperties.getValue()) {
auto *item1 = new QStandardItem(phrase.key);
auto *item2 = new QStandardItem();
item2->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item2->setData(phrase.alert, Qt::CheckStateRole);
auto *item3 = new QStandardItem();
item3->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item3->setData(phrase.sound, Qt::CheckStateRole);
auto *item4 = new QStandardItem();
item4->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item4->setData(phrase.regex, Qt::CheckStateRole);
model->appendRow({item1, item2, item3, item4});
model->appendRow({util::stringItem(phrase.key), util::boolItem(phrase.alert),
util::boolItem(phrase.sound), util::boolItem(phrase.regex)});
}
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
// fourtf: make class extrend BaseWidget and add this to dpiChanged
QTimer::singleShot(1, [view] {
view->resizeColumnsToContents();
@ -89,40 +79,51 @@ HighlightingPage::HighlightingPage()
auto buttons = highlights.emplace<QHBoxLayout>();
QObject::connect(
model, &QStandardItemModel::dataChanged,
[model](const QModelIndex &topLeft, const QModelIndex &bottomRight,
const QVector<int> &roles) {
std::vector<messages::HighlightPhrase> phrases;
for (int i = 0; i < model->rowCount(); i++) {
phrases.push_back(messages::HighlightPhrase{
model->item(i, 0)->data(Qt::DisplayRole).toString(),
model->item(i, 1)->data(Qt::CheckStateRole).toBool(),
model->item(i, 2)->data(Qt::CheckStateRole).toBool(),
model->item(i, 3)->data(Qt::CheckStateRole).toBool()});
}
singletons::SettingManager::getInstance().highlightProperties.setValue(
phrases);
});
QObject::connect(model, &QStandardItemModel::dataChanged,
[model](const QModelIndex &topLeft, const QModelIndex &bottomRight,
const QVector<int> &roles) {
std::vector<messages::HighlightPhrase> phrases;
for (int i = 1; i < model->rowCount(); i++) {
phrases.push_back(messages::HighlightPhrase{
model->item(i, 0)->data(Qt::DisplayRole).toString(),
model->item(i, 1)->data(Qt::CheckStateRole).toBool(),
model->item(i, 2)->data(Qt::CheckStateRole).toBool(),
model->item(i, 3)->data(Qt::CheckStateRole).toBool()});
}
auto &settings = singletons::SettingManager::getInstance();
settings.highlightProperties.setValue(phrases);
settings.enableHighlightsSelf.setValue(
model->item(0, 0)->data(Qt::CheckStateRole).toBool());
settings.enableHighlightTaskbar.setValue(
model->item(0, 1)->data(Qt::CheckStateRole).toBool());
settings.enableHighlightSound.setValue(
model->item(0, 2)->data(Qt::CheckStateRole).toBool());
});
auto add = buttons.emplace<QPushButton>("Add");
QObject::connect(*add, &QPushButton::clicked, [model] {
auto *item1 = new QStandardItem();
auto *item2 = new QStandardItem();
item2->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item2->setData(true, Qt::CheckStateRole);
auto *item3 = new QStandardItem();
item3->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item3->setData(true, Qt::CheckStateRole);
auto *item4 = new QStandardItem();
item4->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item4->setData(false, Qt::CheckStateRole);
model->appendRow({item1, item2, item3, item4});
QObject::connect(*add, &QPushButton::clicked, [model, view] {
model->appendRow({util::stringItem(""),
util::boolItem(model->item(model->rowCount() - 1, 1)
->data(Qt::CheckStateRole)
.toBool()),
util::boolItem(model->item(model->rowCount() - 1, 2)
->data(Qt::CheckStateRole)
.toBool()),
util::boolItem(false)});
view->scrollToBottom();
});
auto remove = buttons.emplace<QPushButton>("Remove");
QObject::connect(*remove, &QPushButton::clicked, [view, model] {
if (view->selectionModel()->hasSelection()) {
model->removeRow(view->selectionModel()->selectedRows()[0].row());
std::vector<int> indices;
for (const QModelIndex &index : view->selectionModel()->selectedRows(0)) {
indices.push_back(index.row());
}
std::sort(indices.begin(), indices.end());
for (int i = indices.size() - 1; i >= 0; i--) {
model->removeRow(indices[i]);
}
});
@ -148,6 +149,21 @@ HighlightingPage::HighlightingPage()
});
}
}
// MISC
auto customSound = layout.emplace<QHBoxLayout>().withoutMargin();
{
customSound.append(this->createCheckBox("Custom sound", settings.customHighlightSound));
auto selectFile = customSound.emplace<QPushButton>("Select custom sound file");
QObject::connect(selectFile.getElement(), &QPushButton::clicked, this,
[&settings, this] {
auto fileName = QFileDialog::getOpenFileName(
this, tr("Open Sound"), "", tr("Audio Files (*.mp3 *.wav)"));
settings.pathHighlightSound = fileName;
});
}
layout.append(createCheckBox(ALWAYS_PLAY, settings.highlightAlwaysPlaySound));
}
// ---- misc

View file

@ -11,7 +11,7 @@
#include <QVBoxLayout>
// clang-format off
#define INFO "/ignore <user> in chat ignores a user\n/unignore <user> in chat unignores a user\n\nChatterino uses the twitch api for ignored users so they are shared with the webchat.\nIf you use your own oauth key make sure that it has the correct permissions.\n"
#define INFO "/ignore <user> in chat ignores a user\n/unignore <user> in chat unignores a user"
// clang-format on
namespace chatterino {
@ -19,16 +19,12 @@ namespace widgets {
namespace settingspages {
IgnoreUsersPage::IgnoreUsersPage()
: SettingsPage("Ignore Users", "")
: SettingsPage("Ignores", "")
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
util::LayoutCreator<IgnoreUsersPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
auto label = layout.emplace<QLabel>(INFO);
label->setWordWrap(true);
label->setStyleSheet("color: #BBB");
auto group = layout.emplace<QGroupBox>("Ignored users").setLayoutType<QVBoxLayout>();
{
group.append(
@ -53,6 +49,10 @@ IgnoreUsersPage::IgnoreUsersPage()
auto userList = group.emplace<QListView>();
UNUSED(userList); // TODO: Fill this list in with ignored users
}
auto label = layout.emplace<QLabel>(INFO);
label->setWordWrap(true);
label->setStyleSheet("color: #BBB");
}
} // namespace settingspages

View file

@ -8,20 +8,47 @@
#include <QTextEdit>
#include <QVBoxLayout>
#include "singletons/pathmanager.hpp"
#include "util/layoutcreator.hpp"
namespace chatterino {
namespace widgets {
namespace settingspages {
inline QString CreateLink(const QString &url, bool file = false)
{
if (file) {
return QString("<a href=\"file:///" + url + "\"><span style=\"color: white;\">" + url +
"</span></a>");
}
return QString("<a href=\"" + url + "\"><span style=\"color: white;\">" + url + "</span></a>");
}
ModerationPage::ModerationPage()
: SettingsPage("Moderation", "")
{
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
singletons::PathManager &pathManager = singletons::PathManager::getInstance();
util::LayoutCreator<ModerationPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
{
// Logs (copied from LoggingMananger)
auto logPath = pathManager.logsFolderPath;
auto created = layout.emplace<QLabel>();
created->setText("Logs are saved to " + CreateLink(logPath, true));
created->setTextFormat(Qt::RichText);
created->setTextInteractionFlags(Qt::TextBrowserInteraction |
Qt::LinksAccessibleByKeyboard |
Qt::LinksAccessibleByKeyboard);
created->setOpenExternalLinks(true);
layout.append(this->createCheckBox("Enable logging", settings.enableLogging));
layout->addStretch(1);
// Logs end
// clang-format off
auto label = layout.emplace<QLabel>("Click the moderation mod button (<img width='18' height='18' src=':/images/moderatormode_disabled.png'>) in a channel that you moderate to enable moderator mode.<br>");
label->setWordWrap(true);