1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 by the Quassel Project * |
3 | * devel@quassel-irc.org * |
4 | * * |
5 | * This program is free software; you can redistribute it and/or modify * |
6 | * it under the terms of the GNU General Public License as published by * |
7 | * the Free Software Foundation; either version 2 of the License, or * |
8 | * (at your option) version 3. * |
9 | * * |
10 | * This program is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
13 | * GNU General Public License for more details. * |
14 | * * |
15 | * You should have received a copy of the GNU General Public License * |
16 | * along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
19 | ***************************************************************************/ |
20 | |
21 | #include <QMessageBox> |
22 | #include <QPushButton> |
23 | |
24 | #include "settingsdlg.h" |
25 | |
26 | #include "client.h" |
27 | #include "iconloader.h" |
28 | |
29 | SettingsDlg::SettingsDlg(QWidget *parent) |
30 | : QDialog(parent), |
31 | _currentPage(0) |
32 | { |
33 | ui.setupUi(this); |
34 | setModal(true); |
35 | setAttribute(Qt::WA_DeleteOnClose, true); |
36 | setWindowIcon(SmallIcon("configure" )); |
37 | |
38 | updateGeometry(); |
39 | |
40 | ui.settingsTree->setRootIsDecorated(false); |
41 | |
42 | connect(ui.settingsTree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelected())); |
43 | connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *))); |
44 | |
45 | connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), SLOT(coreConnectionStateChanged())); |
46 | |
47 | setButtonStates(); |
48 | } |
49 | |
50 | |
51 | void SettingsDlg::coreConnectionStateChanged() |
52 | { |
53 | for (int i = 0; i < ui.settingsTree->topLevelItemCount(); i++) { |
54 | QTreeWidgetItem *catItem = ui.settingsTree->topLevelItem(i); |
55 | for (int j = 0; j < catItem->childCount(); j++) { |
56 | QTreeWidgetItem *item = catItem->child(j); |
57 | setItemState(item); |
58 | } |
59 | setItemState(catItem); |
60 | } |
61 | } |
62 | |
63 | |
64 | void SettingsDlg::setItemState(QTreeWidgetItem *item) |
65 | { |
66 | SettingsPage *sp = qobject_cast<SettingsPage *>(item->data(0, SettingsPageRole).value<QObject *>()); |
67 | Q_ASSERT(sp); |
68 | item->setDisabled(!Client::isConnected() && sp->needsCoreConnection()); |
69 | } |
70 | |
71 | |
72 | void SettingsDlg::registerSettingsPage(SettingsPage *sp) |
73 | { |
74 | sp->setParent(ui.settingsStack); |
75 | ui.settingsStack->addWidget(sp); |
76 | |
77 | connect(sp, SIGNAL(changed(bool)), this, SLOT(setButtonStates())); |
78 | |
79 | QTreeWidgetItem *cat; |
80 | QList<QTreeWidgetItem *> cats = ui.settingsTree->findItems(sp->category(), Qt::MatchExactly); |
81 | if (!cats.count()) { |
82 | cat = new QTreeWidgetItem(ui.settingsTree, QStringList(sp->category())); |
83 | cat->setExpanded(true); |
84 | cat->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); |
85 | } |
86 | else { |
87 | cat = cats[0]; |
88 | } |
89 | |
90 | QTreeWidgetItem *item; |
91 | if (sp->title().isEmpty()) |
92 | item = cat; |
93 | else |
94 | item = new QTreeWidgetItem(cat, QStringList(sp->title())); |
95 | |
96 | item->setData(0, SettingsPageRole, QVariant::fromValue<QObject *>(sp)); |
97 | ui.settingsTree->setMinimumWidth(ui.settingsTree->header()->sectionSizeHint(0) + 5); |
98 | pageIsLoaded[sp] = false; |
99 | if (!ui.settingsTree->selectedItems().count()) |
100 | ui.settingsTree->setCurrentItem(item); |
101 | |
102 | setItemState(item); |
103 | } |
104 | |
105 | |
106 | void SettingsDlg::selectPage(SettingsPage *sp) |
107 | { |
108 | if (!sp) { |
109 | _currentPage = 0; |
110 | ui.settingsStack->setCurrentIndex(0); |
111 | ui.pageTitle->setText(tr("Settings" )); |
112 | return; |
113 | } |
114 | |
115 | if (!pageIsLoaded[sp]) { |
116 | sp->load(); |
117 | pageIsLoaded[sp] = true; |
118 | } |
119 | |
120 | if (sp != currentPage() && currentPage() != 0 && currentPage()->hasChanged()) { |
121 | int ret = QMessageBox::warning(this, tr("Save changes" ), |
122 | tr("There are unsaved changes on the current configuration page. Would you like to apply your changes now?" ), |
123 | QMessageBox::Discard|QMessageBox::Save|QMessageBox::Cancel, QMessageBox::Cancel); |
124 | if (ret == QMessageBox::Save) { |
125 | if (!applyChanges()) sp = currentPage(); |
126 | } |
127 | else if (ret == QMessageBox::Discard) { |
128 | undoChanges(); |
129 | } |
130 | else sp = currentPage(); |
131 | } |
132 | |
133 | if (sp != currentPage()) { |
134 | if (sp->title().isEmpty()) { |
135 | ui.pageTitle->setText(sp->category()); |
136 | setWindowTitle(tr("Configure %1" ).arg(sp->category())); |
137 | } |
138 | else { |
139 | ui.pageTitle->setText(sp->title()); |
140 | setWindowTitle(tr("Configure %1" ).arg(sp->title())); |
141 | } |
142 | |
143 | ui.settingsStack->setCurrentWidget(sp); |
144 | _currentPage = sp; |
145 | } |
146 | setButtonStates(); |
147 | } |
148 | |
149 | |
150 | void SettingsDlg::itemSelected() |
151 | { |
152 | QList<QTreeWidgetItem *> items = ui.settingsTree->selectedItems(); |
153 | SettingsPage *sp = 0; |
154 | if (!items.isEmpty()) { |
155 | sp = qobject_cast<SettingsPage *>(items[0]->data(0, SettingsPageRole).value<QObject *>()); |
156 | } |
157 | selectPage(sp); |
158 | } |
159 | |
160 | |
161 | void SettingsDlg::setButtonStates() |
162 | { |
163 | SettingsPage *sp = currentPage(); |
164 | ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(sp && sp->hasChanged()); |
165 | ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(sp && sp->hasChanged()); |
166 | ui.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setEnabled(sp && sp->hasDefaults()); |
167 | } |
168 | |
169 | |
170 | void SettingsDlg::buttonClicked(QAbstractButton *button) |
171 | { |
172 | switch (ui.buttonBox->standardButton(button)) { |
173 | case QDialogButtonBox::Ok: |
174 | if (currentPage() && currentPage()->hasChanged()) { |
175 | if (applyChanges()) accept(); |
176 | } |
177 | else accept(); |
178 | break; |
179 | case QDialogButtonBox::Apply: |
180 | applyChanges(); |
181 | break; |
182 | case QDialogButtonBox::Cancel: |
183 | undoChanges(); |
184 | reject(); |
185 | break; |
186 | case QDialogButtonBox::Reset: |
187 | reload(); |
188 | break; |
189 | case QDialogButtonBox::RestoreDefaults: |
190 | loadDefaults(); |
191 | break; |
192 | default: |
193 | break; |
194 | } |
195 | } |
196 | |
197 | |
198 | bool SettingsDlg::applyChanges() |
199 | { |
200 | if (!currentPage()) return false; |
201 | if (currentPage()->aboutToSave()) { |
202 | currentPage()->save(); |
203 | return true; |
204 | } |
205 | return false; |
206 | } |
207 | |
208 | |
209 | void SettingsDlg::undoChanges() |
210 | { |
211 | if (currentPage()) { |
212 | currentPage()->load(); |
213 | } |
214 | } |
215 | |
216 | |
217 | void SettingsDlg::reload() |
218 | { |
219 | if (!currentPage()) return; |
220 | int ret = QMessageBox::question(this, tr("Reload Settings" ), tr("Do you like to reload the settings, undoing your changes on this page?" ), |
221 | QMessageBox::Yes|QMessageBox::No, QMessageBox::No); |
222 | if (ret == QMessageBox::Yes) { |
223 | currentPage()->load(); |
224 | } |
225 | } |
226 | |
227 | |
228 | void SettingsDlg::loadDefaults() |
229 | { |
230 | if (!currentPage()) return; |
231 | int ret = QMessageBox::question(this, tr("Restore Defaults" ), tr("Do you like to restore the default values for this page?" ), |
232 | QMessageBox::RestoreDefaults|QMessageBox::Cancel, QMessageBox::Cancel); |
233 | if (ret == QMessageBox::RestoreDefaults) { |
234 | currentPage()->defaults(); |
235 | } |
236 | } |
237 | |