1 /*
2 * Copyright (C) 2019-2021 Ashar Khan <ashar786khan@gmail.com>
3 *
4 * This file is part of CP Editor.
5 *
6 * CP Editor is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * I will not be responsible if CP Editor behaves in unexpected way and
12 * causes your ratings to go down and or lose any important contest.
13 *
14 * Believe Software is "Software" and it isn't immune to bugs.
15 *
16 */
17
18 #include "Settings/PreferencesPage.hpp"
19 #include "Settings/SettingsManager.hpp"
20 #include "Settings/ValueWrapper.hpp"
21 #include <QApplication>
22 #include <QFormLayout>
23 #include <QLabel>
24 #include <QMessageBox>
25 #include <QPushButton>
26 #include <QScrollArea>
27 #include <QStyle>
28 #include <QVBoxLayout>
29
PreferencesPage(QWidget * parent)30 PreferencesPage::PreferencesPage(QWidget *parent) : QWidget(parent)
31 {
32 // construct widgets
33 auto *mainLayout = new QVBoxLayout(this);
34 titleLabel = new QLabel();
35 scrollArea = new QScrollArea();
36 scrollAreaWidget = new QWidget();
37 settingsLayout = new QVBoxLayout(scrollAreaWidget);
38 auto *buttonsLayout = new QHBoxLayout();
39 defaultButton =
40 new QPushButton(QApplication::style()->standardIcon(QStyle::SP_FileDialogDetailedView), tr("Default"));
41 defaultButton->setShortcut({"Ctrl+D"});
42 resetButton = new QPushButton(QApplication::style()->standardIcon(QStyle::SP_DialogResetButton), tr("Reset"));
43 resetButton->setShortcut({"Ctrl+R"});
44 applyButton = new QPushButton(QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton), tr("Apply"));
45 applyButton->setShortcut({"Ctrl+S"});
46
47 // set up the UI
48 buttonsLayout->addWidget(defaultButton);
49 buttonsLayout->addWidget(resetButton);
50 buttonsLayout->addStretch();
51 buttonsLayout->addWidget(applyButton);
52 scrollArea->setWidgetResizable(true);
53 scrollArea->setWidget(scrollAreaWidget);
54 mainLayout->addWidget(titleLabel);
55 mainLayout->addWidget(scrollArea);
56 mainLayout->addLayout(buttonsLayout);
57
58 // add tooltips
59 defaultButton->setToolTip(tr("Restore the default settings on the current page. (Ctrl+D)"));
60 resetButton->setToolTip(tr("Discard all changes on the current page. (Ctrl+R)"));
61 applyButton->setToolTip(tr("Save the changes on the current page. (Ctrl+S)"));
62
63 // set the font for title
64 auto labelFont = font();
65 labelFont.setPointSizeF(font().pointSizeF() * 1.6);
66 titleLabel->setFont(labelFont);
67
68 // connect the signals and slots
69 connect(defaultButton, &QPushButton::clicked, this, &PreferencesPage::loadDefault);
70 connect(resetButton, &QPushButton::clicked, this, &PreferencesPage::loadSettings);
71 connect(applyButton, &QPushButton::clicked, this, &PreferencesPage::applySettings);
72 }
73
aboutToExit()74 bool PreferencesPage::aboutToExit()
75 {
76 // exit if there is no unsaved change
77 if (!areSettingsChanged())
78 return true;
79
80 // otherwise, ask the user whether to save, discard or cancel
81 auto response = QMessageBox::warning(
82 this, tr("Unsaved Settings"), tr("The settings are changed. Do you want to save the settings or discard them?"),
83 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
84
85 switch (response)
86 {
87 case QMessageBox::Save:
88 applySettings();
89 return true;
90 case QMessageBox::Discard:
91 loadSettings();
92 return true;
93 case QMessageBox::Cancel:
94 return false;
95 default:
96 Q_UNREACHABLE();
97 break;
98 }
99 }
100
path() const101 QString PreferencesPage::path() const
102 {
103 return m_path;
104 }
105
trPath() const106 QString PreferencesPage::trPath() const
107 {
108 return m_trPath;
109 }
110
setPath(const QString & path,const QString & trPath)111 void PreferencesPage::setPath(const QString &path, const QString &trPath)
112 {
113 m_path = path;
114 m_trPath = trPath;
115 emit pathChanged(m_path);
116 }
117
setTitle(const QString & title)118 void PreferencesPage::setTitle(const QString &title)
119 {
120 titleLabel->setText(title);
121 }
122
content()123 QStringList PreferencesPage::content()
124 {
125 return QStringList();
126 }
127
loadSettings()128 void PreferencesPage::loadSettings()
129 {
130 makeUITheSameAsSettings();
131 updateButtons();
132 }
133
addLayout(QLayout * layout)134 void PreferencesPage::addLayout(QLayout *layout)
135 {
136 settingsLayout->addLayout(layout);
137 }
138
addWidget(QWidget * widget)139 void PreferencesPage::addWidget(QWidget *widget)
140 {
141 settingsLayout->addWidget(widget);
142 }
143
addItem(QLayoutItem * item)144 void PreferencesPage::addItem(QLayoutItem *item)
145 {
146 settingsLayout->addItem(item);
147 }
148
registerWidget(const QString & key,ValueWidget * widget) const149 void PreferencesPage::registerWidget(const QString &key, ValueWidget *widget) const
150 {
151 // PreferencesPageTemplate::PreferencesPageTemplate uses Qt::DirectConnection
152 QObject::connect(widget, &ValueWidget::valueChanged, this, &PreferencesPage::updateButtons, Qt::QueuedConnection);
153
154 SettingsManager::setWidget(key, widget->coreWidget());
155 }
156
loadDefault()157 void PreferencesPage::loadDefault()
158 {
159 makeUITheSameAsDefault();
160 updateButtons();
161 }
162
applySettings()163 void PreferencesPage::applySettings()
164 {
165 makeSettingsTheSameAsUI();
166 updateButtons();
167 emit settingsApplied(m_path);
168 }
169
updateButtons()170 void PreferencesPage::updateButtons()
171 {
172 bool changed = areSettingsChanged();
173 resetButton->setEnabled(changed);
174 applyButton->setEnabled(changed);
175 }
176