File indexing completed on 2024-04-14 05:43:20
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2019 Bhushan Shah <bshah@kde.org> 0004 * SPDX-FileCopyrightText: 2020-2021 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0005 * SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com> 0006 */ 0007 0008 #include <QCommandLineParser> 0009 #include <QQmlApplicationEngine> 0010 #include <QQuickStyle> 0011 #include <QtQml> 0012 #include <QUrl> 0013 0014 #ifdef Q_OS_ANDROID 0015 #include <QGuiApplication> 0016 #else 0017 #include <QApplication> 0018 #endif 0019 0020 #include <KLocalizedContext> 0021 #include <KLocalizedString> 0022 0023 #include "app/cli.h" 0024 #include "app/keysmith.h" 0025 #include "app/vms.h" 0026 #include "model/accounts.h" 0027 #include "model/input.h" 0028 #include "validators/countervalidator.h" 0029 #include "validators/datetimevalidator.h" 0030 #include "validators/issuervalidator.h" 0031 #include "validators/secretvalidator.h" 0032 0033 #include "keysmith-features.h" 0034 #include "version.h" 0035 0036 /* 0037 * Integrate QML debugging/profiling support, conditional on building Keysmith in Debug mode. 0038 * NDEBUG is defined by the C standard and automatically set by CMake during a Release type build, hence the double negative. 0039 */ 0040 #ifndef NDEBUG 0041 #include <QQmlDebuggingEnabler> 0042 static QQmlDebuggingEnabler enabler; 0043 #endif 0044 0045 #ifdef ENABLE_DBUS_INTERFACE 0046 #include <KDBusService> 0047 #endif 0048 0049 Q_DECL_EXPORT int main(int argc, char *argv[]) 0050 { 0051 #ifdef Q_OS_ANDROID 0052 QGuiApplication app(argc, argv); 0053 QQuickStyle::setStyle(QStringLiteral("org.kde.breeze")); 0054 #else 0055 QApplication app(argc, argv); 0056 if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) { 0057 QQuickStyle::setStyle(QStringLiteral("org.kde.desktop")); 0058 } 0059 #endif 0060 0061 KLocalizedString::setApplicationDomain("keysmith"); 0062 0063 QCoreApplication::setOrganizationName(QStringLiteral("KDE")); 0064 QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); 0065 QCoreApplication::setApplicationName(QStringLiteral("keysmith")); 0066 QCoreApplication::setApplicationVersion(KEYSMITH_VERSION_STRING); 0067 QGuiApplication::setApplicationDisplayName(i18nc("@title", "Keysmith")); 0068 0069 QCommandLineParser cliParser; 0070 0071 // default/boilerplate options handled entirely via command line 0072 const auto helpOption = cliParser.addHelpOption(); 0073 const auto versionOption = cliParser.addVersionOption(); 0074 0075 bool parseOk = app::Proxy::parseCommandLine(cliParser, QCoreApplication::arguments()); 0076 0077 /* 0078 * First check for pure command line options and handle these. 0079 * If any are found, the application should not bother with an UI. 0080 */ 0081 0082 if (cliParser.isSet(helpOption)) { 0083 int ret = parseOk ? 0 : 1; 0084 cliParser.showHelp(ret); 0085 return ret; // just to be explicit: showHelp() is documented to call exit() 0086 } 0087 0088 if (cliParser.isSet(versionOption)) { 0089 cliParser.showVersion(); 0090 return 0; // just to be explicit: showVersion() is documented to call exit() 0091 } 0092 0093 app::Proxy proxy(&app); 0094 0095 #ifdef ENABLE_DBUS_INTERFACE 0096 KDBusService service(KDBusService::Unique); 0097 QObject::connect(&service, &KDBusService::activateRequested, &proxy, &app::Proxy::handleDBusActivation); 0098 #endif 0099 0100 QQmlApplicationEngine engine; 0101 engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); 0102 0103 qmlRegisterUncreatableType<app::AddAccountViewModel>("Keysmith.Application", 1, 0, "AddAccountViewModel", 0104 QStringLiteral("Should be automatically provided through Keysmith.Application.Navigation signals") 0105 ); 0106 qmlRegisterUncreatableType<app::RenameAccountViewModel>("Keysmith.Application", 1, 0, "RenameAccountViewModel", 0107 QStringLiteral("Should be automatically provided through Keysmith.Navigation signals") 0108 ); 0109 qmlRegisterUncreatableType<app::ErrorViewModel>("Keysmith.Application", 1, 0, "ErrorViewModel", 0110 QStringLiteral("Should be automatically provided through Keysmith.Navigation signals") 0111 ); 0112 qmlRegisterUncreatableType<app::SetupPasswordViewModel>("Keysmith.Application", 1, 0, "SetupPasswordViewModel", 0113 QStringLiteral("Should be automatically provided through Keysmith.Navigation signals") 0114 ); 0115 qmlRegisterUncreatableType<app::UnlockAccountsViewModel>("Keysmith.Application", 1, 0, "UnlockAccountsViewModel", 0116 QStringLiteral("Should be automatically provided through Keysmith.Navigation signals") 0117 ); 0118 qmlRegisterUncreatableType<app::AccountsOverviewViewModel>("Keysmith.Application", 1, 0, "AccountsOverviewViewModel", 0119 QStringLiteral("Should be automatically provided through Keysmith.Navigation signals") 0120 ); 0121 qmlRegisterUncreatableType<app::Navigation>("Keysmith.Application", 1, 0, "Navigation", 0122 QStringLiteral("Use the Keysmith singleton to obtain a Navigation") 0123 ); 0124 0125 qmlRegisterUncreatableType<model::SimpleAccountListModel>("Keysmith.Models", 1, 0, "AccountListModel", 0126 QStringLiteral("Use the Keysmith singleton to obtain an AccountListModel") 0127 ); 0128 qmlRegisterUncreatableType<model::PasswordRequest>("Keysmith.Models", 1, 0, "PasswordRequestModel", 0129 QStringLiteral("Use the Keysmith singleton to obtain an PasswordRequestModel") 0130 ); 0131 qmlRegisterUncreatableType<model::AccountView>("Keysmith.Models", 1, 0, "Account", 0132 QStringLiteral("Use an AccountListModel from the Keysmith singleton to obtain an Account") 0133 ); 0134 qmlRegisterType<model::AccountInput>("Keysmith.Models", 1, 0, "ValidatedAccountInput"); 0135 qmlRegisterType<model::SortedAccountsListModel>("Keysmith.Models", 1, 0, "SortedAccountListModel"); 0136 qmlRegisterType<model::AccountNameValidator>("Keysmith.Validators", 1, 0, "AccountNameValidator"); 0137 qmlRegisterType<validators::EpochValidator>("Keysmith.Validators", 1, 0, "TOTPEpochValidator"); 0138 qmlRegisterType<validators::IssuerValidator>("Keysmith.Validators", 1, 0, "AccountIssuerValidator"); 0139 qmlRegisterType<validators::Base32Validator>("Keysmith.Validators", 1, 0, "Base32SecretValidator"); 0140 qmlRegisterType<validators::UnsignedLongValidator>("Keysmith.Validators", 1, 0, "HOTPCounterValidator"); 0141 qmlRegisterSingletonType<app::Keysmith>("Keysmith.Application", 1, 0, "Keysmith", [&proxy](QQmlEngine *qml, QJSEngine *js) -> QObject * 0142 { 0143 Q_UNUSED(js); 0144 0145 auto app = new app::Keysmith(new app::Navigation(qml)); 0146 proxy.enable(app); 0147 return app; 0148 }); 0149 qmlRegisterSingletonType<app::CommandLineOptions>("Keysmith.Application", 1, 0, "CommandLine", [parseOk, &cliParser](QQmlEngine *qml, QJSEngine *js) -> QObject * 0150 { 0151 Q_UNUSED(qml); 0152 Q_UNUSED(js); 0153 0154 return new app::CommandLineOptions(cliParser, parseOk); 0155 }); 0156 0157 engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); 0158 if (engine.rootObjects().isEmpty()) { 0159 return -1; 0160 } 0161 proxy.proxy(cliParser, parseOk); 0162 return app.exec(); 0163 }