diff --git a/src/Kaidan.cpp b/src/Kaidan.cpp index 2068c8e..5849119 100644 --- a/src/Kaidan.cpp +++ b/src/Kaidan.cpp @@ -1,294 +1,294 @@ /* * Kaidan - A user-friendly XMPP client for every device! * * Copyright (C) 2016-2020 Kaidan developers and contributors * (see the LICENSE file for a full list of copyright authors) * * Kaidan is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * In addition, as a special exception, the author of Kaidan gives * permission to link the code of its release with the OpenSSL * project's "OpenSSL" library (or with modified versions of it that * use the same license as the "OpenSSL" library), and distribute the * linked executables. You must obey the GNU General Public License in * all respects for all of the code used other than "OpenSSL". If you * modify this file, you may extend this exception to your version of * the file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Kaidan is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaidan. If not, see . */ #include "Kaidan.h" // Qt #include #include #include #include // QXmpp #include #include "qxmpp-exts/QXmppColorGenerator.h" #include "qxmpp-exts/QXmppUri.h" // Kaidan #include "AvatarFileStorage.h" #include "Database.h" #include "MessageDb.h" #include "MessageModel.h" #include "PresenceCache.h" #include "QmlUtils.h" #include "RosterDb.h" #include "RosterModel.h" Kaidan *Kaidan::s_instance = nullptr; Kaidan::Kaidan(QGuiApplication *app, bool enableLogging, QObject *parent) : QObject(parent), m_database(new Database()), m_dbThrd(new QThread()), m_msgDb(new MessageDb()), m_rosterDb(new RosterDb(m_database)), m_cltThrd(new QThread()) { - Q_ASSERT(!Kaidan::s_instance); - Kaidan::s_instance = this; + Q_ASSERT(!s_instance); + s_instance = this; // Database setup m_database->moveToThread(m_dbThrd); m_msgDb->moveToThread(m_dbThrd); m_rosterDb->moveToThread(m_dbThrd); connect(m_dbThrd, &QThread::started, m_database, &Database::openDatabase); m_dbThrd->setObjectName("SqlDatabase"); m_dbThrd->start(); // Caching components m_caches = new ClientWorker::Caches(this, m_rosterDb, m_msgDb, this); // Connect the avatar changed signal of the avatarStorage with the NOTIFY signal // of the Q_PROPERTY for the avatar storage (so all avatars are updated in QML) connect(m_caches->avatarStorage, &AvatarFileStorage::avatarIdsChanged, this, &Kaidan::avatarStorageChanged); // // Load settings // creds.jid = m_caches->settings->value(KAIDAN_SETTINGS_AUTH_JID).toString(); creds.jidResource = m_caches->settings->value(KAIDAN_SETTINGS_AUTH_RESOURCE) .toString(); creds.password = QString(QByteArray::fromBase64(m_caches->settings->value( KAIDAN_SETTINGS_AUTH_PASSWD).toString().toUtf8())); // use Kaidan as resource, if no set if (creds.jidResource.isEmpty()) setJidResource(APPLICATION_DISPLAY_NAME); creds.isFirstTry = false; // // Start ClientWorker on new thread // m_client = new ClientWorker(m_caches, this, enableLogging, app); m_client->setCredentials(creds); m_client->moveToThread(m_cltThrd); connect(m_client, &ClientWorker::connectionErrorChanged, this, &Kaidan::setConnectionError); connect(m_cltThrd, &QThread::started, m_client, &ClientWorker::main); m_client->setObjectName("XmppClient"); m_cltThrd->start(); // account deletion connect(this, &Kaidan::deleteAccountFromClient, m_client, &ClientWorker::deleteAccountFromClient); connect(this, &Kaidan::deleteAccountFromClientAndServer, m_client, &ClientWorker::deleteAccountFromClientAndServer); } Kaidan::~Kaidan() { delete m_caches; delete m_database; - Kaidan::s_instance = nullptr; + s_instance = nullptr; } void Kaidan::start() { if (creds.jid.isEmpty() || creds.password.isEmpty()) emit newCredentialsNeeded(); else mainConnect(); } void Kaidan::mainConnect() { emit m_client->credentialsUpdated(creds); emit m_client->connectRequested(); } void Kaidan::mainDisconnect() { // disconnect the client if connected or connecting if (connectionState != ConnectionState::StateDisconnected) emit m_client->disconnectRequested(); } void Kaidan::setConnectionState(QXmppClient::State state) { if (this->connectionState != static_cast(state)) { this->connectionState = static_cast(state); emit connectionStateChanged(); // Open the possibly cached URI when connected. // This is needed because the XMPP URIs can't be opened when Kaidan is not connected. if (connectionState == ConnectionState::StateConnected && !openUriCache.isEmpty()) { // delay is needed because sometimes the RosterPage needs to be loaded first QTimer::singleShot(300, [=] () { emit xmppUriReceived(openUriCache); openUriCache = ""; }); } } } void Kaidan::setConnectionError(ClientWorker::ConnectionError error) { connectionError = error; emit connectionErrorChanged(); } void Kaidan::deleteCredentials() { // Delete the JID. m_caches->settings->remove(KAIDAN_SETTINGS_AUTH_JID); setJid(QString()); // Delete the password. m_caches->settings->remove(KAIDAN_SETTINGS_AUTH_PASSWD); setPassword(QString()); // Trigger the opening of the login page. emit newCredentialsNeeded(); } bool Kaidan::notificationsMuted(const QString &jid) { return m_caches->settings->value(QString("muted/") + jid, false).toBool(); } void Kaidan::setNotificationsMuted(const QString &jid, bool muted) { m_caches->settings->setValue(QString("muted/") + jid, muted); emit notificationsMutedChanged(jid); } void Kaidan::setJid(const QString &jid) { creds.jid = jid; // credentials were modified -> first try creds.isFirstTry = true; emit jidChanged(); } void Kaidan::setJidResource(const QString &jidResource) { // JID resource won't influence the authentication, so we don't need // to set the first try flag and can save it. creds.jidResource = jidResource; m_caches->settings->setValue(KAIDAN_SETTINGS_AUTH_RESOURCE, jidResource); emit jidResourceChanged(); } void Kaidan::setPassword(const QString &password) { creds.password = password; // credentials were modified -> first try creds.isFirstTry = true; emit passwordChanged(); } quint8 Kaidan::getConnectionError() const { return static_cast(connectionError); } void Kaidan::addOpenUri(const QString &uri) { if (!QXmppUri::isXmppUri(uri)) return; if (connectionState == ConnectionState::StateConnected) { emit xmppUriReceived(uri); } else { //: The link is an XMPP-URI (i.e. 'xmpp:kaidan@muc.kaidan.im?join' for joining a chat) emit passiveNotificationRequested(tr("The link will be opened after you have connected.")); openUriCache = uri; } } void Kaidan::loginByUri(const QString &uri) { // input does not start with 'xmpp:' if (!QXmppUri::isXmppUri(uri)) { notifyLoginUriNotFound(); return; } // parse QXmppUri parsedUri(uri); // no JID provided if (parsedUri.jid().isEmpty()) { notifyLoginUriNotFound(); return; } setJid(parsedUri.jid()); // URI has no login action or no password if (!parsedUri.hasAction(QXmppUri::Action::Login) || parsedUri.password().isEmpty()) { // reset password setPassword(QString()); emit passiveNotificationRequested(tr("No password found. Please enter it.")); return; } setPassword(parsedUri.password()); // try to connect mainConnect(); } void Kaidan::notifyLoginUriNotFound() { qWarning() << "[main]" << "No valid login URI found."; emit passiveNotificationRequested(tr("No valid login QR code found.")); } ClientWorker *Kaidan::getClient() const { return m_client; } RosterDb *Kaidan::rosterDb() const { return m_rosterDb; } MessageDb *Kaidan::messageDb() const { return m_msgDb; } Kaidan *Kaidan::instance() { return s_instance; }