2018-06-26 15:11:45 +02:00
|
|
|
#include "widgets/dialogs/SettingsDialog.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
|
|
|
|
#include "Application.hpp"
|
2020-09-26 16:03:51 +02:00
|
|
|
#include "common/Args.hpp"
|
2020-10-04 13:02:29 +02:00
|
|
|
#include "controllers/commands/CommandController.hpp"
|
2019-09-02 18:59:37 +02:00
|
|
|
#include "singletons/Resources.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "util/LayoutCreator.hpp"
|
2020-07-18 15:56:33 +02:00
|
|
|
#include "util/Shortcut.hpp"
|
2019-09-02 18:59:37 +02:00
|
|
|
#include "widgets/helper/Button.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "widgets/settingspages/AboutPage.hpp"
|
|
|
|
#include "widgets/settingspages/AccountsPage.hpp"
|
|
|
|
#include "widgets/settingspages/CommandPage.hpp"
|
2018-06-26 17:42:35 +02:00
|
|
|
#include "widgets/settingspages/ExternalToolsPage.hpp"
|
2018-10-31 19:45:51 +01:00
|
|
|
#include "widgets/settingspages/GeneralPage.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "widgets/settingspages/HighlightingPage.hpp"
|
2018-07-05 16:45:34 +02:00
|
|
|
#include "widgets/settingspages/IgnoresPage.hpp"
|
2018-06-26 17:42:35 +02:00
|
|
|
#include "widgets/settingspages/KeyboardSettingsPage.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "widgets/settingspages/ModerationPage.hpp"
|
2018-08-09 15:41:03 +02:00
|
|
|
#include "widgets/settingspages/NotificationPage.hpp"
|
2017-01-02 03:02:32 +01:00
|
|
|
|
2018-01-12 23:33:04 +01:00
|
|
|
#include <QDialogButtonBox>
|
2019-09-01 23:23:20 +02:00
|
|
|
#include <QLineEdit>
|
2017-01-01 18:43:52 +01:00
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
namespace chatterino {
|
2017-01-18 21:30:23 +01:00
|
|
|
|
2017-01-01 18:43:52 +01:00
|
|
|
SettingsDialog::SettingsDialog()
|
2019-09-08 21:45:46 +02:00
|
|
|
: BaseWindow(BaseWindow::DisableCustomScaling)
|
2017-01-01 18:43:52 +01:00
|
|
|
{
|
2019-09-03 12:46:22 +02:00
|
|
|
this->setWindowTitle("Chatterino Settings");
|
2020-02-21 02:07:34 +01:00
|
|
|
this->resize(815, 600);
|
2020-02-20 23:47:25 +01:00
|
|
|
this->themeChangedEvent();
|
|
|
|
this->scaleChangedEvent(this->scale());
|
|
|
|
|
2018-01-12 23:09:05 +01:00
|
|
|
this->initUi();
|
2017-07-02 12:36:50 +02:00
|
|
|
this->addTabs();
|
2018-10-31 20:57:29 +01:00
|
|
|
this->overrideBackgroundColor_ = QColor("#111111");
|
2020-02-21 03:01:48 +01:00
|
|
|
this->scaleChangedEvent(this->scale()); // execute twice to width of item
|
2020-07-18 15:56:33 +02:00
|
|
|
|
|
|
|
createWindowShortcut(this, "CTRL+F", [this] {
|
|
|
|
this->ui_.search->setFocus();
|
|
|
|
this->ui_.search->selectAll();
|
|
|
|
});
|
2017-01-02 03:02:32 +01:00
|
|
|
}
|
|
|
|
|
2018-01-12 23:09:05 +01:00
|
|
|
void SettingsDialog::initUi()
|
2017-10-08 16:31:16 +02:00
|
|
|
{
|
2019-09-08 21:45:46 +02:00
|
|
|
auto outerBox = LayoutCreator<QWidget>(this->getLayoutContainer())
|
2019-09-03 11:15:38 +02:00
|
|
|
.setLayoutType<QVBoxLayout>()
|
|
|
|
.withoutSpacing();
|
|
|
|
|
|
|
|
// TOP
|
|
|
|
auto title = outerBox.emplace<PageHeader>();
|
|
|
|
auto edit = LayoutCreator<PageHeader>(title.getElement())
|
|
|
|
.setLayoutType<QHBoxLayout>()
|
|
|
|
.withoutMargin()
|
|
|
|
.emplace<QLineEdit>()
|
|
|
|
.assign(&this->ui_.search);
|
2020-08-22 12:17:20 +02:00
|
|
|
edit->setPlaceholderText("Find in settings... (Ctrl+F)");
|
2019-09-03 11:15:38 +02:00
|
|
|
|
|
|
|
QObject::connect(edit.getElement(), &QLineEdit::textChanged, this,
|
|
|
|
&SettingsDialog::filterElements);
|
|
|
|
|
|
|
|
// CENTER
|
|
|
|
auto centerBox =
|
|
|
|
outerBox.emplace<QHBoxLayout>().withoutMargin().withoutSpacing();
|
|
|
|
|
|
|
|
// left side (tabs)
|
|
|
|
centerBox.emplace<QWidget>()
|
2018-06-11 15:04:54 +02:00
|
|
|
.assign(&this->ui_.tabContainerContainer)
|
2019-09-03 11:15:38 +02:00
|
|
|
.setLayoutType<QVBoxLayout>()
|
2018-01-12 23:09:05 +01:00
|
|
|
.withoutMargin()
|
2018-06-11 15:04:54 +02:00
|
|
|
.assign(&this->ui_.tabContainer);
|
2017-01-02 03:02:32 +01:00
|
|
|
|
2019-09-03 11:15:38 +02:00
|
|
|
// right side (pages)
|
2020-02-21 03:01:48 +01:00
|
|
|
centerBox.emplace<QStackedLayout>()
|
|
|
|
.assign(&this->ui_.pageStack)
|
|
|
|
.withoutMargin();
|
2017-01-22 12:46:35 +01:00
|
|
|
|
2018-10-31 19:45:51 +01:00
|
|
|
this->ui_.pageStack->setMargin(0);
|
|
|
|
|
2019-09-03 11:15:38 +02:00
|
|
|
outerBox->addSpacing(12);
|
|
|
|
|
|
|
|
// BOTTOM
|
|
|
|
auto buttons = outerBox.emplace<QDialogButtonBox>(Qt::Horizontal);
|
|
|
|
{
|
|
|
|
this->ui_.okButton =
|
|
|
|
buttons->addButton("Ok", QDialogButtonBox::YesRole);
|
|
|
|
this->ui_.cancelButton =
|
|
|
|
buttons->addButton("Cancel", QDialogButtonBox::NoRole);
|
|
|
|
}
|
|
|
|
|
2018-01-12 23:09:05 +01:00
|
|
|
// ---- misc
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainerContainer->setObjectName("tabWidget");
|
|
|
|
this->ui_.pageStack->setObjectName("pages");
|
2017-01-22 12:46:35 +01:00
|
|
|
|
2018-08-06 21:17:03 +02:00
|
|
|
QObject::connect(this->ui_.okButton, &QPushButton::clicked, this,
|
|
|
|
&SettingsDialog::onOkClicked);
|
2018-06-11 15:04:54 +02:00
|
|
|
QObject::connect(this->ui_.cancelButton, &QPushButton::clicked, this,
|
2018-07-06 19:23:47 +02:00
|
|
|
&SettingsDialog::onCancelClicked);
|
2017-10-08 16:31:16 +02:00
|
|
|
}
|
2017-01-22 12:46:35 +01:00
|
|
|
|
2019-09-03 11:15:38 +02:00
|
|
|
void SettingsDialog::filterElements(const QString &text)
|
|
|
|
{
|
|
|
|
// filter elements and hide pages
|
2020-02-21 01:17:22 +01:00
|
|
|
for (auto &&tab : this->tabs_)
|
2019-09-03 11:15:38 +02:00
|
|
|
{
|
|
|
|
// filterElements returns true if anything on the page matches the search query
|
2020-02-21 02:16:17 +01:00
|
|
|
tab->setVisible(tab->page()->filterElements(text) ||
|
|
|
|
tab->name().contains(text, Qt::CaseInsensitive));
|
2019-09-03 11:15:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// find next visible page
|
|
|
|
if (this->lastSelectedByUser_ && this->lastSelectedByUser_->isVisible())
|
|
|
|
{
|
|
|
|
this->selectTab(this->lastSelectedByUser_, false);
|
|
|
|
}
|
|
|
|
else if (!this->selectedTab_->isVisible())
|
|
|
|
{
|
|
|
|
for (auto &&tab : this->tabs_)
|
|
|
|
{
|
|
|
|
if (tab->isVisible())
|
|
|
|
{
|
|
|
|
this->selectTab(tab, false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove duplicate spaces
|
|
|
|
bool shouldShowSpace = false;
|
|
|
|
|
|
|
|
for (int i = 0; i < this->ui_.tabContainer->count(); i++)
|
|
|
|
{
|
|
|
|
auto item = this->ui_.tabContainer->itemAt(i);
|
|
|
|
if (auto x = dynamic_cast<QSpacerItem *>(item); x)
|
|
|
|
{
|
|
|
|
x->changeSize(10, shouldShowSpace ? int(16 * this->scale()) : 0);
|
|
|
|
shouldShowSpace = false;
|
|
|
|
}
|
|
|
|
else if (item->widget())
|
|
|
|
{
|
|
|
|
shouldShowSpace |= item->widget()->isVisible();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-12 23:09:05 +01:00
|
|
|
void SettingsDialog::addTabs()
|
2017-10-08 16:31:16 +02:00
|
|
|
{
|
2018-10-31 19:45:51 +01:00
|
|
|
this->ui_.tabContainer->setMargin(0);
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainer->setSpacing(0);
|
2018-01-24 15:34:04 +01:00
|
|
|
|
2019-09-03 11:15:38 +02:00
|
|
|
this->ui_.tabContainer->setContentsMargins(0, 20, 0, 20);
|
|
|
|
|
2020-02-21 03:01:48 +01:00
|
|
|
// Constructors are wrapped in std::function to remove some strain from first time loading.
|
|
|
|
|
2020-02-21 01:59:58 +01:00
|
|
|
// clang-format off
|
|
|
|
this->addTab([]{return new GeneralPage;}, "General", ":/settings/about.svg");
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainer->addSpacing(16);
|
2020-02-28 19:05:50 +01:00
|
|
|
this->addTab([]{return new AccountsPage;}, "Accounts", ":/settings/accounts.svg", SettingsTabId::Accounts);
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainer->addSpacing(16);
|
2020-02-21 01:59:58 +01:00
|
|
|
this->addTab([]{return new CommandPage;}, "Commands", ":/settings/commands.svg");
|
|
|
|
this->addTab([]{return new HighlightingPage;}, "Highlights", ":/settings/notifications.svg");
|
|
|
|
this->addTab([]{return new IgnoresPage;}, "Ignores", ":/settings/ignore.svg");
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainer->addSpacing(16);
|
2020-02-21 01:59:58 +01:00
|
|
|
this->addTab([]{return new KeyboardSettingsPage;}, "Keybindings", ":/settings/keybinds.svg");
|
2020-02-28 19:05:50 +01:00
|
|
|
this->addTab([]{return new ModerationPage;}, "Moderation", ":/settings/moderation.svg", SettingsTabId::Moderation);
|
2020-08-13 17:36:45 +02:00
|
|
|
this->addTab([]{return new NotificationPage;}, "Live Notifications", ":/settings/notification2.svg");
|
2020-02-21 01:59:58 +01:00
|
|
|
this->addTab([]{return new ExternalToolsPage;}, "External tools", ":/settings/externaltools.svg");
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainer->addStretch(1);
|
2020-02-28 19:05:50 +01:00
|
|
|
this->addTab([]{return new AboutPage;}, "About", ":/settings/about.svg", SettingsTabId(), Qt::AlignBottom);
|
2020-02-21 01:59:58 +01:00
|
|
|
// clang-format on
|
2017-01-02 03:02:32 +01:00
|
|
|
}
|
|
|
|
|
2020-02-21 01:59:58 +01:00
|
|
|
void SettingsDialog::addTab(std::function<SettingsPage *()> page,
|
|
|
|
const QString &name, const QString &iconPath,
|
2020-02-28 19:05:50 +01:00
|
|
|
SettingsTabId id, Qt::Alignment alignment)
|
2017-01-02 03:02:32 +01:00
|
|
|
{
|
2020-02-28 19:05:50 +01:00
|
|
|
auto tab = new SettingsDialogTab(this, std::move(page), name, iconPath, id);
|
2017-01-02 03:02:32 +01:00
|
|
|
|
2018-06-11 15:04:54 +02:00
|
|
|
this->ui_.tabContainer->addWidget(tab, 0, alignment);
|
2018-07-06 19:23:47 +02:00
|
|
|
this->tabs_.push_back(tab);
|
2017-01-02 03:02:32 +01:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (this->tabs_.size() == 1)
|
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->selectTab(tab);
|
2017-01-02 03:02:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-02 17:22:14 +02:00
|
|
|
void SettingsDialog::selectTab(SettingsDialogTab *tab, bool byUser)
|
2017-01-02 03:02:32 +01:00
|
|
|
{
|
2020-02-21 01:59:58 +01:00
|
|
|
// add page if it's not been added yet
|
|
|
|
[&] {
|
|
|
|
for (int i = 0; i < this->ui_.pageStack->count(); i++)
|
|
|
|
if (this->ui_.pageStack->itemAt(i)->widget() == tab->page())
|
|
|
|
return;
|
|
|
|
|
|
|
|
this->ui_.pageStack->addWidget(tab->page());
|
|
|
|
}();
|
|
|
|
|
2020-02-21 00:46:19 +01:00
|
|
|
this->ui_.pageStack->setCurrentWidget(tab->page());
|
2017-01-02 03:02:32 +01:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (this->selectedTab_ != nullptr)
|
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->selectedTab_->setSelected(false);
|
|
|
|
this->selectedTab_->setStyleSheet("color: #FFF");
|
2017-01-02 03:02:32 +01:00
|
|
|
}
|
2017-01-01 18:43:52 +01:00
|
|
|
|
2017-01-02 03:02:32 +01:00
|
|
|
tab->setSelected(true);
|
2020-10-11 14:36:28 +02:00
|
|
|
tab->setStyleSheet(
|
|
|
|
"background: #222; color: #4FC3F7;" // Should this be same as accent color?
|
|
|
|
"/*border: 1px solid #555; border-right: none;*/");
|
2018-07-06 19:23:47 +02:00
|
|
|
this->selectedTab_ = tab;
|
2019-09-02 17:22:14 +02:00
|
|
|
if (byUser)
|
|
|
|
{
|
|
|
|
this->lastSelectedByUser_ = tab;
|
|
|
|
}
|
2017-01-01 18:43:52 +01:00
|
|
|
}
|
2017-01-22 23:00:35 +01:00
|
|
|
|
2020-02-21 01:17:22 +01:00
|
|
|
void SettingsDialog::selectTab(SettingsTabId id)
|
|
|
|
{
|
2020-02-28 19:05:50 +01:00
|
|
|
auto t = this->tab(id);
|
|
|
|
assert(t);
|
|
|
|
if (!t)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this->selectTab(t);
|
2020-02-21 01:17:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
SettingsDialogTab *SettingsDialog::tab(SettingsTabId id)
|
|
|
|
{
|
|
|
|
for (auto &&tab : this->tabs_)
|
|
|
|
if (tab->id() == id)
|
|
|
|
return tab;
|
|
|
|
|
|
|
|
assert(false);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-10-21 15:32:28 +02:00
|
|
|
void SettingsDialog::showDialog(SettingsDialogPreference preferredTab)
|
2017-05-27 15:40:06 +02:00
|
|
|
{
|
|
|
|
static SettingsDialog *instance = new SettingsDialog();
|
2020-02-21 01:59:58 +01:00
|
|
|
static bool hasShownBefore = false;
|
|
|
|
if (hasShownBefore)
|
|
|
|
instance->refresh();
|
|
|
|
hasShownBefore = true;
|
2017-12-19 02:16:01 +01:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
switch (preferredTab)
|
|
|
|
{
|
2018-10-21 15:32:28 +02:00
|
|
|
case SettingsDialogPreference::Accounts:
|
2020-02-21 01:17:22 +01:00
|
|
|
instance->selectTab(SettingsTabId::Accounts);
|
2018-10-21 15:32:28 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SettingsDialogPreference::ModerationActions:
|
2020-02-21 01:17:22 +01:00
|
|
|
if (auto tab = instance->tab(SettingsTabId::Moderation))
|
|
|
|
{
|
|
|
|
instance->selectTab(tab);
|
|
|
|
if (auto page = dynamic_cast<ModerationPage *>(tab->page()))
|
|
|
|
{
|
|
|
|
page->selectModerationActions();
|
|
|
|
}
|
|
|
|
}
|
2018-10-21 15:32:28 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:;
|
2017-12-19 02:16:01 +01:00
|
|
|
}
|
2017-05-27 15:40:06 +02:00
|
|
|
|
|
|
|
instance->show();
|
|
|
|
instance->activateWindow();
|
|
|
|
instance->raise();
|
|
|
|
instance->setFocus();
|
|
|
|
}
|
|
|
|
|
2017-12-19 02:16:01 +01:00
|
|
|
void SettingsDialog::refresh()
|
|
|
|
{
|
2020-02-21 03:01:48 +01:00
|
|
|
// Resets the cancel button.
|
2018-08-12 12:56:28 +02:00
|
|
|
getSettings()->saveSnapshot();
|
2018-05-12 20:34:13 +02:00
|
|
|
|
2020-02-21 03:01:48 +01:00
|
|
|
// Updates tabs.
|
2018-10-21 13:43:02 +02:00
|
|
|
for (auto *tab : this->tabs_)
|
|
|
|
{
|
2020-02-21 00:46:19 +01:00
|
|
|
tab->page()->onShow();
|
2018-05-12 20:34:13 +02:00
|
|
|
}
|
2017-12-19 02:16:01 +01:00
|
|
|
}
|
|
|
|
|
2018-01-25 20:49:49 +01:00
|
|
|
void SettingsDialog::scaleChangedEvent(float newDpi)
|
2017-12-18 00:54:17 +01:00
|
|
|
{
|
|
|
|
QFile file(":/qss/settings.qss");
|
|
|
|
file.open(QFile::ReadOnly);
|
|
|
|
QString styleSheet = QLatin1String(file.readAll());
|
2018-07-03 16:55:02 +02:00
|
|
|
styleSheet.replace("<font-size>", QString::number(int(14 * newDpi)));
|
|
|
|
styleSheet.replace("<checkbox-size>", QString::number(int(14 * newDpi)));
|
2017-12-18 00:54:17 +01:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
for (SettingsDialogTab *tab : this->tabs_)
|
|
|
|
{
|
2018-07-03 16:55:02 +02:00
|
|
|
tab->setFixedHeight(int(30 * newDpi));
|
2017-12-18 00:54:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
this->setStyleSheet(styleSheet);
|
|
|
|
|
2020-02-20 23:47:25 +01:00
|
|
|
if (this->ui_.tabContainerContainer)
|
|
|
|
this->ui_.tabContainerContainer->setFixedWidth(int(150 * newDpi));
|
2017-07-23 11:59:05 +02:00
|
|
|
}
|
|
|
|
|
2018-07-06 17:11:37 +02:00
|
|
|
void SettingsDialog::themeChangedEvent()
|
2018-04-18 09:33:05 +02:00
|
|
|
{
|
2018-07-06 17:11:37 +02:00
|
|
|
BaseWindow::themeChangedEvent();
|
2018-04-18 09:33:05 +02:00
|
|
|
|
|
|
|
QPalette palette;
|
2020-02-21 03:01:48 +01:00
|
|
|
palette.setColor(QPalette::Window, QColor("#111"));
|
2018-04-18 09:33:05 +02:00
|
|
|
this->setPalette(palette);
|
|
|
|
}
|
|
|
|
|
2019-10-07 17:30:47 +02:00
|
|
|
void SettingsDialog::showEvent(QShowEvent *)
|
|
|
|
{
|
|
|
|
this->ui_.search->setText("");
|
|
|
|
}
|
|
|
|
|
2018-01-12 23:09:05 +01:00
|
|
|
///// Widget creation helpers
|
2018-07-06 19:23:47 +02:00
|
|
|
void SettingsDialog::onOkClicked()
|
2017-01-24 19:51:57 +01:00
|
|
|
{
|
2020-09-26 16:03:51 +02:00
|
|
|
if (!getArgs().dontSaveSettings)
|
|
|
|
{
|
2020-10-04 13:02:29 +02:00
|
|
|
getApp()->commands->save();
|
2020-09-26 16:03:51 +02:00
|
|
|
pajlada::Settings::SettingManager::gSave();
|
|
|
|
}
|
2017-01-24 19:51:57 +01:00
|
|
|
this->close();
|
|
|
|
}
|
|
|
|
|
2018-07-06 19:23:47 +02:00
|
|
|
void SettingsDialog::onCancelClicked()
|
2017-01-24 19:51:57 +01:00
|
|
|
{
|
2018-10-21 13:43:02 +02:00
|
|
|
for (auto &tab : this->tabs_)
|
|
|
|
{
|
2020-02-21 00:46:19 +01:00
|
|
|
tab->page()->cancel();
|
2018-01-12 23:09:05 +01:00
|
|
|
}
|
|
|
|
|
2018-08-12 12:56:28 +02:00
|
|
|
getSettings()->restoreSnapshot();
|
2017-07-31 00:37:22 +02:00
|
|
|
|
2017-01-24 19:51:57 +01:00
|
|
|
this->close();
|
|
|
|
}
|
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
} // namespace chatterino
|