6ea4091c3727d1c69cb551c85f984f4fc88cf684
[quassel.git] / gui / mainwin.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005 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 <QtGui>
22 #include <QtCore>
23
24 #include "global.h"
25 #include "message.h"
26 #include "guiproxy.h"
27
28 #include "mainwin.h"
29 #include "buffer.h"
30 #include "networkview.h"
31 #include "serverlist.h"
32 #include "coreconnectdlg.h"
33
34 MainWin::MainWin() : QMainWindow() {
35   ui.setupUi(this);
36   widget = 0;
37
38   setWindowTitle("Quassel IRC");
39   setWindowIcon(QIcon(":/qirc-icon.png"));
40   setWindowIconText("Quassel IRC");
41
42   QSettings s;
43   s.beginGroup("Geometry");
44   resize(s.value("MainWinSize", QSize(500, 400)).toSize());
45   move(s.value("MainWinPos", QPoint(50, 50)).toPoint());
46   s.endGroup();
47
48   workspace = new QWorkspace(this);
49   setCentralWidget(workspace);
50   statusBar()->showMessage(tr("Waiting for core..."));
51
52   netView = new NetworkView("", this);
53   netView->setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea);
54   addDockWidget(Qt::LeftDockWidgetArea, netView);
55   connect(netView, SIGNAL(bufferSelected(QString, QString)), this, SLOT(showBuffer(QString, QString)));
56   connect(this, SIGNAL(bufferSelected(QString, QString)), netView, SLOT(selectBuffer(QString, QString)));
57
58   connect(guiProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant)));
59   connect(guiProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString)));
60   connect(guiProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString)));
61   connect(guiProxy, SIGNAL(csDisplayMsg(QString, Message)), this, SLOT(recvMessage(QString, Message)));
62   connect(guiProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString)));
63   connect(guiProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
64   connect(guiProxy, SIGNAL(csSetNicks(QString, QString, QStringList)), this, SLOT(setNicks(QString, QString, QStringList)));
65   connect(guiProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap)));
66   connect(guiProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString)));
67   connect(guiProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString)));
68   connect(guiProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap)));
69   connect(guiProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString)));
70   connect(this, SIGNAL(sendInput( QString, QString, QString )), guiProxy, SLOT(gsUserInput(QString, QString, QString)));
71
72   show();
73   syncToCore();
74   statusBar()->showMessage(tr("Ready."));
75
76   buffersUpdated();
77
78   serverListDlg = new ServerListDlg(this);
79   serverListDlg->setVisible(serverListDlg->showOnStartup());
80   setupMenus();
81
82   // replay backlog
83   foreach(QString net, coreBackLog.keys()) {
84     while(coreBackLog[net].count()) {
85       recvMessage(net, coreBackLog[net].takeFirst());
86     }
87   }
88   /*
89   foreach(QString key, buffers.keys()) {
90     foreach(Buffer *b, buffers[key].values()) {
91       QWidget *widget = b->showWidget(this);
92       workspace->addWindow(widget);
93       widget->show();
94     }
95   }
96   */
97   s.beginGroup("Buffers");
98   QString net = s.value("CurrentNetwork", "").toString();
99   QString buf = s.value("CurrentBuffer", "").toString();
100   s.endGroup();
101   if(!net.isEmpty()) {
102     if(buffers.contains(net)) {
103       if(buffers[net].contains(buf)) {
104         showBuffer(net, buf);
105       } else {
106         showBuffer(net, "");
107       }
108     }
109   }
110 }
111
112 void MainWin::setupMenus() {
113   connect(ui.actionNetworkList, SIGNAL(activated()), this, SLOT(showServerList()));
114   connect(ui.actionEditIdentities, SIGNAL(activated()), serverListDlg, SLOT(editIdentities()));
115 }
116
117 void MainWin::showServerList() {
118 //  if(!serverListDlg) {
119 //    serverListDlg = new ServerListDlg(this);
120 //  }
121   serverListDlg->show();
122 }
123
124 void MainWin::closeEvent(QCloseEvent *event)
125 {
126   //if (userReallyWantsToQuit()) {
127     QSettings s;
128     s.beginGroup("Geometry");
129     s.setValue("MainWinSize", size());
130     s.setValue("MainWinPos", pos());
131     s.endGroup();
132     s.beginGroup("Buffers");
133     s.setValue("CurrentNetwork", currentNetwork);
134     s.setValue("CurrentBuffer", currentBuffer);
135     s.endGroup();
136     event->accept();
137   //} else {
138     //event->ignore();
139   //}
140 }
141
142 void MainWin::showBuffer(QString net, QString buf) {
143   currentBuffer = buf; currentNetwork = net;
144   Buffer *b = getBuffer(net, buf);
145   QWidget *old = widget;
146   widget = b->showWidget(this);
147   if(widget == old) return;
148   workspace->addWindow(widget);
149   widget->showMaximized();
150   if(old) { old->close(); old->setParent(this); }
151   workspace->setActiveWindow(widget);
152   //widget->setFocus();
153   //workspace->setFocus();
154   //widget->activateWindow();
155   widget->setFocus(Qt::MouseFocusReason);
156   focusNextChild();
157   //workspace->tile();
158   emit bufferSelected(net, buf);
159 }
160
161 void MainWin::networkConnected(QString net) {
162   connected[net] = true;
163   Buffer *b = getBuffer(net, "");
164   b->setActive(true);
165   b->displayMsg(Message::server("", tr("Connected.")));
166   buffersUpdated();
167 }
168
169 void MainWin::networkDisconnected(QString net) {
170   //getBuffer(net, "")->setActive(false);
171   foreach(QString buf, buffers[net].keys()) {
172     Buffer *b = getBuffer(net, buf);
173     b->displayMsg(Message::server(buf, tr("Server disconnected.")));
174     b->setActive(false);
175     
176   }
177   connected[net] = false;
178 }
179
180 Buffer * MainWin::getBuffer(QString net, QString buf) {
181   if(!buffers[net].contains(buf)) {
182     Buffer *b = new Buffer(net, buf);
183     b->setOwnNick(ownNick[net]);
184     connect(b, SIGNAL(userInput(QString, QString, QString)), this, SLOT(userInput(QString, QString, QString)));
185     buffers[net][buf] = b;
186     buffersUpdated();
187   }
188   return buffers[net][buf];
189 }
190
191 void MainWin::buffersUpdated() {
192   netView->buffersUpdated(buffers);
193 }
194
195 void MainWin::recvNetworkState(QString net, QVariant state) {
196   connected[net] = true;
197   setOwnNick(net, state.toMap()["OwnNick"].toString());
198   getBuffer(net, "")->setActive(true);
199   VarMap t = state.toMap()["Topics"].toMap();
200   VarMap n = state.toMap()["Nicks"].toMap();
201   foreach(QString buf, t.keys()) {
202     getBuffer(net, buf)->setActive(true);
203     setTopic(net, buf, t[buf].toString());
204   }
205   foreach(QString nick, n.keys()) {
206     addNick(net, nick, n[nick].toMap());
207   }
208   buffersUpdated();
209 }
210
211 void MainWin::recvMessage(QString net, Message msg) {
212   Buffer *b = getBuffer(net, msg.target);
213   b->displayMsg(msg);
214 }
215
216 void MainWin::recvStatusMsg(QString net, QString msg) {
217   recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg)));
218
219 }
220
221 void MainWin::userInput(QString net, QString buf, QString msg) {
222   emit sendInput(net, buf, msg);
223 }
224
225 void MainWin::setTopic(QString net, QString buf, QString topic) {
226   if(!connected[net]) return;
227   Buffer *b = getBuffer(net, buf);
228   b->setTopic(topic);
229   buffersUpdated();
230   //if(!b->isActive()) {
231   //  b->setActive(true);
232   //  buffersUpdated();
233   //}
234 }
235
236 void MainWin::setNicks(QString net, QString buf, QStringList nicks) {
237   Q_ASSERT(false);
238 }
239
240 void MainWin::addNick(QString net, QString nick, VarMap props) {
241   if(!connected[net]) return;
242   nicks[net][nick] = props;
243   VarMap chans = props["Channels"].toMap();
244   QStringList c = chans.keys();
245   foreach(QString bufname, c) {
246     getBuffer(net, bufname)->addNick(nick, props);
247   }
248   buffersUpdated();
249 }
250
251 void MainWin::renameNick(QString net, QString oldnick, QString newnick) {
252   if(!connected[net]) return;
253   QStringList chans = nicks[net][oldnick]["Channels"].toMap().keys();
254   foreach(QString c, chans) {
255     getBuffer(net, c)->renameNick(oldnick, newnick);
256   }
257   nicks[net][newnick] = nicks[net].take(oldnick);
258 }
259
260 void MainWin::updateNick(QString net, QString nick, VarMap props) {
261   if(!connected[net]) return;
262   QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys();
263   QStringList newchans = props["Channels"].toMap().keys();
264   foreach(QString c, newchans) {
265     if(oldchans.contains(c)) getBuffer(net, c)->updateNick(nick, props);
266     else getBuffer(net, c)->addNick(nick, props);
267   }
268   foreach(QString c, oldchans) {
269     if(!newchans.contains(c)) getBuffer(net, c)->removeNick(nick);
270   }
271   nicks[net][nick] = props;
272   buffersUpdated();
273 }
274
275 void MainWin::removeNick(QString net, QString nick) {
276   if(!connected[net]) return;
277   VarMap chans = nicks[net][nick]["Channels"].toMap();
278   foreach(QString bufname, chans.keys()) {
279     getBuffer(net, bufname)->removeNick(nick);
280   }
281   nicks[net].remove(nick);
282   buffersUpdated();
283 }
284
285 void MainWin::setOwnNick(QString net, QString nick) {
286   if(!connected[net]) return;
287   ownNick[net] = nick;
288   foreach(Buffer *b, buffers[net].values()) {
289     b->setOwnNick(nick);
290   }
291 }
292