Testing the CIA bot.
[quassel.git] / gui / serverlist.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-07 by The Quassel Team                                *
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) any later version.                                   *
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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "serverlist.h"
22 #include "identities.h"
23 #include "guiproxy.h"
24
25 /* NOTE: This dialog holds not only the server list, but also the identities.
26  *       This makes perfect sense given the fact that connections are initiated from
27  *       this dialog, and that the dialog exists during the lifetime of the program.
28  */
29
30 ServerListDlg::ServerListDlg(QWidget *parent) : QDialog(parent) {
31   ui.setupUi(this);
32
33   QSettings settings;
34   settings.beginGroup("GUI");
35   ui.showOnStartup->setChecked(settings.value("ShowServerListOnStartup", true).toBool());
36
37   updateNetworkTree();
38   connect(ui.networkTree, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons()));
39
40   settings.endGroup();
41   // check if we already have a valid identity
42   if(!global->getData("Identities", VarMap()).toMap().contains("Default")) editIdentities(true);
43   connect(this, SIGNAL(requestConnect(QStringList)), guiProxy, SLOT(gsRequestConnect(QStringList)));
44
45   // Autoconnect
46   QStringList list;
47   VarMap networks = global->getData("Networks").toMap();
48   foreach(QString net, networks.keys()) {
49     if(networks[net].toMap()["AutoConnect"].toBool()) {
50       list << net;
51     }
52   }
53   if(!list.isEmpty()) emit requestConnect(list);
54 }
55
56 ServerListDlg::~ServerListDlg() {
57
58 }
59
60 void ServerListDlg::updateNetworkTree() {
61   VarMap networks = global->getData("Networks").toMap();
62   //QStringList headers;
63   //headers << "Network" << "Autoconnect";
64   ui.networkTree->clear();
65   //ui.networkTree->setHeaderLabels(headers);
66   ui.networkTree->setHeaderLabel("Networks");
67   QHash<QString, QTreeWidgetItem *> groups;
68   foreach(QString net, networks.keys()) {
69     VarMap s = networks[net].toMap();
70     QString gr = s["Group"].toString();
71     QTreeWidgetItem *item = 0;
72     if(gr.isEmpty()) {
73       item = new QTreeWidgetItem(ui.networkTree);
74     } else {
75       if(groups.contains(gr)) {
76         item = new QTreeWidgetItem(groups[gr]);
77       } else {
78         QTreeWidgetItem *newgr = new QTreeWidgetItem(ui.networkTree);
79         //ui.networkTree->addTopLevelItem(newgr);
80         newgr->setText(0, gr);
81         newgr->setFlags(newgr->flags() & ~Qt::ItemIsSelectable);
82         groups[gr] = newgr;
83         item = new QTreeWidgetItem(newgr);
84         newgr->setExpanded(true);
85         ui.networkTree->addTopLevelItem(newgr);
86         //ui.networkTree->expandItem(newgr); //<-- buggy Qt?
87       }
88     }
89     item->setText(0, net);
90     item->setToolTip(0, s["Description"].toString());
91     //item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
92     //item->setCheckState(1, Qt::Unchecked);
93   }
94   ui.networkTree->sortItems(0, Qt::AscendingOrder);
95
96 }
97
98 void ServerListDlg::updateButtons() {
99   QList<QTreeWidgetItem *> selected = ui.networkTree->selectedItems();
100   ui.editButton->setEnabled(selected.size() == 1);
101   ui.deleteButton->setEnabled(selected.size() >= 1);
102   ui.connectButton->setEnabled(selected.size() >= 1);
103
104 }
105
106 bool ServerListDlg::showOnStartup() {
107   return ui.showOnStartup->isChecked();
108 }
109
110 void ServerListDlg::on_addButton_clicked() {
111   NetworkEditDlg dlg(this, VarMap());
112   if(dlg.exec() == QDialog::Accepted) {
113     VarMap networks = global->getData("Networks").toMap();
114     VarMap net = dlg.getNetwork();
115     networks[net["Name"].toString()] = net;
116     global->putData("Networks", networks);
117     updateNetworkTree();
118   }
119 }
120
121 void ServerListDlg::on_editButton_clicked() {
122   QString curnet = ui.networkTree->currentItem()->text(0);
123   VarMap networks = global->getData("Networks").toMap();
124   NetworkEditDlg dlg(this, networks[curnet].toMap());
125   if(dlg.exec() == QDialog::Accepted) {
126     VarMap net = dlg.getNetwork();
127     networks.remove(curnet);
128     networks[net["Name"].toString()] = net;
129     global->putData("Networks", networks);
130     updateNetworkTree();
131   }
132 }
133
134 void ServerListDlg::on_deleteButton_clicked() {
135   if(QMessageBox::warning(this, tr("Remove Network?"), tr("Are you sure you want to delete the selected network(s)?"),
136                         QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
137     VarMap networks = global->getData("Networks").toMap();
138     QList<QTreeWidgetItem *> sel = ui.networkTree->selectedItems();
139     foreach(QTreeWidgetItem *item, sel) {
140       networks.remove(item->text(0));
141     }
142     global->putData("Networks", networks);
143     updateNetworkTree();
144   }
145 }
146
147 void ServerListDlg::editIdentities(bool end) {
148   IdentitiesDlg dlg(this);
149   if(dlg.exec() == QDialog::Accepted) {
150     /* Should now all be handled within the dialog class. Global settings rulez0rs. */
151     //identities = dlg.getIdentities();
152     //QMap<QString, QString> mapping = dlg.getNameMapping();
153     // add mapping here  <-- well, I don't fucking know anymore what I meant by this back in 2005...
154
155     //
156     //storeIdentities();
157     //storeNetworks();  // ? how to treat mapping and NOT save changes not yet applied to the server list?
158   }
159   else if(end) exit(0);
160 }
161
162 void ServerListDlg::on_showOnStartup_stateChanged(int) {
163   QSettings s;
164   s.setValue("GUI/ShowServerListOnStartup", ui.showOnStartup->isChecked());
165 }
166
167 void ServerListDlg::accept() {
168   QStringList nets;
169   QList<QTreeWidgetItem *> list = ui.networkTree->selectedItems();
170   foreach(QTreeWidgetItem *item, list) {
171     nets << item->text(0);
172   }
173   emit requestConnect(nets);
174   QDialog::accept();
175 }
176
177 /***************************************************************************/
178
179 NetworkEditDlg::NetworkEditDlg(QWidget *parent, VarMap _network) : QDialog(parent) {
180   ui.setupUi(this);
181   network = _network;
182   oldName = network["Name"].toString();
183
184   connect(ui.serverList, SIGNAL(itemSelectionChanged()), this, SLOT(updateServerButtons()));
185
186   VarMap identities = global->getData("Identities").toMap();
187
188   ui.identityList->addItem(tr("Default Identity"));
189   foreach(QString id, identities.keys()) {
190     if(id != "Default") ui.identityList->addItem(id);
191   }
192   QStringList groups; groups << "";
193   VarMap nets = global->getData("Networks").toMap();
194   foreach(QString net, nets.keys()) {
195     QString gr = nets[net].toMap()["Group"].toString();
196     if(!groups.contains(gr) && !gr.isEmpty()) {
197       groups.append(gr);
198     }
199   }
200   ui.networkGroup->addItems(groups);
201   if(network.size() == 0) network = createDefaultNetwork();
202
203   ui.networkName->setText(network["Name"].toString());
204   if(network["Group"].toString().isEmpty()) ui.networkGroup->setCurrentIndex(0);
205   else ui.networkGroup->setCurrentIndex(ui.networkGroup->findText(network["Group"].toString()));
206   if(network["Identity"].toString().isEmpty() || network["Identity"].toString() == "Default") ui.identityList->setCurrentIndex(0);
207   else ui.identityList->setCurrentIndex(ui.identityList->findText(network["Identity"].toString()));
208   ui.enableAutoConnect->setChecked(network["AutoConnect"].toBool());
209   updateWidgets();
210
211   on_networkName_textChanged(ui.networkName->text());
212   ui.networkName->setFocus();
213 }
214
215 VarMap NetworkEditDlg::createDefaultNetwork() {
216   VarMap net;
217
218   net["Name"] = QString();
219   net["Group"] = QString();
220   net["Identity"] = QString("Default");
221
222   return net;
223 }
224
225 void NetworkEditDlg::updateWidgets() {
226   ui.serverList->clear();
227   foreach(QVariant s, network["Servers"].toList()) {
228     VarMap server = s.toMap();
229     QString entry = QString("%1:%2").arg(server["Address"].toString()).arg(server["Port"].toInt());
230     QListWidgetItem *item = new QListWidgetItem(entry);
231     //if(server["Exclude"].toBool()) item->setCheckState(Qt::Checked);
232     ui.serverList->addItem(item);
233   }
234   ui.performEdit->clear();
235   ui.performEdit->setText( network["Perform"].toString() );
236   updateServerButtons();
237 }
238
239 void NetworkEditDlg::updateServerButtons() {
240   Q_ASSERT(ui.serverList->selectedItems().size() <= 1);
241   int curidx;
242   if(ui.serverList->selectedItems().isEmpty()) curidx = -1;
243   else curidx = ui.serverList->row(ui.serverList->selectedItems()[0]);
244   ui.editServer->setEnabled(curidx >= 0);
245   ui.deleteServer->setEnabled(curidx >= 0);
246   ui.upServer->setEnabled(curidx > 0);
247   ui.downServer->setEnabled(curidx >= 0 && curidx < ui.serverList->count() - 1);
248
249 }
250
251 void NetworkEditDlg::on_networkName_textChanged(QString text) {
252   ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
253 }
254
255 void NetworkEditDlg::accept() {
256   QString reason = checkValidity();
257   if(reason.isEmpty()) {
258     network["Name"] = ui.networkName->text();
259     network["Description"] = ui.networkDesc->text();
260     /*if(ui.networkGroup->currentText() == "<none>") network["Group"] = "";
261     else */ network["Group"] = ui.networkGroup->currentText();
262     network["AutoConnect"] = ui.enableAutoConnect->isChecked();
263     network["Perform"] = ui.performEdit->toPlainText();
264     if(ui.identityList->currentIndex()) network["Identity"] = ui.identityList->currentText();
265     else network["Identity"] = "Default";
266     QDialog::accept();
267   } else {
268     QMessageBox::warning(this, tr("Invalid Network Settings!"),
269                          tr("<b>Your network settings are invalid!</b><br>%1").arg(reason));
270   }
271
272 }
273
274 QString NetworkEditDlg::checkValidity() {
275   QString r;
276   VarMap nets = global->getData("Networks").toMap();
277   if(ui.networkName->text() != oldName && nets.keys().contains(ui.networkName->text())) {
278     r += tr(" Network name already exists.");
279   }
280   if(network["Servers"].toList().isEmpty()) {
281     r += tr(" You need to enter at least one server for this network.");
282   }
283   return r;
284 }
285
286 void NetworkEditDlg::on_addServer_clicked() {
287   ServerEditDlg dlg(this);
288   if(dlg.exec() == QDialog::Accepted) {
289     QList<QVariant> list = network["Servers"].toList();
290     list.append(dlg.getServer());
291     network["Servers"] = list;
292     updateWidgets();
293   }
294 }
295
296 void NetworkEditDlg::on_editServer_clicked() {
297   int idx = ui.serverList->currentRow();
298   ServerEditDlg dlg(this, network["Servers"].toList()[idx].toMap());
299   if(dlg.exec() == QDialog::Accepted) {
300     QList<QVariant> list = network["Servers"].toList();
301     list[idx] = dlg.getServer();
302     network["Servers"] = list;
303     updateWidgets();
304   }
305 }
306
307 void NetworkEditDlg::on_deleteServer_clicked() {
308   int idx = ui.serverList->currentRow();
309   QList<QVariant> list = network["Servers"].toList();
310   list.removeAt(idx);
311   network["Servers"] = list;
312   updateWidgets();
313   if(idx < ui.serverList->count()) ui.serverList->setCurrentRow(idx);
314   else if(ui.serverList->count()) ui.serverList->setCurrentRow(ui.serverList->count()-1);
315 }
316
317 void NetworkEditDlg::on_upServer_clicked() {
318   int idx = ui.serverList->currentRow();
319   QList<QVariant> list = network["Servers"].toList();
320   list.swap(idx, idx-1);
321   network["Servers"] = list;
322   updateWidgets();
323   ui.serverList->setCurrentRow(idx-1);
324 }
325
326 void NetworkEditDlg::on_downServer_clicked() {
327   int idx = ui.serverList->currentRow();
328   QList<QVariant> list = network["Servers"].toList();
329   list.swap(idx, idx+1);
330   network["Servers"] = list;
331   updateWidgets();
332   ui.serverList->setCurrentRow(idx+1);
333 }
334
335 void NetworkEditDlg::on_editIdentities_clicked() {
336   QString id;
337   if(ui.identityList->currentIndex() > 0) id = ui.identityList->currentText();
338   else id = "Default";
339   IdentitiesDlg dlg(this, id);
340   if(dlg.exec() == QDialog::Accepted) {
341     VarMap identities = global->getData("Identities").toMap();
342     ui.identityList->clear();
343     ui.identityList->addItem(tr("Default Identity"));
344     foreach(QString i, identities.keys()) {
345       if(i != "Default") ui.identityList->addItem(i);
346     }
347     QMap<QString, QString> mapping = dlg.getNameMapping();
348     if(mapping.contains(id)) id = mapping[id];
349     else id = "Default";
350     if(id != "Default") ui.identityList->setCurrentIndex(ui.identityList->findText(id));
351     else ui.identityList->setCurrentIndex(0);
352     network["Identity"] = id;
353   }
354 }
355
356 /***************************************************************************/
357
358 ServerEditDlg::ServerEditDlg(QWidget *parent, VarMap server) {
359   ui.setupUi(this);
360
361   if(!server.isEmpty()) {
362     ui.serverAddress->setText(server["Address"].toString());
363     ui.serverPort->setValue(server["Port"].toInt());
364   } else {
365     ui.serverAddress->setText(QString());
366     ui.serverPort->setValue(6667);
367   }
368   on_serverAddress_textChanged();
369 }
370
371 void ServerEditDlg::on_serverAddress_textChanged() {
372   ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!ui.serverAddress->text().isEmpty());
373 }
374
375 VarMap ServerEditDlg::getServer() {
376   VarMap s;
377   s["Address"] = ui.serverAddress->text();
378   s["Port"] = ui.serverPort->text();
379   return s;
380 }
381
382
383 /***************************************************************************/