~quassel-dev/quassel/i18n-master

« back to all changes in this revision

Viewing changes to src/qtgui/gui.cpp

  • Committer: Manuel Nickschas
  • Date: 2007-06-20 01:21:00 UTC
  • Revision ID: git-v1:077d44f36d2f5c730283ef6be839aea7dd073d56
Starting reorganization of files in preparation of separation of client and GUI.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "gui.h"
 
22
#include "guiproxy.h"
 
23
#include "mainwin.h"
 
24
#include "buffer.h"
 
25
//#include "bufferview.h"
 
26
#include "bufferviewwidget.h"
 
27
#include "util.h"
 
28
 
 
29
Client * Client::instanceptr = 0;
 
30
 
 
31
Client::ClientMode Client::clientMode;
 
32
QHash<BufferId, Buffer *> Client::buffers;
 
33
QHash<uint, BufferId> Client::bufferIds;
 
34
QHash<QString, QHash<QString, VarMap> > Client::nicks;
 
35
QHash<QString, bool> Client::connected;
 
36
QHash<QString, QString> Client::ownNick;
 
37
QList<BufferId> Client::coreBuffers;
 
38
 
 
39
 
 
40
Client *Client::instance() {
 
41
  if(instanceptr) return instanceptr;
 
42
  instanceptr = new Client();
 
43
  instanceptr->init();
 
44
  return instanceptr;
 
45
}
 
46
 
 
47
void Client::destroy() {
 
48
  delete instanceptr;
 
49
  instanceptr = 0;
 
50
}
 
51
 
 
52
Client::Client() {
 
53
  clientProxy = ClientProxy::instance();
 
54
 
 
55
  //mainWin = new MainWin();
 
56
 
 
57
  _bufferModel = new BufferTreeModel(0);  // FIXME
 
58
 
 
59
  connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *)));
 
60
  connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *)));
 
61
  connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), _bufferModel, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *)));
 
62
 
 
63
    // TODO: make this configurable (allow monolithic client to connect to remote cores)
 
64
  if(Global::runMode == Global::Monolithic) clientMode = LocalCore;
 
65
  else clientMode = RemoteCore;
 
66
}
 
67
 
 
68
void Client::init() {
 
69
  blockSize = 0;
 
70
 
 
71
  connect(&socket, SIGNAL(readyRead()), this, SLOT(serverHasData()));
 
72
  connect(&socket, SIGNAL(connected()), this, SLOT(coreConnected()));
 
73
  connect(&socket, SIGNAL(disconnected()), this, SLOT(coreDisconnected()));
 
74
  connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(serverError(QAbstractSocket::SocketError)));
 
75
 
 
76
  connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(updateCoreData(UserId, QString)));
 
77
  connect(clientProxy, SIGNAL(csUpdateGlobalData(QString, QVariant)), this, SLOT(updateLocalData(QString, QVariant)));
 
78
 
 
79
  connect(clientProxy, SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant)));
 
80
  connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant)));
 
81
  connect(clientProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString)));
 
82
  connect(clientProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString)));
 
83
  connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(Message)));
 
84
  connect(clientProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString)));
 
85
  connect(clientProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
 
86
  connect(clientProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap)));
 
87
  connect(clientProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString)));
 
88
  connect(clientProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString)));
 
89
  connect(clientProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap)));
 
90
  connect(clientProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString)));
 
91
  connect(clientProxy, SIGNAL(csBacklogData(BufferId, QList<QVariant>, bool)), this, SLOT(recvBacklogData(BufferId, QList<QVariant>, bool)));
 
92
  connect(clientProxy, SIGNAL(csUpdateBufferId(BufferId)), this, SLOT(updateBufferId(BufferId)));
 
93
  connect(this, SIGNAL(sendInput(BufferId, QString)), clientProxy, SLOT(gsUserInput(BufferId, QString)));
 
94
  connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), clientProxy, SLOT(gsRequestBacklog(BufferId, QVariant, QVariant)));
 
95
 
 
96
  syncToCore();
 
97
 
 
98
  layoutTimer = new QTimer(this);
 
99
  layoutTimer->setInterval(0);
 
100
  layoutTimer->setSingleShot(false);
 
101
  connect(layoutTimer, SIGNAL(timeout()), this, SLOT(layoutMsg()));
 
102
 
 
103
  /* make lookups by id faster */
 
104
  foreach(BufferId id, coreBuffers) {
 
105
    bufferIds[id.uid()] = id;  // make lookups by id faster
 
106
    buffer(id);                // create all buffers, so we see them in the network views
 
107
    emit requestBacklog(id, -1, -1);  // TODO: use custom settings for backlog request
 
108
  }
 
109
 
 
110
  mainWin = new MainWin();
 
111
  mainWin->init();
 
112
 
 
113
}
 
114
 
 
115
Client::~Client() {
 
116
  delete mainWin;
 
117
  delete _bufferModel;
 
118
  foreach(Buffer *buf, buffers.values()) delete buf;
 
119
  ClientProxy::destroy();
 
120
 
 
121
}
 
