File indexing completed on 2024-05-12 08:02:44

0001 // SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
0002 // SPDX-License-Identifier: LGPL-2.1-only or LGPL-3.0-only or LicenseRef-KDE-Accepted-LGPL
0003 
0004 #include <QCommandLineParser>
0005 #include <QFontDatabase>
0006 #include <QNetworkProxy>
0007 #include <QNetworkProxyFactory>
0008 #include <QQmlApplicationEngine>
0009 #include <QQmlContext>
0010 #include <QQuickStyle>
0011 #include <QQuickWindow>
0012 #include <QtWebEngineQuick>
0013 
0014 #include <QApplication>
0015 
0016 #include <KAboutData>
0017 #include <KConfig>
0018 #include <KDBusService>
0019 #include <KLocalizedContext>
0020 #include <KLocalizedString>
0021 #include <KWindowConfig>
0022 #include <KWindowSystem>
0023 #include <qstringliteral.h>
0024 
0025 #include "arianna-version.h"
0026 #include "bookdatabase.h"
0027 #include "booklistmodel.h"
0028 #include "bookserver.h"
0029 #include "clipboard.h"
0030 #include "config.h"
0031 #include "contentlist/contentlist.h"
0032 #include "contentlist/contentquery.h"
0033 #include "format.h"
0034 #include "navigation.h"
0035 #include "tableofcontentmodel.h"
0036 
0037 int main(int argc, char *argv[])
0038 {
0039     QNetworkProxyFactory::setUseSystemConfiguration(true);
0040     QtWebEngineQuick::initialize();
0041 
0042     QApplication app(argc, argv);
0043     // Default to org.kde.desktop style unless the user forces another style
0044     if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
0045         QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
0046     }
0047 
0048 #ifdef Q_OS_WINDOWS
0049     if (AttachConsole(ATTACH_PARENT_PROCESS)) {
0050         freopen("CONOUT$", "w", stdout);
0051         freopen("CONOUT$", "w", stderr);
0052     }
0053 
0054     QApplication::setStyle(QStringLiteral("breeze"));
0055     auto font = app.font();
0056     font.setPointSize(10);
0057     app.setFont(font);
0058 #endif
0059 
0060     KLocalizedString::setApplicationDomain(QByteArrayLiteral("arianna"));
0061 
0062     KAboutData about(QStringLiteral("arianna"),
0063                      i18n("Arianna"),
0064                      QStringLiteral(ARIANNA_VERSION_STRING),
0065                      i18n("EPub Reader"),
0066                      KAboutLicense::GPL_V3,
0067                      i18n("2022 Niccolò Venerandi <niccolo@venerandi.com>"));
0068     about.addAuthor(i18n("Niccolò Venerandi"), i18n("Maintainer"), QStringLiteral("niccolo@venerandi.com"));
0069     about.addAuthor(i18n("Carl Schwan"), i18n("Maintainer"), QStringLiteral("carl@carlschwan.eu"));
0070     about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
0071     about.setOrganizationDomain("kde.org");
0072     about.setBugAddress("https://bugs.kde.org/describecomponents.cgi?product=arianna");
0073 
0074     KAboutData::setApplicationData(about);
0075     QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.arianna")));
0076 
0077     KDBusService service(KDBusService::Unique);
0078     QQmlApplicationEngine engine;
0079     engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
0080     QObject::connect(&engine, &QQmlApplicationEngine::quit, &app, &QCoreApplication::quit);
0081 
0082     QCommandLineParser parser;
0083     parser.setApplicationDescription(i18n("Epub reader"));
0084     parser.addPositionalArgument(QLatin1String("file"), i18n("Epub file to open"));
0085 
0086     about.setupCommandLine(&parser);
0087     parser.process(app);
0088     about.processCommandLine(&parser);
0089 
0090     Clipboard clipboard;
0091     Format format;
0092     Navigation navigation;
0093     qmlRegisterSingletonInstance("org.kde.arianna", 1, 0, "Config", Config::self());
0094     qmlRegisterSingletonInstance("org.kde.arianna", 1, 0, "Clipboard", &clipboard);
0095     qmlRegisterSingletonInstance("org.kde.arianna", 1, 0, "Format", &format);
0096     qmlRegisterSingletonInstance("org.kde.arianna", 1, 0, "Navigation", &navigation);
0097     qmlRegisterType<BookListModel>("org.kde.arianna", 1, 0, "BookListModel");
0098     qmlRegisterType<ContentList>("org.kde.arianna", 1, 0, "ContentList");
0099     qmlRegisterType<QSortFilterProxyModel>("org.kde.arianna", 1, 0, "SortFilterProxyModel");
0100     qmlRegisterType<ContentQuery>("org.kde.arianna", 1, 0, "ContentQuery");
0101     qmlRegisterType<TableOfContentModel>("org.kde.arianna", 1, 0, "TableOfContentModel");
0102     qmlRegisterType<CategoryEntriesModel>("org.kde.arianna", 1, 0, "CategoryEntriesModel");
0103     qmlRegisterSingletonType("org.kde.arianna", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
0104         return engine->toScriptValue(KAboutData::applicationData());
0105     });
0106 
0107     BookServer bookServer;
0108 
0109     engine.load(QUrl(QStringLiteral("qrc:/content/ui/main.qml")));
0110     if (engine.rootObjects().isEmpty()) {
0111         return -1;
0112     }
0113 
0114     QObject::connect(&service,
0115                      &KDBusService::activateRequested,
0116                      &engine,
0117                      [&engine, &navigation](const QStringList &arguments, const QString & /*workingDirectory*/) {
0118                          const auto rootObjects = engine.rootObjects();
0119                          for (auto obj : rootObjects) {
0120                              auto view = qobject_cast<QQuickWindow *>(obj);
0121                              if (view) {
0122                                  KWindowSystem::updateStartupId(view);
0123                                  KWindowSystem::activateWindow(view);
0124 
0125                                  if (arguments.count() > 1) {
0126                                      const auto entry = BookDatabase::self().loadEntry(arguments[1]);
0127                                      if (auto book = entry) {
0128                                          Q_EMIT navigation.openBook(arguments[1], book->locations, book->currentLocation);
0129                                      } else {
0130                                          Q_EMIT navigation.openBook(arguments[1], {}, {});
0131                                      }
0132                                  }
0133                                  return;
0134                              }
0135                          }
0136                      });
0137     const auto rootObjects = engine.rootObjects();
0138     for (auto obj : rootObjects) {
0139         auto view = qobject_cast<QQuickWindow *>(obj);
0140         if (view) {
0141             KConfig dataResource(QStringLiteral("data"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
0142             KConfigGroup windowGroup(&dataResource, QStringLiteral("Window"));
0143             KWindowConfig::restoreWindowSize(view, windowGroup);
0144             KWindowConfig::restoreWindowPosition(view, windowGroup);
0145             break;
0146         }
0147     }
0148 
0149     const QStringList args = parser.positionalArguments();
0150     if (!args.isEmpty()) {
0151         const auto entry = BookDatabase::self().loadEntry(args[0]);
0152         if (const auto book = entry) {
0153             Q_EMIT navigation.openBook(args[0], book->locations, book->currentLocation);
0154         } else {
0155             Q_EMIT navigation.openBook(args[0], {}, {});
0156         }
0157     }
0158 
0159     return QCoreApplication::exec();
0160 }