X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fclient.cpp;h=759afcf96ec3dc851587c837cc579d4a2803875f;hp=faddce720462262c9400c12be9ca6a66bf9a942f;hb=aadd816dbcae859ce9ac5b44d609bd3094b3d6fc;hpb=b9a73f8181f4cee4b5b226b4a641796f04e85179 diff --git a/src/client/client.cpp b/src/client/client.cpp index faddce72..759afcf9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-08 by the Quassel Project * + * Copyright (C) 2005-09 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -21,25 +21,29 @@ #include "client.h" #include "abstractmessageprocessor.h" +#include "abstractui.h" #include "bufferinfo.h" #include "buffermodel.h" #include "buffersettings.h" #include "buffersyncer.h" -#include "bufferviewmanager.h" +#include "bufferviewconfig.h" #include "clientbacklogmanager.h" +#include "clientbufferviewmanager.h" #include "clientirclisthelper.h" -#include "global.h" -#include "identity.h" +#include "clientidentity.h" #include "ircchannel.h" #include "ircuser.h" #include "message.h" #include "messagemodel.h" #include "network.h" #include "networkmodel.h" -#include "quasselui.h" +#include "quassel.h" #include "signalproxy.h" #include "util.h" +#include +#include + QPointer Client::instanceptr = 0; AccountId Client::_currentCoreAccount = 0; @@ -52,20 +56,22 @@ Client *Client::instance() { } void Client::destroy() { - //delete instanceptr; - instanceptr->deleteLater(); + if(instanceptr) { + delete instanceptr->mainUi(); + instanceptr->deleteLater(); + instanceptr = 0; + } } void Client::init(AbstractUi *ui) { - instance()->mainUi = ui; + instance()->_mainUi = ui; instance()->init(); } Client::Client(QObject *parent) : QObject(parent), - socket(0), _signalProxy(new SignalProxy(SignalProxy::Client, this)), - mainUi(0), + _mainUi(0), _networkModel(0), _bufferModel(0), _bufferSyncer(0), @@ -75,13 +81,11 @@ Client::Client(QObject *parent) _messageModel(0), _messageProcessor(0), _connectedToCore(false), - _syncedToCore(false) + _syncedToCore(false), + _internalCore(false), + _debugLog(&_debugLogBuffer) { - _monitorBuffer = new Buffer(BufferInfo(), this); _signalProxy->synchronize(_ircListHelper); - - connect(_backlogManager, SIGNAL(backlog(BufferId, const QVariantList &)), - this, SLOT(receiveBacklog(BufferId, const QVariantList &))); } Client::~Client() { @@ -92,47 +96,50 @@ void Client::init() { _currentCoreAccount = 0; _networkModel = new NetworkModel(this); - connect(this, SIGNAL(bufferUpdated(BufferInfo)), - _networkModel, SLOT(bufferUpdated(BufferInfo))); connect(this, SIGNAL(networkRemoved(NetworkId)), _networkModel, SLOT(networkRemoved(NetworkId))); _bufferModel = new BufferModel(_networkModel); - _messageModel = mainUi->createMessageModel(this); - _messageProcessor = mainUi->createMessageProcessor(this); + _messageModel = mainUi()->createMessageModel(this); + _messageProcessor = mainUi()->createMessageProcessor(this); SignalProxy *p = signalProxy(); p->attachSlot(SIGNAL(displayMsg(const Message &)), this, SLOT(recvMessage(const Message &))); p->attachSlot(SIGNAL(displayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); - p->attachSlot(SIGNAL(bufferInfoUpdated(BufferInfo)), this, SLOT(updateBufferInfo(BufferInfo))); + p->attachSlot(SIGNAL(bufferInfoUpdated(BufferInfo)), _networkModel, SLOT(bufferUpdated(BufferInfo))); p->attachSignal(this, SIGNAL(sendInput(BufferInfo, QString))); p->attachSignal(this, SIGNAL(requestNetworkStates())); - p->attachSignal(this, SIGNAL(requestCreateIdentity(const Identity &)), SIGNAL(createIdentity(const Identity &))); - p->attachSignal(this, SIGNAL(requestUpdateIdentity(const Identity &)), SIGNAL(updateIdentity(const Identity &))); + p->attachSignal(this, SIGNAL(requestCreateIdentity(const Identity &, const QVariantMap &)), SIGNAL(createIdentity(const Identity &, const QVariantMap &))); p->attachSignal(this, SIGNAL(requestRemoveIdentity(IdentityId)), SIGNAL(removeIdentity(IdentityId))); p->attachSlot(SIGNAL(identityCreated(const Identity &)), this, SLOT(coreIdentityCreated(const Identity &))); p->attachSlot(SIGNAL(identityRemoved(IdentityId)), this, SLOT(coreIdentityRemoved(IdentityId))); - p->attachSignal(this, SIGNAL(requestCreateNetwork(const NetworkInfo &)), SIGNAL(createNetwork(const NetworkInfo &))); - p->attachSignal(this, SIGNAL(requestUpdateNetwork(const NetworkInfo &)), SIGNAL(updateNetwork(const NetworkInfo &))); + p->attachSignal(this, SIGNAL(requestCreateNetwork(const NetworkInfo &, const QStringList &)), SIGNAL(createNetwork(const NetworkInfo &, const QStringList &))); p->attachSignal(this, SIGNAL(requestRemoveNetwork(NetworkId)), SIGNAL(removeNetwork(NetworkId))); p->attachSlot(SIGNAL(networkCreated(NetworkId)), this, SLOT(coreNetworkCreated(NetworkId))); p->attachSlot(SIGNAL(networkRemoved(NetworkId)), this, SLOT(coreNetworkRemoved(NetworkId))); - connect(p, SIGNAL(disconnected()), this, SLOT(disconnectFromCore())); + connect(p, SIGNAL(disconnected()), this, SLOT(disconnectedFromCore())); - //connect(mainUi, SIGNAL(connectToCore(const QVariantMap &)), this, SLOT(connectToCore(const QVariantMap &))); - connect(mainUi, SIGNAL(disconnectFromCore()), this, SLOT(disconnectFromCore())); - connect(this, SIGNAL(connected()), mainUi, SLOT(connectedToCore())); - connect(this, SIGNAL(disconnected()), mainUi, SLOT(disconnectedFromCore())); + //connect(mainUi(), SIGNAL(connectToCore(const QVariantMap &)), this, SLOT(connectToCore(const QVariantMap &))); + connect(mainUi(), SIGNAL(disconnectFromCore()), this, SLOT(disconnectFromCore())); + connect(this, SIGNAL(connected()), mainUi(), SLOT(connectedToCore())); + connect(this, SIGNAL(disconnected()), mainUi(), SLOT(disconnectedFromCore())); + // attach backlog manager + p->synchronize(backlogManager()); + connect(backlogManager(), SIGNAL(messagesReceived(BufferId, int)), _messageModel, SLOT(messagesReceived(BufferId, int))); } /*** public static methods ***/ +AbstractUi *Client::mainUi() { + return instance()->_mainUi; +} + AccountId Client::currentCoreAccount() { return _currentCoreAccount; } @@ -141,56 +148,6 @@ void Client::setCurrentCoreAccount(AccountId id) { _currentCoreAccount = id; } -QList Client::allBufferInfos() { - QList bufferids; - foreach(Buffer *buffer, buffers()) { - bufferids << buffer->bufferInfo(); - } - return bufferids; -} - -QList Client::buffers() { - return instance()->_buffers.values(); -} - - -Buffer *Client::statusBuffer(const NetworkId &networkId) const { - if(_statusBuffers.contains(networkId)) - return _statusBuffers[networkId]; - else - return 0; -} - -Buffer *Client::buffer(BufferId bufferId) { - if(instance()->_buffers.contains(bufferId)) - return instance()->_buffers[bufferId]; - else - return 0; -} - -Buffer *Client::buffer(BufferInfo bufferInfo) { - Buffer *buff = buffer(bufferInfo.bufferId()); - - if(!buff) { - Client *client = Client::instance(); - buff = new Buffer(bufferInfo, client); - connect(buff, SIGNAL(destroyed()), client, SLOT(bufferDestroyed())); - client->_buffers[bufferInfo.bufferId()] = buff; - if(bufferInfo.type() == BufferInfo::StatusBuffer) - client->_statusBuffers[bufferInfo.networkId()] = buff; - - emit client->bufferUpdated(bufferInfo); - - // I don't like this: but currently there isn't really a prettier way: - if(isSynced()) { // this slows down syncing a lot, so disable it during sync - QModelIndex bufferIdx = networkModel()->bufferIndex(bufferInfo.bufferId()); - bufferModel()->setCurrentIndex(bufferModel()->mapFromSource(bufferIdx)); - } - } - Q_ASSERT(buff); - return buff; -} - bool Client::isConnected() { return instance()->_connectedToCore; } @@ -210,18 +167,23 @@ const Network * Client::network(NetworkId networkid) { else return 0; } -void Client::createNetwork(const NetworkInfo &info) { - emit instance()->requestCreateNetwork(info); -} - -void Client::updateNetwork(const NetworkInfo &info) { - emit instance()->requestUpdateNetwork(info); +void Client::createNetwork(const NetworkInfo &info, const QStringList &persistentChannels) { + emit instance()->requestCreateNetwork(info, persistentChannels); } void Client::removeNetwork(NetworkId id) { emit instance()->requestRemoveNetwork(id); } +void Client::updateNetwork(const NetworkInfo &info) { + Network *netptr = instance()->_networks.value(info.networkId, 0); + if(!netptr) { + qWarning() << "Update for unknown network requested:" << info; + return; + } + netptr->requestSetNetworkInfo(info); +} + void Client::addNetwork(Network *net) { net->setProxy(signalProxy()); signalProxy()->synchronize(net); @@ -254,17 +216,27 @@ QList Client::identityIds() { return instance()->_identities.keys(); } -const Identity * Client::identity(IdentityId id) { +const Identity *Client::identity(IdentityId id) { if(instance()->_identities.contains(id)) return instance()->_identities[id]; else return 0; } -void Client::createIdentity(const Identity &id) { - emit instance()->requestCreateIdentity(id); +void Client::createIdentity(const CertIdentity &id) { + QVariantMap additional; +#ifdef HAVE_SSL + additional["KeyPem"] = id.sslKey().toPem(); + additional["CertPem"] = id.sslCert().toPem(); +#endif + emit instance()->requestCreateIdentity(id, additional); } -void Client::updateIdentity(const Identity &id) { - emit instance()->requestUpdateIdentity(id); +void Client::updateIdentity(IdentityId id, const QVariantMap &ser) { + Identity *idptr = instance()->_identities.value(id, 0); + if(!idptr) { + qWarning() << "Update for unknown identity requested:" << id; + return; + } + idptr->requestUpdate(ser); } void Client::removeIdentity(IdentityId id) { @@ -298,9 +270,14 @@ void Client::userInput(BufferInfo bufferInfo, QString message) { /*** core connection stuff ***/ -void Client::setConnectedToCore(QIODevice *sock, AccountId id) { - socket = sock; - signalProxy()->addPeer(socket); +void Client::setConnectedToCore(AccountId id, QIODevice *socket) { + if(socket) { // external core + // if the socket is an orphan, the signalProxy adopts it. + // -> we don't need to care about it anymore + socket->setParent(0); + signalProxy()->addPeer(socket); + } + _internalCore = !socket; _connectedToCore = true; setCurrentCoreAccount(id); } @@ -309,39 +286,54 @@ void Client::setSyncedToCore() { // create buffersyncer Q_ASSERT(!_bufferSyncer); _bufferSyncer = new BufferSyncer(this); - connect(bufferSyncer(), SIGNAL(lastSeenMsgSet(BufferId, MsgId)), this, SLOT(updateLastSeenMsg(BufferId, MsgId))); + connect(bufferSyncer(), SIGNAL(lastSeenMsgSet(BufferId, MsgId)), _networkModel, SLOT(setLastSeenMsgId(BufferId, MsgId))); connect(bufferSyncer(), SIGNAL(bufferRemoved(BufferId)), this, SLOT(bufferRemoved(BufferId))); connect(bufferSyncer(), SIGNAL(bufferRenamed(BufferId, QString)), this, SLOT(bufferRenamed(BufferId, QString))); + connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), this, SLOT(buffersPermanentlyMerged(BufferId, BufferId))); + connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), _messageModel, SLOT(buffersPermanentlyMerged(BufferId, BufferId))); + connect(bufferSyncer(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog())); + connect(networkModel(), SIGNAL(setLastSeenMsg(BufferId, MsgId)), bufferSyncer(), SLOT(requestSetLastSeenMsg(BufferId, const MsgId &))); signalProxy()->synchronize(bufferSyncer()); - // attach backlog manager - signalProxy()->synchronize(backlogManager()); - // create a new BufferViewManager - _bufferViewManager = new BufferViewManager(signalProxy(), this); + Q_ASSERT(!_bufferViewManager); + _bufferViewManager = new ClientBufferViewManager(signalProxy(), this); + connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog())); + connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(createDefaultBufferView())); _syncedToCore = true; emit connected(); emit coreConnectionStateChanged(true); } -void Client::setSecuredConnection() { - emit securedConnection(); +void Client::requestInitialBacklog() { + if(bufferViewManager()->isInitialized() && bufferSyncer()->isInitialized()) + Client::backlogManager()->requestInitialBacklog(); +} + +void Client::createDefaultBufferView() { + if(bufferViewManager()->bufferViewConfigs().isEmpty()) { + BufferViewConfig config(-1); + config.setBufferViewName(tr("All Buffers")); + config.initSetBufferList(networkModel()->allBufferIdsSorted()); + bufferViewManager()->requestCreateBufferView(config.toVariantMap()); + } } void Client::disconnectFromCore() { if(!isConnected()) return; - _connectedToCore = false; - if(socket) { - socket->close(); - socket->deleteLater(); - } + signalProxy()->removeAllPeers(); +} + +void Client::disconnectedFromCore() { + _connectedToCore = false; _syncedToCore = false; emit disconnected(); emit coreConnectionStateChanged(false); + backlogManager()->reset(); messageProcessor()->reset(); // Clear internal data. Hopefully nothing relies on it at this point. @@ -360,17 +352,6 @@ void Client::disconnectFromCore() { _messageModel->clear(); _networkModel->clear(); - QHash::iterator bufferIter = _buffers.begin(); - while(bufferIter != _buffers.end()) { - Buffer *buffer = bufferIter.value(); - disconnect(buffer, SIGNAL(destroyed()), this, 0); - bufferIter = _buffers.erase(bufferIter); - buffer->deleteLater(); - } - Q_ASSERT(_buffers.isEmpty()); - - _statusBuffers.clear(); - QHash::iterator netIter = _networks.begin(); while(netIter != _networks.end()) { Network *net = netIter.value(); @@ -381,10 +362,10 @@ void Client::disconnectFromCore() { } Q_ASSERT(_networks.isEmpty()); - QHash::iterator idIter = _identities.begin(); + QHash::iterator idIter = _identities.begin(); while(idIter != _identities.end()) { + emit identityRemoved(idIter.key()); Identity *id = idIter.value(); - emit identityRemoved(id->id()); idIter = _identities.erase(idIter); id->deleteLater(); } @@ -392,37 +373,8 @@ void Client::disconnectFromCore() { } -void Client::setCoreConfiguration(const QVariantMap &settings) { - SignalProxy::writeDataToDevice(socket, settings); -} - /*** ***/ -void Client::updateBufferInfo(BufferInfo id) { - emit bufferUpdated(id); -} - -void Client::bufferDestroyed() { - Buffer *buffer = static_cast(sender()); - QHash::iterator iter = _buffers.begin(); - while(iter != _buffers.end()) { - if(iter.value() == buffer) { - iter = _buffers.erase(iter); - break; - } - iter++; - } - - QHash::iterator statusIter = _statusBuffers.begin(); - while(statusIter != _statusBuffers.end()) { - if(statusIter.value() == buffer) { - statusIter = _statusBuffers.erase(statusIter); - break; - } - statusIter++; - } -} - void Client::networkDestroyed() { Network *net = static_cast(sender()); QHash::iterator netIter = _networks.begin(); @@ -441,30 +393,9 @@ void Client::recvStatusMsg(QString /*net*/, QString /*msg*/) { //recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg))); } -void Client::recvMessage(const Message &msg_) { - Message msg = msg_; - messageProcessor()->process(msg); -} - -void Client::receiveBacklog(BufferId bufferId, const QVariantList &msgs) { - //QTime start = QTime::currentTime(); - QList msglist; - foreach(QVariant v, msgs) { - Message msg = v.value(); - msg.setFlags(msg.flags() | Message::Backlog); - msglist << msg; - } - messageProcessor()->process(msglist); - //qDebug() << "processed" << msgs.count() << "backlog lines in" << start.msecsTo(QTime::currentTime()); -} - -void Client::updateLastSeenMsg(BufferId id, const MsgId &msgId) { - Buffer *b = buffer(id); - if(!b) { - qWarning() << "Client::updateLastSeen(): Unknown buffer" << id; - return; - } - b->setLastSeenMsg(msgId); +void Client::recvMessage(const Message &msg) { + Message msg_ = msg; + messageProcessor()->process(msg_); } void Client::setBufferLastSeenMsg(BufferId id, const MsgId &msgId) { @@ -478,15 +409,26 @@ void Client::removeBuffer(BufferId id) { bufferSyncer()->requestRemoveBuffer(id); } -void Client::bufferRemoved(BufferId bufferId) { - // first remove the buffer from hash. this prohibits further lastSeenUpdates - Buffer *buff = 0; - if(_buffers.contains(bufferId)) { - buff = _buffers.take(bufferId); - disconnect(buff, 0, this, 0); - } +void Client::renameBuffer(BufferId bufferId, const QString &newName) { + if(!bufferSyncer()) + return; + bufferSyncer()->requestRenameBuffer(bufferId, newName); +} + +void Client::mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2) { + if(!bufferSyncer()) + return; + bufferSyncer()->requestMergeBuffersPermanently(bufferId1, bufferId2); +} + +void Client::purgeKnownBufferIds() { + if(!bufferSyncer()) + return; + bufferSyncer()->requestPurgeBufferIds(); +} - // then we select a sane buffer (status buffer) +void Client::bufferRemoved(BufferId bufferId) { + // select a sane buffer (status buffer) /* we have to manually select a buffer because otherwise inconsitent changes * to the model might occur: * the result of a buffer removal triggers a change in the selection model. @@ -501,9 +443,6 @@ void Client::bufferRemoved(BufferId bufferId) { // and remove it from the model networkModel()->removeBuffer(bufferId); - - if(buff) - buff->deleteLater(); } void Client::bufferRenamed(BufferId bufferId, const QString &newName) { @@ -512,3 +451,22 @@ void Client::bufferRenamed(BufferId bufferId, const QString &newName) { networkModel()->setData(bufferIndex, newName, Qt::DisplayRole); } } + +void Client::buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferId2) { + QModelIndex idx = networkModel()->bufferIndex(bufferId1); + bufferModel()->setCurrentIndex(bufferModel()->mapFromSource(idx)); + networkModel()->removeBuffer(bufferId2); +} + +void Client::logMessage(QtMsgType type, const char *msg) { + fprintf(stderr, "%s\n", msg); + fflush(stderr); + if(type == QtFatalMsg) { + Quassel::logFatalMessage(msg); + } else { + QString msgString = QString("%1\n").arg(msg); + instance()->_debugLog << msgString; + emit instance()->logUpdated(msgString); + } +} +