122
 
 
123
BufferTreeModel *Client::bufferModel() {
 
124
  return instance()->_bufferModel;
 
125
}
 
126
 
 
127
void Client::coreConnected() {
 
128
 
 
129
}
 
130
 
 
131
void Client::coreDisconnected() {
 
132
 
 
133
}
 
134
 
 
135
void Client::updateCoreData(UserId, QString key) {
 
136
  if(clientMode == LocalCore) return;
 
137
  QVariant data = Global::data(key);
 
138
  recvProxySignal(GS_UPDATE_GLOBAL_DATA, key, data, QVariant());
 
139
}
 
140
 
 
141
void Client::updateLocalData(QString key, QVariant data) {
 
142
  Global::updateData(key, data);
 
143
}
 
144
 
 
145
void Client::recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) {
 
146
  if(clientMode == LocalCore) return;
 
147
  QList<QVariant> sigdata;
 
148
  sigdata.append(sig); sigdata.append(arg1); sigdata.append(arg2); sigdata.append(arg3);
 
149
  //qDebug() << "Sending signal: " << sigdata;
 
150
  writeDataToDevice(&socket, QVariant(sigdata));
 
151
}
 
152
 
 
153
void Client::connectToCore(QString host, quint16 port) {
 
154
  // TODO implement SSL
 
155
  socket.connectToHost(host, port);
 
156
}
 
157
 
 
158
void Client::disconnectFromCore() {
 
159
  socket.close();
 
160
}
 
161
 
 
162
void Client::serverError(QAbstractSocket::SocketError) {
 
163
  emit coreConnectionError(socket.errorString());
 
164
}
 
165
 
 
166
void Client::serverHasData() {
 
167
  QVariant item;
 
168
  while(readDataFromDevice(&socket, blockSize, item)) {
 
169
    emit recvPartialItem(1,1);
 
170
    QList<QVariant> sigdata = item.toList();
 
171
    Q_ASSERT(sigdata.size() == 4);
 
172
    ClientProxy::instance()->recv((CoreSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]);
 
173
    blockSize = 0;
 
174
  }
 
175
  if(blockSize > 0) {
 
176
    emit recvPartialItem(socket.bytesAvailable(), blockSize);
 
177
  }
 
178
}
 
179
 
 
180
/*******************************************************************************************************************/
 
181
 
 
182
void Client::networkConnected(QString net) {
 
183
  connected[net] = true;
 
184
  BufferId id = statusBufferId(net);
 
185
  Buffer *b = buffer(id);
 
186
  b->setActive(true);
 
187
  //b->displayMsg(Message(id, Message::Server, tr("Connected.")));
 
188
  // TODO buffersUpdated();
 
189
}
 
190
 
 
191
void Client::networkDisconnected(QString net) {
 
192
  foreach(BufferId id, buffers.keys()) {
 
193
    if(id.network() != net) continue;
 
194
    Buffer *b = buffer(id);
 
195
    //b->displayMsg(Message(id, Message::Server, tr("Server disconnected."))); FIXME
 
196
    b->setActive(false);
 
197
  }
 
198
  connected[net] = false;
 
199
}
 
200
 
 
201
void Client::updateBufferId(BufferId id) {
 
202
  bufferIds[id.uid()] = id;  // make lookups by id faster
 
203
  buffer(id);
 
204
}
 
205
 
 
206
BufferId Client::bufferId(QString net, QString buf) {
 
207
  foreach(BufferId id, buffers.keys()) {
 
208
    if(id.network() == net && id.buffer() == buf) return id;
 
209
  }
 
210
  Q_ASSERT(false);  // should never happen!
 
211
  return BufferId();
 
212
}
 
213
 
 
214
BufferId Client::statusBufferId(QString net) {
 
215
  return bufferId(net, "");
 
216
}
 
217
 
 
218
 
 
219
Buffer * Client::buffer(BufferId id) {
 
220
  Client *client = Client::instance();
 
221
  if(!buffers.contains(id)) {
 
222
    Buffer *b = new Buffer(id);
 
223
    b->setOwnNick(ownNick[id.network()]);
 
224
    connect(b, SIGNAL(userInput(BufferId, QString)), client, SLOT(userInput(BufferId, QString)));
 
225
    connect(b, SIGNAL(bufferUpdated(Buffer *)), client, SIGNAL(bufferUpdated(Buffer *)));
 
226
    connect(b, SIGNAL(bufferDestroyed(Buffer *)), client, SIGNAL(bufferDestroyed(Buffer *)));
 
227
    buffers[id] = b;
 
228
    emit client->bufferUpdated(b);
 
229
  }
 
230
  return buffers[id];
 
231
}
 
