Rename settingspages.inc to settingspages.cmake
[quassel.git] / src / qtui / settingspages / coreaccountsettingspage.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2013 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 }