fixing layout issues
[quassel.git] / src / qtui / mainwin.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #include "mainwin.h"
21
22 #include "aboutdlg.h"
23 #include "chatwidget.h"
24 #include "bufferview.h"
25 #include "bufferviewconfig.h"
26 #include "bufferviewfilter.h"
27 #include "bufferviewmanager.h"
28 #include "chatline-old.h"
29 #include "client.h"
30 #include "clientbacklogmanager.h"
31 #include "coreconnectdlg.h"
32 #include "networkmodel.h"
33 #include "buffermodel.h"
34 #include "nicklistwidget.h"
35 #include "settingsdlg.h"
36 #include "settingspagedlg.h"
37 #include "signalproxy.h"
38 #include "topicwidget.h"
39 #include "inputwidget.h"
40 #include "verticaldock.h"
41 #include "uisettings.h"
42 #include "qtuisettings.h"
43 #include "jumpkeyhandler.h"
44
45 #include "uisettings.h"
46
47 #include "selectionmodelsynchronizer.h"
48 #include "mappedselectionmodel.h"
49
50 #include "settingspages/appearancesettingspage.h"
51 #include "settingspages/bufferviewsettingspage.h"
52 #include "settingspages/colorsettingspage.h"
53 #include "settingspages/fontssettingspage.h"
54 #include "settingspages/generalsettingspage.h"
55 #include "settingspages/highlightsettingspage.h"
56 #include "settingspages/identitiessettingspage.h"
57 #include "settingspages/networkssettingspage.h"
58
59
60 #include "debugconsole.h"
61 #include "global.h"
62 #include "qtuistyle.h"
63
64 MainWin::MainWin(QtUi *_gui, QWidget *parent)
65   : QMainWindow(parent),
66     gui(_gui),
67     sslLabel(new QLabel()),
68     systray(new QSystemTrayIcon(this)),
69     activeTrayIcon(":/icons/quassel-icon-active.png"),
70     onlineTrayIcon(":/icons/quassel-icon.png"),
71     offlineTrayIcon(":/icons/quassel-icon-offline.png"),
72     trayIconActive(false),
73     timer(new QTimer(this)),
74     settingsDlg(new SettingsDlg(this)),
75     debugConsole(new DebugConsole(this))
76 {
77   ui.setupUi(this);
78   setWindowTitle("Quassel IRC");
79   setWindowIcon(offlineTrayIcon);
80   systray->setIcon(offlineTrayIcon);
81   setWindowIconText("Quassel IRC");
82
83   statusBar()->showMessage(tr("Waiting for core..."));
84
85   installEventFilter(new JumpKeyHandler(this));
86
87   UiSettings uiSettings;
88   QString style = uiSettings.value("Style", QString("")).toString();
89   if(style != "") {
90     QApplication::setStyle(style);
91   }
92 }
93
94 void MainWin::init() {
95   QtUiSettings s;
96   if(s.value("MainWinSize").isValid())
97     resize(s.value("MainWinSize").toSize());
98   else
99     resize(QSize(800, 500));
100
101   Client::signalProxy()->attachSignal(this, SIGNAL(requestBacklog(BufferInfo, QVariant, QVariant)));
102
103   connect(Client::instance(), SIGNAL(networkCreated(NetworkId)), this, SLOT(clientNetworkCreated(NetworkId)));
104   connect(Client::instance(), SIGNAL(networkRemoved(NetworkId)), this, SLOT(clientNetworkRemoved(NetworkId)));
105   //ui.bufferWidget->init();
106
107   show();
108
109   statusBar()->showMessage(tr("Not connected to core."));
110
111   // DOCK OPTIONS
112   setDockNestingEnabled(true);
113
114   setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
115   setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
116   setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
117   setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
118
119   // setup stuff...
120   setupMenus();
121   setupViews();
122   setupNickWidget();
123   setupTopicWidget();
124   setupChatMonitor();
125   setupInputWidget();
126   setupStatusBar();
127   setupSystray();
128
129   setupSettingsDlg();
130
131   // restore mainwin state
132   restoreState(s.value("MainWinState").toByteArray());
133
134   setDisconnectedState();  // Disable menus and stuff
135   showCoreConnectionDlg(true); // autoconnect if appropriate
136
137   // attach the BufferWidget to the BufferModel and the default selection
138   ui.bufferWidget->setModel(Client::bufferModel());
139   ui.bufferWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
140
141 }
142
143 MainWin::~MainWin() {
144   QtUiSettings s;
145   s.setValue("MainWinSize", size());
146   s.setValue("MainWinPos", pos());
147   s.setValue("MainWinState", saveState());
148 }
149
150 void MainWin::setupMenus() {
151   connect(ui.actionConnectCore, SIGNAL(triggered()), this, SLOT(showCoreConnectionDlg()));
152   connect(ui.actionDisconnectCore, SIGNAL(triggered()), Client::instance(), SLOT(disconnectFromCore()));
153   connect(ui.actionQuit, SIGNAL(triggered()), QCoreApplication::instance(), SLOT(quit()));
154   //connect(ui.actionNetworkList, SIGNAL(triggered()), this, SLOT(showServerList()));
155   connect(ui.actionSettingsDlg, SIGNAL(triggered()), this, SLOT(showSettingsDlg()));
156   connect(ui.actionDebug_Console, SIGNAL(triggered()), this, SLOT(showDebugConsole()));
157   connect(ui.actionAboutQuassel, SIGNAL(triggered()), this, SLOT(showAboutDlg()));
158   connect(ui.actionAboutQt, SIGNAL(triggered()), QApplication::instance(), SLOT(aboutQt()));
159
160   actionEditNetworks = new QAction(QIcon(":/22x22/actions/configure"), tr("Edit &Networks..."), this);
161   ui.menuNetworks->addAction(actionEditNetworks);
162   connect(actionEditNetworks, SIGNAL(triggered()), this, SLOT(showNetworkDlg()));
163   connect(ui.actionManageViews, SIGNAL(triggered()), this, SLOT(showManageViewsDlg()));
164 }
165
166 void MainWin::setupViews() {
167   QAction *separator = ui.menuViews->addSeparator();
168   separator->setData("__EOBV__");
169   addBufferView();
170 }
171
172 void MainWin::addBufferView(int bufferViewConfigId) {
173   addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewConfigId));
174 }
175
176 void MainWin::addBufferView(BufferViewConfig *config) {
177   BufferViewDock *dock;
178   if(config)
179     dock = new BufferViewDock(config, this);
180   else
181     dock = new BufferViewDock(this);
182
183   //create the view and initialize it's filter
184   BufferView *view = new BufferView(dock);
185   view->setFilteredModel(Client::bufferModel(), config);
186   view->show();
187
188   Client::bufferModel()->synchronizeView(view);
189
190   dock->setWidget(view);
191   dock->show();
192
193   addDockWidget(Qt::LeftDockWidgetArea, dock);
194
195   QAction *endOfBufferViews = 0;
196   foreach(QAction *action, ui.menuViews->actions()) {
197     if(action->data().toString() == "__EOBV__") {
198       endOfBufferViews = action;
199       break;
200     }
201   }
202   Q_CHECK_PTR(endOfBufferViews);
203   ui.menuViews->insertAction(endOfBufferViews, dock->toggleViewAction());
204
205   _netViews.append(dock);
206 }
207
208 void MainWin::removeBufferView(int bufferViewConfigId) {
209   QVariant actionData;
210   BufferViewDock *dock;
211   foreach(QAction *action, ui.menuViews->actions()) {
212     actionData = action->data();
213     if(!actionData.isValid())
214       continue;
215     
216     if(actionData.toString() == "__EOBV__")
217       break;
218
219     dock = qobject_cast<BufferViewDock *>(action->parent());
220     if(dock && actionData.toInt() == bufferViewConfigId) {
221       removeAction(action);
222       dock->deleteLater();
223     }
224   }
225 }
226
227 void MainWin::setupSettingsDlg() {
228   //Category: Appearance
229   settingsDlg->registerSettingsPage(new ColorSettingsPage(settingsDlg));
230   settingsDlg->registerSettingsPage(new FontsSettingsPage(settingsDlg));
231   settingsDlg->registerSettingsPage(new AppearanceSettingsPage(settingsDlg)); //General
232   //Category: Behaviour
233   settingsDlg->registerSettingsPage(new GeneralSettingsPage(settingsDlg));
234   settingsDlg->registerSettingsPage(new HighlightSettingsPage(settingsDlg));
235   //Category: General
236   settingsDlg->registerSettingsPage(new IdentitiesSettingsPage(settingsDlg));
237   settingsDlg->registerSettingsPage(new NetworksSettingsPage(settingsDlg));
238   settingsDlg->registerSettingsPage(new BufferViewSettingsPage(settingsDlg));
239 }
240
241 void MainWin::showNetworkDlg() {
242   SettingsPageDlg dlg(new NetworksSettingsPage(this), this);
243   dlg.exec();
244 }
245
246 void MainWin::showManageViewsDlg() {
247   SettingsPageDlg dlg(new BufferViewSettingsPage(this), this);
248   dlg.exec();
249 }
250
251 void MainWin::setupNickWidget() {
252   // create nick dock
253   NickListDock *nickDock = new NickListDock(tr("Nicks"), this);
254   nickDock->setObjectName("NickDock");
255   nickDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
256
257   nickListWidget = new NickListWidget(nickDock);
258   nickDock->setWidget(nickListWidget);
259
260   addDockWidget(Qt::RightDockWidgetArea, nickDock);
261   ui.menuViews->addAction(nickDock->toggleViewAction());
262   connect(nickDock->toggleViewAction(), SIGNAL(triggered(bool)), nickListWidget, SLOT(showWidget(bool)));
263
264   // attach the NickListWidget to the BufferModel and the default selection
265   nickListWidget->setModel(Client::bufferModel());
266   nickListWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
267 }
268
269 void MainWin::setupChatMonitor() {
270   VerticalDock *dock = new VerticalDock(tr("Chat Monitor"), this);
271   dock->setObjectName("ChatMonitorDock");
272
273   ChatWidget *chatWidget = new ChatWidget(0, this);
274   chatWidget->show();
275   dock->setWidget(chatWidget);
276   dock->show();
277
278   Buffer *buf = Client::monitorBuffer();
279   if(!buf)
280     return;
281
282   chatWidget->setContents(buf->contents());
283   connect(buf, SIGNAL(msgAppended(AbstractUiMsg *)), chatWidget, SLOT(appendMsg(AbstractUiMsg *)));
284   connect(buf, SIGNAL(msgPrepended(AbstractUiMsg *)), chatWidget, SLOT(prependMsg(AbstractUiMsg *)));
285
286   addDockWidget(Qt::TopDockWidgetArea, dock, Qt::Vertical);
287   ui.menuViews->addAction(dock->toggleViewAction());
288 }
289
290 void MainWin::setupInputWidget() {
291   VerticalDock *dock = new VerticalDock(tr("Inputline"), this);
292   dock->setObjectName("InputDock");
293
294   InputWidget *inputWidget = new InputWidget(dock);
295   dock->setWidget(inputWidget);
296
297   addDockWidget(Qt::BottomDockWidgetArea, dock);
298
299   ui.menuViews->addAction(dock->toggleViewAction());
300
301   inputWidget->setModel(Client::bufferModel());
302   inputWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
303
304   ui.bufferWidget->setFocusProxy(inputWidget);
305 }
306
307 void MainWin::setupTopicWidget() {
308   VerticalDock *dock = new VerticalDock(tr("Topic"), this);
309   dock->setObjectName("TopicDock");
310   TopicWidget *topicwidget = new TopicWidget(dock);
311   connect(topicwidget, SIGNAL(topicChanged(const QString &)), this, SLOT(changeTopic(const QString &)));
312
313   dock->setWidget(topicwidget);
314
315   topicwidget->setModel(Client::bufferModel());
316   topicwidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
317
318   addDockWidget(Qt::TopDockWidgetArea, dock);
319
320   ui.menuViews->addAction(dock->toggleViewAction());
321 }
322
323 void MainWin::setupStatusBar() {
324   connect(Client::instance(), SIGNAL(securedConnection()), this, SLOT(securedConnection()));
325   sslLabel->setPixmap(QPixmap());
326   statusBar()->addPermanentWidget(sslLabel);
327
328   ui.menuViews->addSeparator();
329   QAction *showStatusbar = ui.menuViews->addAction(tr("Statusbar"));
330   showStatusbar->setCheckable(true);
331
332   UiSettings uiSettings;
333
334   bool enabled = uiSettings.value("ShowStatusBar", QVariant(true)).toBool();
335   showStatusbar->setChecked(enabled);
336   enabled ? statusBar()->show() : statusBar()->hide();
337
338   connect(showStatusbar, SIGNAL(toggled(bool)), statusBar(), SLOT(setVisible(bool)));
339   connect(showStatusbar, SIGNAL(toggled(bool)), this, SLOT(saveStatusBarStatus(bool)));
340 }
341
342 void MainWin::saveStatusBarStatus(bool enabled) {
343   UiSettings uiSettings;
344   uiSettings.setValue("ShowStatusBar", enabled);
345 }
346
347 void MainWin::setupSystray() {
348   connect(timer, SIGNAL(timeout()), this, SLOT(makeTrayIconBlink()));
349   connect(Client::instance(), SIGNAL(messageReceived(const Message &)), this, SLOT(receiveMessage(const Message &)));
350
351   systrayMenu = new QMenu(this);
352   systrayMenu->addAction(ui.actionAboutQuassel);
353   systrayMenu->addSeparator();
354   systrayMenu->addAction(ui.actionConnectCore);
355   systrayMenu->addAction(ui.actionDisconnectCore);
356   systrayMenu->addSeparator();
357   systrayMenu->addAction(ui.actionQuit);
358
359   systray->setContextMenu(systrayMenu);
360
361   UiSettings s;
362   if(s.value("UseSystemTrayIcon", QVariant(true)).toBool()) {
363     systray->show();
364   }
365
366 #ifndef Q_WS_MAC
367   connect(systray, SIGNAL(activated( QSystemTrayIcon::ActivationReason )),
368           this, SLOT(systrayActivated( QSystemTrayIcon::ActivationReason )));
369 #endif
370
371 }
372
373 void MainWin::changeEvent(QEvent *event) {
374   if(event->type() == QEvent::WindowStateChange) {
375     if(windowState() & Qt::WindowMinimized) {
376       UiSettings s;
377       if(s.value("UseSystemTrayIcon").toBool() && s.value("MinimizeOnMinimize").toBool()) {
378         toggleVisibility();
379         event->ignore();
380       }
381     }
382   }
383 }
384
385 // FIXME this should be made prettier...
386 void MainWin::changeTopic(const QString &topic) {
387   BufferId id = ui.bufferWidget->currentBuffer();
388   if(!id.isValid()) return;
389   Buffer *buffer = Client::buffer(id);
390   if(buffer) Client::userInput(buffer->bufferInfo(), QString("/topic %1").arg(topic));
391 }
392
393 void MainWin::connectedToCore() {
394   Q_CHECK_PTR(Client::bufferViewManager());
395   connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigAdded(int)), this, SLOT(addBufferView(int)));
396   connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigDeleted(int)), this, SLOT(removeBufferView(int)));
397   connect(Client::bufferViewManager(), SIGNAL(initDone()), this, SLOT(loadLayout()));
398   
399   foreach(BufferInfo id, Client::allBufferInfos()) {
400     Client::backlogManager()->requestBacklog(id.bufferId(), 500, -1);
401   }
402   setConnectedState();
403 }
404
405 void MainWin::setConnectedState() {
406   ui.menuViews->setEnabled(true);
407   //ui.menuCore->setEnabled(true);
408   ui.actionConnectCore->setEnabled(false);
409   ui.actionDisconnectCore->setEnabled(true);
410   //ui.actionNetworkList->setEnabled(true);
411   ui.bufferWidget->show();
412   statusBar()->showMessage(tr("Connected to core."));
413   setWindowIcon(onlineTrayIcon);
414   systray->setIcon(onlineTrayIcon);
415   if(sslLabel->width() == 0)
416     sslLabel->setPixmap(QPixmap::fromImage(QImage(":/16x16/status/no-ssl")));
417 }
418
419 void MainWin::loadLayout() {
420   QtUiSettings s;
421   int accountId = Client::currentCoreAccount().toInt();
422   restoreState(s.value(QString("MainWinState-%1").arg(accountId)).toByteArray(), accountId);
423 }
424
425 void MainWin::securedConnection() {
426   // todo: make status bar entry
427   qDebug() << "secured the connection";
428
429   sslLabel->setPixmap(QPixmap::fromImage(QImage(":/16x16/status/ssl")));
430 }
431
432 void MainWin::disconnectedFromCore() {
433   // save core specific layout and remove bufferviews;
434   QtUiSettings s;
435   int accountId = Client::currentCoreAccount().toInt();
436   s.setValue(QString("MainWinState-%1").arg(accountId) , saveState(accountId));
437   QVariant actionData;
438   BufferViewDock *dock;
439   foreach(QAction *action, ui.menuViews->actions()) {
440     actionData = action->data();
441     if(!actionData.isValid())
442       continue;
443     
444     if(actionData.toString() == "__EOBV__")
445       break;
446
447     dock = qobject_cast<BufferViewDock *>(action->parent());
448     if(dock && actionData.toInt() != -1) {
449       removeAction(action);
450       dock->deleteLater();
451     }
452   }
453   restoreState(s.value("MainWinState").toByteArray());
454   setDisconnectedState();
455 }
456
457 void MainWin::setDisconnectedState() {
458   ui.menuViews->setEnabled(false);
459   //ui.menuCore->setEnabled(false);
460   ui.actionDisconnectCore->setEnabled(false);
461   //ui.actionNetworkList->setEnabled(false);
462   ui.bufferWidget->hide();
463   ui.actionConnectCore->setEnabled(true);
464   // nickListWidget->reset();
465   statusBar()->showMessage(tr("Not connected to core."));
466   setWindowIcon(offlineTrayIcon);
467   systray->setIcon(offlineTrayIcon);
468   sslLabel->setPixmap(QPixmap());
469 }
470
471 AbstractUiMsg *MainWin::layoutMsg(const Message &msg) {
472   return new ChatLineOld(msg);
473 }
474
475 void MainWin::showCoreConnectionDlg(bool autoConnect) {
476   coreConnectDlg = new CoreConnectDlg(this, autoConnect);
477   connect(coreConnectDlg, SIGNAL(finished(int)), this, SLOT(coreConnectionDlgFinished(int)));
478   coreConnectDlg->setModal(true);
479   coreConnectDlg->show();
480 }
481
482 void MainWin::coreConnectionDlgFinished(int /*code*/) {
483   coreConnectDlg->close();
484   //exit(1);
485 }
486
487 void MainWin::showSettingsDlg() {
488   settingsDlg->show();
489 }
490
491 void MainWin::showDebugConsole() {
492   debugConsole->show();
493 }
494
495 void MainWin::showAboutDlg() {
496   AboutDlg dlg(this);
497   dlg.exec();
498 }
499
500 void MainWin::closeEvent(QCloseEvent *event) {
501   UiSettings s;
502   if(s.value("UseSystemTrayIcon").toBool() && s.value("MinimizeOnClose").toBool()) {
503     toggleVisibility();
504     event->ignore();
505   } else {
506     event->accept();
507   }
508 }
509
510 void MainWin::systrayActivated( QSystemTrayIcon::ActivationReason activationReason) {
511   if (activationReason == QSystemTrayIcon::Trigger) {
512     toggleVisibility();
513   }
514 }
515
516 void MainWin::toggleVisibility() {
517   if(isHidden() /*|| !isActiveWindow()*/) {
518     show();
519     if(isMinimized())
520       if (isMaximized())
521         showMaximized();
522       else
523         showNormal();
524
525     raise();
526     activateWindow();
527     // setFocus(); //Qt::ActiveWindowFocusReason
528
529   } else {
530     if(systray->isSystemTrayAvailable ()) {
531       clearFocus();
532       hide();
533       if(!systray->isVisible()) {
534         systray->show();
535       }
536     } else {
537       lower();
538     }
539   }
540 }
541
542 void MainWin::receiveMessage(const Message &msg) {
543   if(QApplication::activeWindow() != 0)
544     return;
545
546   if(msg.flags() & Message::Highlight || msg.bufferInfo().type() == BufferInfo::QueryBuffer) {
547     QString title = msg.bufferInfo().bufferName();;
548     if(msg.bufferInfo().type() != BufferInfo::QueryBuffer) {
549       QString sender = msg.sender();
550       int i = sender.indexOf("!");
551       if(i != -1)
552         sender = sender.left(i);
553       title += QString(" - %1").arg(sender);
554     }
555
556     UiSettings uiSettings;
557
558     if(uiSettings.value("DisplayPopupMessages", QVariant(true)).toBool()) {
559       // FIXME don't invoke style engine for this!
560       QString text = QtUi::style()->styleString(Message::mircToInternal(msg.text())).text;
561       displayTrayIconMessage(title, text);
562     }
563
564     if(uiSettings.value("AnimateTrayIcon", QVariant(true)).toBool()) {
565       QApplication::alert(this);
566       setTrayIconActivity(true);
567     }
568   }
569 }
570
571 bool MainWin::event(QEvent *event) {
572   if(event->type() == QEvent::WindowActivate)
573     setTrayIconActivity(false);
574   return QMainWindow::event(event);
575 }
576
577 void MainWin::displayTrayIconMessage(const QString &title, const QString &message) {
578   systray->showMessage(title, message);
579 }
580
581 void MainWin::setTrayIconActivity(bool active) {
582   if(active) {
583     if(!timer->isActive())
584       timer->start(500);
585   } else {
586     timer->stop();
587     systray->setIcon(onlineTrayIcon);
588   }
589 }
590
591 void MainWin::makeTrayIconBlink() {
592   if(trayIconActive) {
593     systray->setIcon(onlineTrayIcon);
594     trayIconActive = false;
595   } else {
596     systray->setIcon(activeTrayIcon);
597     trayIconActive = true;
598   }
599 }
600
601
602 void MainWin::clientNetworkCreated(NetworkId id) {
603   const Network *net = Client::network(id);
604   QAction *act = new QAction(net->networkName(), this);
605   act->setData(QVariant::fromValue<NetworkId>(id));
606   connect(net, SIGNAL(updatedRemotely()), this, SLOT(clientNetworkUpdated()));
607   connect(act, SIGNAL(triggered()), this, SLOT(connectOrDisconnectFromNet()));
608   bool inserted = false;
609   for(int i = 0; i < networkActions.count(); i++) {
610     if(net->networkName().localeAwareCompare(networkActions[i]->text()) < 0) {
611       networkActions.insert(i, act);
612       inserted = true;
613       break;
614     }
615   }
616   if(!inserted) networkActions.append(act);
617   ui.menuNetworks->clear();  // why the f*** isn't there a QMenu::insertAction()???
618   foreach(QAction *a, networkActions) ui.menuNetworks->addAction(a);
619   ui.menuNetworks->addSeparator();
620   ui.menuNetworks->addAction(actionEditNetworks);
621 }
622
623 void MainWin::clientNetworkUpdated() {
624   const Network *net = qobject_cast<const Network *>(sender());
625   if(!net) return;
626   foreach(QAction *a, networkActions) {
627     if(a->data().value<NetworkId>() == net->networkId()) {
628       a->setText(net->networkName());
629       if(net->connectionState() == Network::Initialized) {
630         a->setIcon(QIcon(":/16x16/actions/network-connect"));
631         //a->setEnabled(true);
632       } else if(net->connectionState() == Network::Disconnected) {
633         a->setIcon(QIcon(":/16x16/actions/network-disconnect"));
634         //a->setEnabled(true);
635       } else {
636         a->setIcon(QIcon(":/16x16/actions/gear"));
637         //a->setEnabled(false);
638       }
639       return;
640     }
641   }
642 }
643
644 void MainWin::clientNetworkRemoved(NetworkId id) {
645   QList<QAction *>::iterator actionIter = networkActions.begin();;
646   QAction *action;
647   while(actionIter != networkActions.end()) {
648     action = *actionIter;
649     if(action->data().value<NetworkId>() == id) {
650       action->deleteLater();
651       actionIter = networkActions.erase(actionIter);
652     } else
653       actionIter++;
654   }
655 }
656
657 void MainWin::connectOrDisconnectFromNet() {
658   QAction *act = qobject_cast<QAction *>(sender());
659   if(!act) return;
660   const Network *net = Client::network(act->data().value<NetworkId>());
661   if(!net) return;
662   if(net->connectionState() == Network::Disconnected) net->requestConnect();
663   else net->requestDisconnect();
664 }
665