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
28CoreAccountSettingsPage::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
55void CoreAccountSettingsPage::setStandAlone(bool standalone)
56{
57 _standalone = standalone;
58}
59
60
61void 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
87void 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
101void 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
116void 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
131AccountId 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
140void 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
148void 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
159void 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
169void 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
183void 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
196void 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
208void 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
218void CoreAccountSettingsPage::widgetHasChanged()
219{
220 setChangedState(testHasChanged());
221 setWidgetStates();
222}
223
224
225bool 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 *****************************************************************************************/
239CoreAccountEditDlg::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
266CoreAccount 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
284void 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
293void CoreAccountEditDlg::on_hostName_textChanged(const QString &text)
294{
295 Q_UNUSED(text);
296 setWidgetStates();
297}
298
299
300void CoreAccountEditDlg::on_accountName_textChanged(const QString &text)
301{
302 Q_UNUSED(text);
303 setWidgetStates();
304}
305
306
307void CoreAccountEditDlg::on_user_textChanged(const QString &text)
308{
309 Q_UNUSED(text)
310 setWidgetStates();
311}
312
313
314/*****************************************************************************************
315 * FilteredCoreAccountModel
316 *****************************************************************************************/
317
318FilteredCoreAccountModel::FilteredCoreAccountModel(CoreAccountModel *model, QObject *parent) : QSortFilterProxyModel(parent)
319{
320 _internalAccount = model->internalAccount();
321 setSourceModel(model);
322}
323
324
325bool 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