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 "coreaccountsettingspage.h" |
22 | |
23 | #include "client.h" |
24 | #include "clientsettings.h" |
25 | #include "coreaccountmodel.h" |
26 | #include "iconloader.h" |
27 | |
28 | CoreAccountSettingsPage::CoreAccountSettingsPage(QWidget *parent) |
29 | : SettingsPage(tr("Remote Cores" ), QString(), parent), |
30 | _lastAccountId(0), |
31 | _lastAutoConnectId(0), |
32 | _standalone(false) |
33 | { |
34 | ui.setupUi(this); |
35 | initAutoWidgets(); |
36 | ui.addAccountButton->setIcon(SmallIcon("list-add" )); |
37 | ui.editAccountButton->setIcon(SmallIcon("document-edit" )); |
38 | ui.deleteAccountButton->setIcon(SmallIcon("edit-delete" )); |
39 | |
40 | _model = new CoreAccountModel(Client::coreAccountModel(), this); |
41 | _filteredModel = new FilteredCoreAccountModel(_model, this); |
42 | |
43 | ui.accountView->setModel(filteredModel()); |
44 | ui.autoConnectAccount->setModel(filteredModel()); |
45 | |
46 | connect(filteredModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); |
47 | connect(filteredModel(), SIGNAL(rowsInserted(QModelIndex, int, int)), SLOT(rowsInserted(QModelIndex, int, int))); |
48 | |
49 | connect(ui.accountView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(setWidgetStates())); |
50 | connect(ui.autoConnectAccount, SIGNAL(currentIndexChanged(int)), SLOT(widgetHasChanged())); |
51 | setWidgetStates(); |
52 | } |
53 | |
54 | |
55 | void CoreAccountSettingsPage::setStandAlone(bool standalone) |
56 | { |
57 | _standalone = standalone; |
58 | } |
59 | |
60 | |
61 | void CoreAccountSettingsPage::load() |
62 | { |
63 | model()->update(Client::coreAccountModel()); |
64 | SettingsPage::load(); |
65 | |
66 | CoreAccountSettings s; |
67 | |
68 | if (Quassel::runMode() != Quassel::Monolithic) { |
69 | // make sure we don't have selected the internal account as autoconnect account |
70 | |
71 | if (s.autoConnectOnStartup() && s.autoConnectToFixedAccount()) { |
72 | CoreAccount acc = model()->account(s.autoConnectAccount()); |
73 | if (acc.isInternal()) |
74 | ui.autoConnectOnStartup->setChecked(false); |
75 | } |
76 | } |
77 | ui.accountView->setCurrentIndex(filteredModel()->index(0, 0)); |
78 | ui.accountView->selectionModel()->select(filteredModel()->index(0, 0), QItemSelectionModel::Select); |
79 | |
80 | QModelIndex idx = filteredModel()->mapFromSource(model()->accountIndex(s.autoConnectAccount())); |
81 | ui.autoConnectAccount->setCurrentIndex(idx.isValid() ? idx.row() : 0); |
82 | ui.autoConnectAccount->setProperty("storedValue" , ui.autoConnectAccount->currentIndex()); |
83 | setWidgetStates(); |
84 | } |
85 | |
86 | |
87 | void CoreAccountSettingsPage::save() |
88 | { |
89 | SettingsPage::save(); |
90 | Client::coreAccountModel()->update(model()); |
91 | Client::coreAccountModel()->save(); |
92 | CoreAccountSettings s; |
93 | AccountId id = filteredModel()->index(ui.autoConnectAccount->currentIndex(), 0).data(CoreAccountModel::AccountIdRole).value<AccountId>(); |
94 | s.setAutoConnectAccount(id); |
95 | ui.autoConnectAccount->setProperty("storedValue" , ui.autoConnectAccount->currentIndex()); |
96 | } |
97 | |
98 | |
99 | // TODO: Qt 4.6 - replace by proper rowsMoved() semantics |
100 | // NOTE: This is the filtered model |
101 | void CoreAccountSettingsPage::rowsAboutToBeRemoved(const QModelIndex &index, int start, int end) |
102 | { |
103 | _lastAutoConnectId = _lastAccountId = 0; |
104 | if (index.isValid() || start != end) |
105 | return; |
106 | |
107 | // the current index is removed, so remember it in case it's reinserted immediately afterwards |
108 | AccountId id = filteredModel()->index(start, 0).data(CoreAccountModel::AccountIdRole).value<AccountId>(); |
109 | if (start == ui.accountView->currentIndex().row()) |
110 | _lastAccountId = id; |
111 | if (start == ui.autoConnectAccount->currentIndex()) |
112 | _lastAutoConnectId = id; |
113 | } |
114 | |
115 | |
116 | void CoreAccountSettingsPage::rowsInserted(const QModelIndex &index, int start, int end) |
117 | { |
118 | if (index.isValid() || start != end) |
119 | return; |
120 | |
121 | // check if the inserted index was just removed and select it in that case |
122 | AccountId id = filteredModel()->index(start, 0).data(CoreAccountModel::AccountIdRole).value<AccountId>(); |
123 | if (id == _lastAccountId) |
124 | ui.accountView->setCurrentIndex(filteredModel()->index(start, 0)); |
125 | if (id == _lastAutoConnectId) |
126 | ui.autoConnectAccount->setCurrentIndex(start); |
127 | _lastAccountId = _lastAutoConnectId = 0; |
128 | } |
129 | |
130 | |
131 | AccountId CoreAccountSettingsPage::selectedAccount() const |
132 | { |
133 | QModelIndex index = ui.accountView->currentIndex(); |
134 | if (!index.isValid()) |
135 | return 0; |
136 | return index.data(CoreAccountModel::AccountIdRole).value<AccountId>(); |
137 | } |
138 | |
139 | |
140 | void CoreAccountSettingsPage::setSelectedAccount(AccountId accId) |
141 | { |
142 | QModelIndex index = filteredModel()->mapFromSource(model()->accountIndex(accId)); |
143 | if (index.isValid()) |
144 | ui.accountView->setCurrentIndex(index); |
145 | } |
146 | |
147 | |
148 | void CoreAccountSettingsPage::on_addAccountButton_clicked() |
149 | { |
150 | CoreAccountEditDlg dlg(CoreAccount(), this); |
151 | if (dlg.exec() == QDialog::Accepted) { |
152 | AccountId id = model()->createOrUpdateAccount(dlg.account()); |
153 | ui.accountView->setCurrentIndex(filteredModel()->mapFromSource(model()->accountIndex(id))); |
154 | widgetHasChanged(); |
155 | } |
156 | } |
157 | |
158 | |
159 | void CoreAccountSettingsPage::on_editAccountButton_clicked() |
160 | { |
161 | QModelIndex idx = ui.accountView->selectionModel()->currentIndex(); |
162 | if (!idx.isValid()) |
163 | return; |
164 | |
165 | editAccount(idx); |
166 | } |
167 | |
168 | |
169 | void CoreAccountSettingsPage::editAccount(const QModelIndex &index) |
170 | { |
171 | if (!index.isValid()) |
172 | return; |
173 | |
174 | CoreAccountEditDlg dlg(model()->account(filteredModel()->mapToSource(index)), this); |
175 | if (dlg.exec() == QDialog::Accepted) { |
176 | AccountId id = model()->createOrUpdateAccount(dlg.account()); |
177 | ui.accountView->setCurrentIndex(filteredModel()->mapFromSource(model()->accountIndex(id))); |
178 | widgetHasChanged(); |
179 | } |
180 | } |
181 | |
182 | |
183 | void CoreAccountSettingsPage::on_deleteAccountButton_clicked() |
184 | { |
185 | if (!ui.accountView->selectionModel()->selectedIndexes().count()) |
186 | return; |
187 | |
188 | AccountId id = ui.accountView->selectionModel()->selectedIndexes().at(0).data(CoreAccountModel::AccountIdRole).value<AccountId>(); |
189 | if (id.isValid()) { |
190 | model()->removeAccount(id); |
191 | widgetHasChanged(); |
192 | } |
193 | } |
194 | |
195 | |
196 | void CoreAccountSettingsPage::on_accountView_doubleClicked(const QModelIndex &index) |
197 | { |
198 | if (!index.isValid()) |
199 | return; |
200 | |
201 | if (isStandAlone()) |
202 | emit connectToCore(index.data(CoreAccountModel::AccountIdRole).value<AccountId>()); |
203 | else |
204 | editAccount(index); |
205 | } |
206 | |
207 | |
208 | void CoreAccountSettingsPage::setWidgetStates() |
209 | { |
210 | AccountId accId = selectedAccount(); |
211 | bool editable = accId.isValid() && accId != model()->internalAccount(); |
212 | |
213 | ui.editAccountButton->setEnabled(editable); |
214 | ui.deleteAccountButton->setEnabled(editable); |
215 | } |
216 | |
217 | |
218 | void CoreAccountSettingsPage::widgetHasChanged() |
219 | { |
220 | setChangedState(testHasChanged()); |
221 | setWidgetStates(); |
222 | } |
223 | |
224 | |
225 | bool CoreAccountSettingsPage::testHasChanged() |
226 | { |
227 | if (ui.autoConnectAccount->currentIndex() != ui.autoConnectAccount->property("storedValue" ).toInt()) |
228 | return true; |
229 | if (!(*model() == *Client::coreAccountModel())) |
230 | return true; |
231 | |
232 | return false; |
233 | } |
234 | |
235 | |
236 | /***************************************************************************************** |
237 | * CoreAccountEditDlg |
238 | *****************************************************************************************/ |
239 | CoreAccountEditDlg::CoreAccountEditDlg(const CoreAccount &acct, QWidget *parent) |
240 | : QDialog(parent) |
241 | { |
242 | ui.setupUi(this); |
243 | |
244 | _account = acct; |
245 | |
246 | ui.hostName->setText(acct.hostName()); |
247 | ui.port->setValue(acct.port()); |
248 | ui.accountName->setText(acct.accountName()); |
249 | ui.user->setText(acct.user()); |
250 | ui.password->setText(acct.password()); |
251 | ui.rememberPassword->setChecked(acct.storePassword()); |
252 | ui.useProxy->setChecked(acct.useProxy()); |
253 | ui.proxyHostName->setText(acct.proxyHostName()); |
254 | ui.proxyPort->setValue(acct.proxyPort()); |
255 | ui.proxyType->setCurrentIndex(acct.proxyType() == QNetworkProxy::Socks5Proxy ? 0 : 1); |
256 | ui.proxyUser->setText(acct.proxyUser()); |
257 | ui.proxyPassword->setText(acct.proxyPassword()); |
258 | |
259 | if (acct.accountId().isValid()) |
260 | setWindowTitle(tr("Edit Core Account" )); |
261 | else |
262 | setWindowTitle(tr("Add Core Account" )); |
263 | } |
264 | |
265 | |
266 | CoreAccount CoreAccountEditDlg::account() |
267 | { |
268 | _account.setAccountName(ui.accountName->text().trimmed()); |
269 | _account.setHostName(ui.hostName->text().trimmed()); |
270 | _account.setPort(ui.port->value()); |
271 | _account.setUser(ui.user->text().trimmed()); |
272 | _account.setPassword(ui.password->text()); |
273 | _account.setStorePassword(ui.rememberPassword->isChecked()); |
274 | _account.setUseProxy(ui.useProxy->isChecked()); |
275 | _account.setProxyHostName(ui.proxyHostName->text().trimmed()); |
276 | _account.setProxyPort(ui.proxyPort->value()); |
277 | _account.setProxyType(ui.proxyType->currentIndex() == 0 ? QNetworkProxy::Socks5Proxy : QNetworkProxy::HttpProxy); |
278 | _account.setProxyUser(ui.proxyUser->text().trimmed()); |
279 | _account.setProxyPassword(ui.proxyPassword->text()); |
280 | return _account; |
281 | } |
282 | |
283 | |
284 | void CoreAccountEditDlg::setWidgetStates() |
285 | { |
286 | bool ok = !ui.accountName->text().trimmed().isEmpty() |
287 | && !ui.user->text().trimmed().isEmpty() |
288 | && !ui.hostName->text().isEmpty(); |
289 | ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok); |
290 | } |
291 | |
292 | |
293 | void CoreAccountEditDlg::on_hostName_textChanged(const QString &text) |
294 | { |
295 | Q_UNUSED(text); |
296 | setWidgetStates(); |
297 | } |
298 | |
299 | |
300 | void CoreAccountEditDlg::on_accountName_textChanged(const QString &text) |
301 | { |
302 | Q_UNUSED(text); |
303 | setWidgetStates(); |
304 | } |
305 | |
306 | |
307 | void CoreAccountEditDlg::on_user_textChanged(const QString &text) |
308 | { |
309 | Q_UNUSED(text) |
310 | setWidgetStates(); |
311 | } |
312 | |
313 | |
314 | /***************************************************************************************** |
315 | * FilteredCoreAccountModel |
316 | *****************************************************************************************/ |
317 | |
318 | FilteredCoreAccountModel::FilteredCoreAccountModel(CoreAccountModel *model, QObject *parent) : QSortFilterProxyModel(parent) |
319 | { |
320 | _internalAccount = model->internalAccount(); |
321 | setSourceModel(model); |
322 | } |
323 | |
324 | |
325 | bool FilteredCoreAccountModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const |
326 | { |
327 | if (Quassel::runMode() == Quassel::Monolithic) |
328 | return true; |
329 | |
330 | if (!_internalAccount.isValid()) |
331 | return true; |
332 | |
333 | return _internalAccount != sourceModel()->index(source_row, 0, source_parent).data(CoreAccountModel::AccountIdRole).value<AccountId>(); |
334 | } |
335 | |