Warning, file /utilities/daykountdown/src/main.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 * SPDX-FileCopyrightText: (C) 2021 Carl Schwan <carl@carlschwan.eu>
0003 * SPDX-FileCopyrightText: (C) 2021 Claudio Cambra <claudio.cambra@gmail.com>
0004 * 
0005 * SPDX-LicenseRef: GPL-3.0-or-later
0006 */
0007 
0008 #include <QApplication>
0009 #include <QCommandLineParser>
0010 #include <QQmlApplicationEngine>
0011 #include <QQuickStyle>
0012 #include <QtQml>
0013 
0014 #include <QUrl>
0015 #include <QIcon>
0016 
0017 #include <QSqlDatabase>
0018 #include <QSqlError>
0019 #include <QSqlQuery>
0020 
0021 #include <KLocalizedContext>
0022 #include <KAboutData>
0023 #include <KLocalizedString>
0024 
0025 #include "kountdownmodel.h"
0026 #include "importexport.h"
0027 #include "aboutdatapasser.h"
0028 #include "daykountdownconfig.h"
0029 /* This last header file is auto-created by daykountdown.kcfgc
0030  * It allows us to easily instantiate the config class by the name provided there.
0031  */
0032 
0033 // Define the database driver in a string
0034 const QString DRIVER(QStringLiteral("QSQLITE"));
0035 
0036 /* #ifdefs are ifs that affect the preprocessor.
0037  * We can use this to compile specific chunks of code depending on the platform!
0038  */
0039 #ifdef Q_OS_ANDROID
0040 Q_DECL_EXPORT 
0041 #endif
0042 int main(int argc, char *argv[])
0043 {
0044     // Enable HiDPI scaling
0045     QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
0046     
0047 #ifdef Q_OS_ANDROID
0048     QGuiApplication app(argc, argv);
0049     QQuickStyle::setStyle(QStringLiteral("Material"));
0050 #else
0051     // QApplication handles initialisation and includes extensive functionality
0052     QApplication app(argc, argv);
0053     if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
0054         QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
0055     }
0056 #endif
0057 
0058     KLocalizedString::setApplicationDomain("daykountdown");
0059 
0060     // KAboutData instances hold information about the application
0061     KAboutData about(QStringLiteral("daykountdown"), i18nc("@title", "DayKountdown"), QStringLiteral("0.1"),
0062                         i18nc("@title", "A day countdown application"),
0063                         KAboutLicense::GPL_V3);
0064 
0065     about.addAuthor(i18nc("@info:credit", "Claudio Cambra"), i18nc("@info:credit", "Creator"), 
0066                     QStringLiteral("claudio.cambra@gmail.com"));
0067     about.addAuthor(i18nc("@info:credit", "Carl Schwan"), i18nc("@info:credit", "SQLite pro and code review"));
0068 
0069     // Sets the KAboutData instance
0070     KAboutData::setApplicationData(about);
0071     QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.daykountdown")));
0072     
0073     // We are instantiating the kcfg here
0074     auto config = DayKountdownConfig::self();
0075 
0076     // Q_ASSERTs hald the problem if the argument is false
0077     Q_ASSERT(QSqlDatabase::isDriverAvailable(DRIVER));
0078     
0079     /*
0080      * .mkpath() creates the directory oath, including all parent directories (returning true if successful)
0081      * cleanPath() returns the path with directory separators normalised ("/") and redundant ones removed 
0082      *  also "." and ".." resolved
0083      * QStandardPaths is a class that provides methods to query standard locations on the filesystem
0084      * writableLocation() returns the directory where files of QStandardPaths::DataLocation type should be written to
0085      */
0086     Q_ASSERT(QDir().mkpath(QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))));
0087     // Creates SQLite database object instance
0088     QSqlDatabase db = QSqlDatabase::addDatabase(DRIVER);
0089     // The auto keyword automatically decides the type of the variable 'path' at compile time
0090     // This line defines a path for our application to have a folder to save stuff in
0091     // qApp macro returns a pointer to the running QApplication instance
0092     const auto path = QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/") + qApp->applicationName());
0093     db.setDatabaseName(path);
0094     if (!db.open()) {
0095         qCritical() << db.lastError() << "while opening database at" << path;
0096     }
0097 
0098     // Let Qt parse and remove arguments meant to affect Qt
0099     QCommandLineParser parser;
0100     about.setupCommandLine(&parser);
0101     parser.process(app);
0102     about.processCommandLine(&parser);
0103 
0104     QQmlApplicationEngine engine;
0105     
0106     // We instantiate the AboutDataPasser class so we can easily pass the about data to QML
0107     AboutDataPasser AboutData;
0108     AboutData.setAboutData(about);
0109     
0110     // Lets you import instantiations of these classes into QML code
0111     qmlRegisterSingletonInstance("org.kde.daykountdown.private", 1, 0, "KountdownModel", new KountdownModel(qApp));
0112     qmlRegisterSingletonInstance("org.kde.daykountdown.private", 1, 0, "ImportExport", new ImportExport());
0113     qmlRegisterSingletonInstance("org.kde.daykountdown.private", 1, 0, "AboutData", &AboutData);
0114     qmlRegisterSingletonInstance("org.kde.daykountdown.private", 1, 0, "Config", config);
0115 
0116     // Set up localisation functionality
0117     engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
0118     // Load main.qml
0119     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
0120 
0121     // Stop function if QML is empty
0122     if (engine.rootObjects().isEmpty()) {
0123         return -1;
0124     }
0125     
0126     return app.exec();
0127 }