232
 
 
233
void Client::recvNetworkState(QString net, QVariant state) {
 
234
  connected[net] = true;
 
235
  setOwnNick(net, state.toMap()["OwnNick"].toString());
 
236
  buffer(statusBufferId(net))->setActive(true);
 
237
  VarMap t = state.toMap()["Topics"].toMap();
 
238
  VarMap n = state.toMap()["Nicks"].toMap();
 
239
  foreach(QVariant v, t.keys()) {
 
240
    QString buf = v.toString();
 
241
    BufferId id = bufferId(net, buf);
 
242
    buffer(id)->setActive(true);
 
243
    setTopic(net, buf, t[buf].toString());
 
244
  }
 
245
  foreach(QString nick, n.keys()) {
 
246
    addNick(net, nick, n[nick].toMap());
 
247
  }
 
248
}
 
249
 
 
250
void Client::recvMessage(Message msg) {
 
251
  Buffer *b = buffer(msg.buffer);
 
252
 
 
253
  Buffer::ActivityLevel level = Buffer::OtherActivity;
 
254
  if(msg.type == Message::Plain || msg.type == Message::Notice){
 
255
    level |= Buffer::NewMessage;
 
256
  }
 
257
  if(msg.flags & Message::Highlight){
 
258
    level |= Buffer::Highlight;
 
259
  }
 
260
  emit bufferActivity(level, b);
 
261
 
 
262
  //b->displayMsg(msg);
 
263
  b->appendChatLine(new ChatLine(msg));
 
264
}
 
265
 
 
266
void Client::recvStatusMsg(QString net, QString msg) {
 
267
  //recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg)));
 
268
 
 
269
}
 
270
 
 
271
void Client::recvBacklogData(BufferId id, QList<QVariant> msgs, bool done) {
 
272
  foreach(QVariant v, msgs) {
 
273
    layoutQueue.append(v.value<Message>());
 
274
  }
 
275
  if(!layoutTimer->isActive()) layoutTimer->start();
 
276
}
 
277
 
 
278
 
 
279
void Client::layoutMsg() {
 
280
  if(layoutQueue.count()) {
 
281
    ChatLine *line = new ChatLine(layoutQueue.takeFirst());
 
282
    buffer(line->bufferId())->prependChatLine(line);
 
283
  }
 
284
  if(!layoutQueue.count()) layoutTimer->stop();
 
285
}
 
286
 
 
287
void Client::userInput(BufferId id, QString msg) {
 
288
  emit sendInput(id, msg);
 
289
}
 
290
 
 
291
void Client::setTopic(QString net, QString buf, QString topic) {
 
292
  BufferId id = bufferId(net, buf);
 
293
  if(!connected[id.network()]) return;
 
294
  Buffer *b = buffer(id);
 
295
  b->setTopic(topic);
 
296
  //if(!b->isActive()) {
 
297
  //  b->setActive(true);
 
298
  //  buffersUpdated();
 
299
  //}
 
300
}
 
301
 
 
302
void Client::addNick(QString net, QString nick, VarMap props) {
 
303
  if(!connected[net]) return;
 
304
  nicks[net][nick] = props;
 
305
  VarMap chans = props["Channels"].toMap();
 
306
  QStringList c = chans.keys();
 
307
  foreach(QString bufname, c) {
 
308
    buffer(bufferId(net, bufname))->addNick(nick, props);
 
309
  }
 
310
}
 
311
 
 
312
void Client::renameNick(QString net, QString oldnick, QString newnick) {
 
313
  if(!connected[net]) return;
 
314
  QStringList chans = nicks[net][oldnick]["Channels"].toMap().keys();
 
315
  foreach(QString c, chans) {
 
316
    buffer(bufferId(net, c))->renameNick(oldnick, newnick);
 
317
  }
 
318
  nicks[net][newnick] = nicks[net].take(oldnick);
 
319
}
 
320
 
 
321
void Client::updateNick(QString net, QString nick, VarMap props) {
 
322
  if(!connected[net]) return;
 
323
  QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys();
 
324
  QStringList newchans = props["Channels"].toMap().keys();
 
325
  foreach(QString c, newchans) {
 
326
    if(oldchans.contains(c)) buffer(bufferId(net, c))->updateNick(nick, props);
 
327
    else buffer(bufferId(net, c))->addNick(nick, props);
 
328
  }
 
329
  foreach(QString c, oldchans) {
 
330
    if(!newchans.contains(c)) buffer(bufferId(net, c))->removeNick(nick);
 
331
  }
 
332
  nicks[net][nick] = props;
 
333
}
 
334
 
 
335
void Client::removeNick(QString net, QString nick) {
 
336
  if(!connected[net]) return;
 
337
  VarMap chans = nicks[net][nick]["Channels"].toMap();
 
338
  foreach(QString bufname, chans.keys()) {
 
339
    buffer(bufferId(net, bufname))->removeNick(nick);
 
340
  }
 
341
  nicks[net].remove(nick);
 
342
}
 
343
 
 
344
void Client::setOwnNick(QString net, QString nick) {
 
345
  if(!connected[net]) return;
 
346
  ownNick[net] = nick;
 
347
  foreach(BufferId id, buffers.keys()) {
 
348
    if(id.network() == net) {
 
349
      buffers[id]->setOwnNick(nick);
 
350
    }
 
351
  }
 
352
}
 
353
 
 
354