-
-Client * Client::instanceptr = 0;
-
-bool Client::connectedToCore = false;
-Client::ClientMode Client::clientMode;
-QVariantMap Client::coreConnectionInfo;
-QHash<BufferId, Buffer *> Client::buffers;
-QHash<uint, BufferId> Client::bufferIds;
-QHash<QString, QHash<QString, QVariantMap> > Client::nicks;
-QHash<QString, bool> Client::netConnected;
-QStringList Client::netsAwaitingInit;
-QHash<QString, QString> Client::ownNick;
-
-Client *Client::instance() {
- if(instanceptr) return instanceptr;
- instanceptr = new Client();
- return instanceptr;
-}
-
-void Client::destroy() {
- delete instanceptr;
- instanceptr = 0;
-}
-
-Client::Client() {
- //clientProxy = ClientProxy::instance();
- _signalProxy = new SignalProxy(SignalProxy::Client, 0, this);
-
- // TODO: make this configurable (allow monolithic client to connect to remote cores)
- //if(Global::runMode == Global::Monolithic) clientMode = LocalCore;
- //else clientMode = RemoteCore;
- connectedToCore = false;
- socket = 0;
-}
-
-void Client::init(AbstractUi *ui) {
- instance()->mainUi = ui;
- instance()->init();
-}
-
-void Client::init() {
- blockSize = 0;
-
- _bufferModel = new BufferTreeModel(this);
-
- connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *)));
- connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *)));
- connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), _bufferModel, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *)));
-
- //connect(&socket, SIGNAL(readyRead()), this, SLOT(serverHasData()));
- //connect(&socket, SIGNAL(connected()), this, SLOT(coreSocketConnected()));
- //connect(&socket, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected()));
- //connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(serverError(QAbstractSocket::SocketError)));
-
- //connect(this, SIGNAL(sendSessionData(const QString &, const QVariant &)), clientProxy, SLOT(gsSessionDataChanged(const QString &, const QVariant &)));
- //connect(clientProxy, SIGNAL(csSessionDataChanged(const QString &, const QVariant &)), this, SLOT(recvSessionData(const QString &, const QVariant &)));
-
- //connect(clientProxy, SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant)));
- //connect(clientProxy, SIGNAL(csCoreState(QVariant)), this, SLOT(recvCoreState(const QVariant &)));
- //connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant)));
- //connect(clientProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString)));
- //connect(clientProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString)));
- //connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(const Message &)));
- //connect(clientProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString)));
- //connect(clientProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
- //connect(clientProxy, SIGNAL(csNickAdded(QString, QString, QVariantMap)), this, SLOT(addNick(QString, QString, QVariantMap)));
- //connect(clientProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString)));
- //connect(clientProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString)));
- //connect(clientProxy, SIGNAL(csNickUpdated(QString, QString, QVariantMap)), this, SLOT(updateNick(QString, QString, QVariantMap)));
- //connect(clientProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString)));
- //connect(clientProxy, SIGNAL(csBacklogData(BufferId, const QList<QVariant> &, bool)), this, SLOT(recvBacklogData(BufferId, QList<QVariant>, bool)));
- //connect(clientProxy, SIGNAL(csUpdateBufferId(BufferId)), this, SLOT(updateBufferId(BufferId)));
- //connect(this, SIGNAL(sendInput(BufferId, QString)), clientProxy, SLOT(gsUserInput(BufferId, QString)));
- //connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), clientProxy, SLOT(gsRequestBacklog(BufferId, QVariant, QVariant)));
- //connect(this, SIGNAL(requestNetworkStates()), clientProxy, SLOT(gsRequestNetworkStates()));
-
- SignalProxy *p = signalProxy();
- p->attachSignal(this, SIGNAL(sendSessionData(const QString &, const QVariant &)), SIGNAL(clientSessionDataChanged(const QString &, const QVariant &)));
- p->attachSlot(SIGNAL(coreSessionDataChanged(const QString &, const QVariant &)), this, SLOT(recvSessionData(const QString &, const QVariant &)));
- p->attachSlot(SIGNAL(coreState(const QVariant &)), this, SLOT(recvCoreState(const QVariant &)));
- p->attachSlot(SIGNAL(networkState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant)));
- p->attachSlot(SIGNAL(networkConnected(QString)), this, SLOT(networkConnected(QString)));
- p->attachSlot(SIGNAL(networkDisconnected(QString)), this, SLOT(networkDisconnected(QString)));
- 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(topicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
- p->attachSlot(SIGNAL(nickAdded(QString, QString, QVariantMap)), this, SLOT(addNick(QString, QString, QVariantMap)));
- p->attachSlot(SIGNAL(nickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString)));
- p->attachSlot(SIGNAL(nickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString)));
- p->attachSlot(SIGNAL(nickUpdated(QString, QString, QVariantMap)), this, SLOT(updateNick(QString, QString, QVariantMap)));
- p->attachSlot(SIGNAL(ownNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString)));
- p->attachSlot(SIGNAL(backlogData(BufferId, const QVariantList &, bool)), this, SLOT(recvBacklogData(BufferId, const QVariantList &, bool)));
- p->attachSlot(SIGNAL(bufferIdUpdated(BufferId)), this, SLOT(updateBufferId(BufferId)));
- p->attachSignal(this, SIGNAL(sendInput(BufferId, QString)));
- //p->attachSignal(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), "requestBacklog");
- p->attachSignal(this, SIGNAL(requestNetworkStates()));
-
- 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()));
-
- layoutTimer = new QTimer(this);
- layoutTimer->setInterval(0);
- layoutTimer->setSingleShot(false);
- connect(layoutTimer, SIGNAL(timeout()), this, SLOT(layoutMsg()));
-
-}
-
-Client::~Client() {
- //delete mainUi;
- //delete _bufferModel;
- foreach(Buffer *buf, buffers.values()) delete buf; // this is done by disconnectFromCore()! FIXME?
- //ClientProxy::destroy();
- Q_ASSERT(!buffers.count());
-}
-
-BufferTreeModel *Client::bufferModel() {
- return instance()->_bufferModel;
-}
-
-SignalProxy *Client::signalProxy() {
- return instance()->_signalProxy;
-}
-
-bool Client::isConnected() {
- return connectedToCore;
-}
-
-void Client::connectToCore(const QVariantMap &conn) {
- // TODO implement SSL
- coreConnectionInfo = conn;
- if(isConnected() || socket != 0) {
- emit coreConnectionError(tr("Already connected to Core!"));
- return;
- }
- if(conn["Host"].toString().isEmpty()) {
- clientMode = LocalCore;
- socket = new QBuffer(this);
- connect(socket, SIGNAL(readyRead()), this, SLOT(coreHasData()));
- socket->open(QIODevice::ReadWrite);
- //QVariant state = connectToLocalCore(coreConnectionInfo["User"].toString(), coreConnectionInfo["Password"].toString());
- //syncToCore(state);
- coreSocketConnected();
- } else {
- clientMode = RemoteCore;
- emit coreConnectionMsg(tr("Connecting..."));
- Q_ASSERT(!socket);
- QTcpSocket *sock = new QTcpSocket(this);
- socket = sock;
- connect(sock, SIGNAL(readyRead()), this, SLOT(coreHasData()));
- connect(sock, SIGNAL(connected()), this, SLOT(coreSocketConnected()));
- connect(sock, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected()));
- connect(signalProxy(), SIGNAL(peerDisconnected()), this, SLOT(coreSocketDisconnected()));
- //connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(coreSocketStateChanged(QAbstractSocket::SocketState)));
- connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(coreSocketError(QAbstractSocket::SocketError)));
- sock->connectToHost(conn["Host"].toString(), conn["Port"].toUInt());
- }
-}
-
-void Client::disconnectFromCore() {
- if(clientMode == RemoteCore) {
- socket->close();
- //QAbstractSocket *sock = qobject_cast<QAbstractSocket*>(socket);
- //Q_ASSERT(sock);
- //sock->disconnectFromHost();
- } else {
- socket->close();
- //disconnectFromLocalCore();
- coreSocketDisconnected();
- }
-}
-
-void Client::coreSocketConnected() {
- connect(this, SIGNAL(recvPartialItem(uint, uint)), this, SIGNAL(coreConnectionProgress(uint, uint)));
- emit coreConnectionMsg(tr("Synchronizing to core..."));
- QVariantMap clientInit;
- clientInit["GuiProtocol"] = GUI_PROTOCOL;
- clientInit["User"] = coreConnectionInfo["User"].toString();
- clientInit["Password"] = coreConnectionInfo["Password"].toString();
- writeDataToDevice(socket, clientInit);
-}
-
-void Client::coreSocketDisconnected() {
- connectedToCore = false;
- emit disconnected();
- socket->deleteLater();
-
- /* Clear internal data. Hopefully nothing relies on it at this point. */
- _bufferModel->clear();
- // Buffers, if deleted, send a signal that causes their removal from buffers and bufferIds.
- // So we cannot simply go through the array in a loop (or use qDeleteAll) for deletion...
- while(buffers.count()) { delete buffers.take(buffers.keys()[0]); }
- Q_ASSERT(!buffers.count()); // should be empty now!
- Q_ASSERT(!bufferIds.count());
- coreConnectionInfo.clear();
- sessionData.clear();
- nicks.clear();
- netConnected.clear();
- netsAwaitingInit.clear();
- ownNick.clear();
- layoutQueue.clear();
- layoutTimer->stop();
-}
-
-void Client::coreSocketStateChanged(QAbstractSocket::SocketState state) { qDebug() << state;
- if(state == QAbstractSocket::UnconnectedState) coreSocketDisconnected();
-}
-
-void Client::recvCoreState(const QVariant &state) {
- disconnect(this, SIGNAL(recvPartialItem(uint, uint)), this, SIGNAL(coreConnectionProgress(uint, uint)));
- disconnect(socket, 0, this, 0); // rest of communication happens through SignalProxy
- signalProxy()->addPeer(socket);
- syncToCore(state);
-}
-
-void Client::syncToCore(const QVariant &coreState) {
- if(!coreState.toMap().contains("SessionState")) {
- emit coreConnectionError(tr("Invalid data received from core!"));
+#include "clientauthhandler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+Client::Client(std::unique_ptr<AbstractUi> ui, QObject *parent)
+ : QObject(parent), Singleton<Client>(this),
+ _signalProxy(new SignalProxy(SignalProxy::Client, this)),
+ _mainUi(std::move(ui)),
+ _networkModel(new NetworkModel(this)),
+ _bufferModel(new BufferModel(_networkModel)),
+ _bufferSyncer(0),
+ _aliasManager(0),
+ _backlogManager(new ClientBacklogManager(this)),
+ _bufferViewManager(0),
+ _bufferViewOverlay(new BufferViewOverlay(this)),
+ _coreInfo(new CoreInfo(this)),
+ _dccConfig(0),
+ _ircListHelper(new ClientIrcListHelper(this)),
+ _inputHandler(new ClientUserInputHandler(this)),
+ _networkConfig(0),
+ _ignoreListManager(0),
+ _highlightRuleManager(0),
+ _transferManager(0),
+ _transferModel(new TransferModel(this)),
+ _messageModel(_mainUi->createMessageModel(this)),
+ _messageProcessor(_mainUi->createMessageProcessor(this)),
+ _coreAccountModel(new CoreAccountModel(this)),
+ _coreConnection(new CoreConnection(this)),
+ _connected(false)
+{
+ //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(this, SIGNAL(networkRemoved(NetworkId)), _networkModel, SLOT(networkRemoved(NetworkId)));
+ connect(this, SIGNAL(networkRemoved(NetworkId)), _messageProcessor, SLOT(networkRemoved(NetworkId)));
+
+ connect(backlogManager(), SIGNAL(messagesReceived(BufferId, int)), _messageModel, SLOT(messagesReceived(BufferId, int)));
+ connect(coreConnection(), SIGNAL(stateChanged(CoreConnection::ConnectionState)), SLOT(connectionStateChanged(CoreConnection::ConnectionState)));
+
+ 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)), _networkModel, SLOT(bufferUpdated(BufferInfo)));
+ p->attachSignal(inputHandler(), SIGNAL(sendInput(BufferInfo, QString)));
+ p->attachSignal(this, SIGNAL(requestNetworkStates()));
+
+ 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 &, 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)));
+
+ p->attachSignal(this, SIGNAL(requestPasswordChange(PeerPtr,QString,QString,QString)), SIGNAL(changePassword(PeerPtr,QString,QString,QString)));
+ p->attachSlot(SIGNAL(passwordChanged(PeerPtr,bool)), this, SLOT(corePasswordChanged(PeerPtr,bool)));
+
+ p->attachSignal(this, SIGNAL(requestKickClient(int)), SIGNAL(kickClient(int)));
+ p->attachSlot(SIGNAL(disconnectFromCore()), this, SLOT(disconnectFromCore()));
+
+ p->synchronize(backlogManager());
+ p->synchronize(coreInfo());
+ p->synchronize(_ircListHelper);
+
+ coreAccountModel()->load();
+ coreConnection()->init();
+}
+
+
+Client::~Client()
+{