+
+ _authHandler = new ClientAuthHandler(currentAccount(), this);
+
+ connect(_authHandler, &ClientAuthHandler::disconnected, this, &CoreConnection::coreSocketDisconnected);
+ connect(_authHandler, &ClientAuthHandler::connectionReady, this, &CoreConnection::onConnectionReady);
+ connect(_authHandler, &ClientAuthHandler::socketError, this, &CoreConnection::coreSocketError);
+ connect(_authHandler, &ClientAuthHandler::transferProgress, this, &CoreConnection::updateProgress);
+ connect(_authHandler,
+ &ClientAuthHandler::requestDisconnect,
+ this,
+ selectOverload<const QString&, bool>(&CoreConnection::disconnectFromCore));
+
+ connect(_authHandler, &ClientAuthHandler::errorMessage, this, &CoreConnection::connectionError);
+ connect(_authHandler, &ClientAuthHandler::errorPopup, this, &CoreConnection::connectionErrorPopup, Qt::QueuedConnection);
+ connect(_authHandler, &ClientAuthHandler::statusMessage, this, &CoreConnection::connectionMsg);
+ connect(_authHandler, &ClientAuthHandler::encrypted, this, &CoreConnection::encrypted);
+ connect(_authHandler, &ClientAuthHandler::startCoreSetup, this, &CoreConnection::startCoreSetup);
+ connect(_authHandler, &ClientAuthHandler::coreSetupFailed, this, &CoreConnection::coreSetupFailed);
+ connect(_authHandler, &ClientAuthHandler::coreSetupSuccessful, this, &CoreConnection::coreSetupSuccess);
+ connect(_authHandler, &ClientAuthHandler::userAuthenticationRequired, this, &CoreConnection::userAuthenticationRequired);
+ connect(_authHandler, &ClientAuthHandler::handleNoSslInClient, this, &CoreConnection::handleNoSslInClient);
+ connect(_authHandler, &ClientAuthHandler::handleNoSslInCore, this, &CoreConnection::handleNoSslInCore);
+ connect(_authHandler, &ClientAuthHandler::handleSslErrors, this, &CoreConnection::handleSslErrors);
+ connect(_authHandler, &ClientAuthHandler::loginSuccessful, this, &CoreConnection::onLoginSuccessful);
+ connect(_authHandler, &ClientAuthHandler::handshakeComplete, this, &CoreConnection::onHandshakeComplete);
+
+ setState(Connecting);
+ _authHandler->connectToCore();
+}
+
+void CoreConnection::setupCore(const Protocol::SetupData& setupData)
+{
+ _authHandler->setupCore(setupData);
+}
+
+void CoreConnection::loginToCore(const QString& user, const QString& password, bool remember)
+{
+ _authHandler->login(user, password, remember);
+}
+
+void CoreConnection::onLoginSuccessful(const CoreAccount& account)
+{
+ updateProgress(0, 0);
+
+ // save current account data
+ accountModel()->createOrUpdateAccount(account);
+ accountModel()->save();
+
+ _reconnectTimer.stop();
+
+ setProgressText(tr("Receiving session state"));
+ setState(Synchronizing);
+ emit connectionMsg(tr("Synchronizing to %1...").arg(account.accountName()));
+}
+
+void CoreConnection::onHandshakeComplete(RemotePeer* peer, const Protocol::SessionState& sessionState)
+{
+ updateProgress(100, 100);
+
+ disconnect(_authHandler, nullptr, this, nullptr);
+ _authHandler->deleteLater();
+ _authHandler = nullptr;
+
+ _peer = peer;
+ connect(peer, &Peer::disconnected, this, &CoreConnection::coreSocketDisconnected);
+ connect(peer, &RemotePeer::statusMessage, this, &CoreConnection::connectionMsg);
+ connect(peer, &RemotePeer::socketError, this, &CoreConnection::coreSocketError);
+
+ Client::signalProxy()->addPeer(_peer); // sigproxy takes ownership of the peer!
+
+ syncToCore(sessionState);
+}
+
+void CoreConnection::internalSessionStateReceived(const Protocol::SessionState& sessionState)
+{
+ updateProgress(100, 100);
+ setState(Synchronizing);
+ syncToCore(sessionState);
+}
+
+void CoreConnection::syncToCore(const Protocol::SessionState& sessionState)
+{
+ setProgressText(tr("Receiving network states"));
+ updateProgress(0, 100);
+
+ // create identities
+ foreach (const QVariant& vid, sessionState.identities) {
+ Client::instance()->coreIdentityCreated(vid.value<Identity>());
+ }
+
+ // create buffers
+ // FIXME: get rid of this crap -- why?
+ NetworkModel* networkModel = Client::networkModel();
+ Q_ASSERT(networkModel);
+ foreach (const QVariant& vinfo, sessionState.bufferInfos)
+ networkModel->bufferUpdated(vinfo.value<BufferInfo>()); // create BufferItems
+
+ // prepare sync progress thingys...
+ // FIXME: Care about removal of networks
+ _numNetsToSync = sessionState.networkIds.count();
+ updateProgress(0, _numNetsToSync);
+
+ // create network objects
+ foreach (const QVariant& networkid, sessionState.networkIds) {
+ NetworkId netid = networkid.value<NetworkId>();
+ if (Client::network(netid))
+ continue;
+ auto* net = new Network(netid, Client::instance());
+ _netsToSync.insert(net);
+ connect(net, &SyncableObject::initDone, this, &CoreConnection::networkInitDone);
+ connect(net, &QObject::destroyed, this, &CoreConnection::networkInitDone);
+ Client::addNetwork(net);
+ }
+ checkSyncState();
+}
+
+// this is also called for destroyed networks!
+void CoreConnection::networkInitDone()
+{
+ QObject* net = sender();
+ Q_ASSERT(net);
+ disconnect(net, nullptr, this, nullptr);
+ _netsToSync.remove(net);
+ updateProgress(_numNetsToSync - _netsToSync.count(), _numNetsToSync);
+ checkSyncState();
+}
+
+void CoreConnection::checkSyncState()
+{
+ if (_netsToSync.isEmpty() && state() >= Synchronizing) {
+ setState(Synchronized);
+ setProgressText(tr("Synchronized to %1").arg(currentAccount().accountName()));
+ setProgressMaximum(-1);
+ emit synchronized();