diff --git a/src/main.cpp b/src/main.cpp index b44f8f9..2c3e662 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,396 +1,394 @@ /* * 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 . */ // Qt #include #include #include #include #include #include #include #include #include #include #include #include // QXmpp #include "qxmpp-exts/QXmppUploadManager.h" #include // Kaidan #include "AvatarFileStorage.h" #include "EmojiModel.h" #include "Enums.h" #include "Kaidan.h" #include "Message.h" #include "MessageModel.h" #include "PresenceCache.h" #include "QmlUtils.h" #include "RosterModel.h" #include "RosterFilterProxyModel.h" #include "StatusBar.h" #include "UploadManager.h" #include "EmojiModel.h" #include "Utils.h" #include "QrCodeGenerator.h" #include "QrCodeScannerFilter.h" #include "VCardModel.h" #include "CameraModel.h" #include "AudioDeviceModel.h" #include "MediaSettingModel.h" #include "MediaUtils.h" #include "MediaRecorder.h" #include "CredentialsValidator.h" #ifdef STATIC_BUILD #include "static_plugins.h" #endif #ifndef QAPPLICATION_CLASS #define QAPPLICATION_CLASS QApplication #endif #include QT_STRINGIFY(QAPPLICATION_CLASS) #if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID) // SingleApplication (Qt5 replacement for QtSingleApplication) #include "singleapp/singleapplication.h" #endif #ifdef STATIC_BUILD #define KIRIGAMI_BUILD_TYPE_STATIC #include "./3rdparty/kirigami/src/kirigamiplugin.h" #endif #ifdef Q_OS_ANDROID #include #endif #ifdef Q_OS_WIN #include #endif enum CommandLineParseResult { CommandLineOk, CommandLineError, CommandLineVersionRequested, CommandLineHelpRequested }; CommandLineParseResult parseCommandLine(QCommandLineParser &parser, QString *errorMessage) { // application description parser.setApplicationDescription(QString(APPLICATION_DISPLAY_NAME) + " - " + QString(APPLICATION_DESCRIPTION)); // add all possible arguments QCommandLineOption helpOption = parser.addHelpOption(); QCommandLineOption versionOption = parser.addVersionOption(); parser.addOption({"disable-xml-log", "Disable output of full XMPP XML stream."}); parser.addOption({{"m", "multiple"}, "Allow multiple instances to be started."}); parser.addPositionalArgument("xmpp-uri", "An XMPP-URI to open (i.e. join a chat).", "[xmpp-uri]"); // parse arguments if (!parser.parse(QGuiApplication::arguments())) { *errorMessage = parser.errorText(); return CommandLineError; } // check for special cases if (parser.isSet(versionOption)) return CommandLineVersionRequested; if (parser.isSet(helpOption)) return CommandLineHelpRequested; // if nothing special happened, return OK return CommandLineOk; } Q_DECL_EXPORT int main(int argc, char *argv[]) { #ifdef Q_OS_WIN if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); } #endif - // initialize random generator - qsrand(time(nullptr)); // // App // #ifdef UBUNTU_TOUCH qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "true"); qputenv("QT_QUICK_CONTROLS_MOBILE", "true"); #endif #ifdef APPIMAGE qputenv("OPENSSL_CONF", ""); #endif // name, display name, description QGuiApplication::setApplicationName(APPLICATION_NAME); QGuiApplication::setApplicationDisplayName(APPLICATION_DISPLAY_NAME); QGuiApplication::setApplicationVersion(VERSION_STRING); // attributes QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); // create a qt app #if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) QGuiApplication app(argc, argv); #else SingleApplication app(argc, argv, true); #endif #ifdef APPIMAGE QFileInfo executable(QCoreApplication::applicationFilePath()); if (executable.isSymLink()) { executable.setFile(executable.symLinkTarget()); } QString gstreamerPluginsPath; // Try to use deployed plugins if any... #if defined(TARGET_GSTREAMER_PLUGINS) gstreamerPluginsPath = QString::fromLocal8Bit(TARGET_GSTREAMER_PLUGINS); if (!gstreamerPluginsPath.isEmpty()) { gstreamerPluginsPath = QDir::cleanPath(QString::fromLatin1("%1/../..%2") .arg(executable.absolutePath(), gstreamerPluginsPath)); } qDebug() << "Looking for gstreamer in " << gstreamerPluginsPath; #else qFatal("Please provide the unified directory containing the gstreamer plugins and gst-plugin-scanner."); #endif #if defined(QT_DEBUG) qputenv("GST_DEBUG", "ERROR:5,WARNING:5,INFO:5,DEBUG:5,LOG:5"); #endif qputenv("GST_PLUGIN_PATH_1_0", QByteArray()); qputenv("GST_PLUGIN_SYSTEM_PATH_1_0", gstreamerPluginsPath.toLocal8Bit()); qputenv("GST_PLUGIN_SCANNER_1_0", QString::fromLatin1("%1/gst-plugin-scanner").arg(gstreamerPluginsPath).toLocal8Bit()); #endif // APPIMAGE // register qMetaTypes qRegisterMetaType("RosterItem"); qRegisterMetaType("RosterModel*"); qRegisterMetaType("Message"); qRegisterMetaType("MessageModel*"); qRegisterMetaType("AvatarFileStorage*"); qRegisterMetaType("PresenceCache*"); qRegisterMetaType("QXmppPresence"); qRegisterMetaType("Credentials"); qRegisterMetaType("Qt::ApplicationState"); qRegisterMetaType("QXmppClient::State"); qRegisterMetaType("MessageType"); qRegisterMetaType("TransferJob*"); qRegisterMetaType("QmlUtils*"); qRegisterMetaType>("QVector"); qRegisterMetaType>("QVector"); qRegisterMetaType>("QHash"); qRegisterMetaType>("std::function"); qRegisterMetaType>("std::function"); qRegisterMetaType("ClientWorker::Credentials"); qRegisterMetaType("QXmppVCardIq"); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType("QXmppStanza::Error"); // Enums for c++ member calls using enums qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); // Qt-Translator QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); QCoreApplication::installTranslator(&qtTranslator); // Kaidan-Translator QTranslator kaidanTranslator; // load the systems locale or none from resources kaidanTranslator.load(QLocale::system().name(), ":/i18n"); QCoreApplication::installTranslator(&kaidanTranslator); // // Command line arguments // // create parser and add a description QCommandLineParser parser; // parse the arguments QString commandLineErrorMessage; switch (parseCommandLine(parser, &commandLineErrorMessage)) { case CommandLineError: qWarning() << commandLineErrorMessage; return 1; case CommandLineVersionRequested: parser.showVersion(); return 0; case CommandLineHelpRequested: parser.showHelp(); return 0; case CommandLineOk: break; } #if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID) // check if another instance already runs if (app.isSecondary() && !parser.isSet("multiple")) { qDebug().noquote() << QString("Another instance of %1 is already running.") .arg(APPLICATION_DISPLAY_NAME) << "You can enable multiple instances by specifying '--multiple'."; // send a possible link to the primary instance if (!parser.positionalArguments().isEmpty()) app.sendMessage(parser.positionalArguments().first().toUtf8()); return 0; } #endif // // Kaidan back-end // auto *kaidan = new Kaidan(&app, !parser.isSet("disable-xml-log")); #if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID) // receive messages from other instances of Kaidan Kaidan::connect(&app, &SingleApplication::receivedMessage, kaidan, &Kaidan::receiveMessage); #endif // open the XMPP-URI/link (if given) if (!parser.positionalArguments().isEmpty()) kaidan->addOpenUri(parser.positionalArguments().first()); // // QML-GUI // if (QIcon::themeName().isEmpty()) { QIcon::setThemeName("breeze"); } QQmlApplicationEngine engine; // QtQuickControls2 Style if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) { #ifdef Q_OS_WIN const QString defaultStyle = QStringLiteral("Universal"); #else const QString defaultStyle = QStringLiteral("Material"); #endif qDebug() << "QT_QUICK_CONTROLS_STYLE not set, setting to" << defaultStyle; qputenv("QT_QUICK_CONTROLS_STYLE", defaultStyle.toLatin1()); } // QML type bindings #ifdef STATIC_BUILD KirigamiPlugin::getInstance().registerTypes(); #endif qmlRegisterType("StatusBar", 0, 1, "StatusBar"); qmlRegisterType("EmojiModel", 0, 1, "EmojiModel"); qmlRegisterType("EmojiModel", 0, 1, "EmojiProxyModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "QrCodeScannerFilter"); qmlRegisterType(APPLICATION_ID, 1, 0, "VCardModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "RosterFilterProxyModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "CameraModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "AudioDeviceModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsContainerModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsResolutionModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsQualityModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsImageCodecModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsAudioCodecModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsAudioSampleRateModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsVideoCodecModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaSettingsVideoFrameRateModel"); qmlRegisterType(APPLICATION_ID, 1, 0, "MediaRecorder"); qmlRegisterType(APPLICATION_ID, 1, 0, "CredentialsValidator"); qmlRegisterType(APPLICATION_ID, 1, 0, "QrCodeGenerator"); qmlRegisterUncreatableType("EmojiModel", 0, 1, "QAbstractItemModel", "Used by proxy models"); qmlRegisterUncreatableType("EmojiModel", 0, 1, "Emoji", "Used by emoji models"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "TransferJob", "TransferJob type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "QMimeType", "QMimeType type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "CameraInfo", "CameraInfo type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "AudioDeviceInfo", "AudioDeviceInfo type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "MediaSettings", "MediaSettings type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "CommonEncoderSettings", "CommonEncoderSettings type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "ImageEncoderSettings", "ImageEncoderSettings type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "AudioEncoderSettings", "AudioEncoderSettings type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "VideoEncoderSettings", "VideoEncoderSettings type usable"); qmlRegisterUncreatableType(APPLICATION_ID, 1, 0, "ClientWorker", "Cannot create object; only enums defined!"); qmlRegisterUncreatableMetaObject(Enums::staticMetaObject, APPLICATION_ID, 1, 0, "Enums", "Can't create object; only enums defined!"); qmlRegisterSingletonType("MediaUtils", 0, 1, "MediaUtilsInstance", [](QQmlEngine *, QJSEngine *) { QObject *instance = new MediaUtils(qApp); return instance; }); qmlRegisterSingletonType(APPLICATION_ID, 1, 0, "Utils", [](QQmlEngine *, QJSEngine *) { return static_cast(QmlUtils::instance()); }); qmlRegisterSingletonType(APPLICATION_ID, 1, 0, "Kaidan", [](QQmlEngine *, QJSEngine *) { return static_cast(Kaidan::instance()); }); engine.load(QUrl("qrc:/qml/main.qml")); if (engine.rootObjects().isEmpty()) return -1; #ifdef Q_OS_ANDROID QtAndroid::hideSplashScreen(); #endif // enter qt main loop return app.exec(); }