File indexing completed on 2025-04-20 04:02:15
0001 /* 0002 * SPDX-FileCopyrightText: (C) 2014 Vishesh Handa <vhanda@kde.org> 0003 * SPDX-FileCopyrightText: (C) 2017 Atul Sharma <atulsharma406@gmail.com> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include <QQmlApplicationEngine> 0009 #include <QQmlComponent> 0010 #include <QQmlContext> 0011 0012 #include <QDebug> 0013 #include <QDir> 0014 #include <QStandardPaths> 0015 #include <QThread> 0016 0017 #include <KAboutData> 0018 #include <KDBusService> 0019 #include <KLocalizedContext> 0020 #include <KLocalizedString> 0021 #include <KWindowSystem> 0022 0023 #include <QApplication> 0024 #include <QCommandLineOption> 0025 #include <QCommandLineParser> 0026 #include <QQuickView> 0027 0028 #include <iostream> 0029 0030 #include "controller.h" 0031 #include "filemenu.h" 0032 #include "filesystemtracker.h" 0033 #include "imagestorage.h" 0034 #include "kokoconfig.h" 0035 #include "openfilemodel.h" 0036 #include "processor.h" 0037 #include "vectorimage.h" 0038 #include "version.h" 0039 0040 #ifndef Q_OS_ANDROID 0041 #include <KConfigGroup> 0042 #include <KSharedConfig> 0043 #include <KWindowConfig> 0044 #include <QQuickWindow> 0045 #else 0046 #include <QtAndroid> 0047 #endif 0048 0049 int main(int argc, char **argv) 0050 { 0051 QApplication app(argc, argv); 0052 KLocalizedString::setApplicationDomain("koko"); 0053 app.setApplicationDisplayName("Koko"); 0054 app.setOrganizationDomain("kde.org"); 0055 0056 KAboutData aboutData(QStringLiteral("koko"), 0057 xi18nc("@title", "<application>Koko</application>"), 0058 QStringLiteral(KOKO_VERSION_STRING), 0059 xi18nc("@title", "Koko is an image viewer for your image collection."), 0060 KAboutLicense::LGPL, 0061 xi18nc("@info:credit", "(c) 2013-2020 KDE Contributors")); 0062 0063 aboutData.setOrganizationDomain(QByteArray("kde.org")); 0064 aboutData.setProductName(QByteArray("koko")); 0065 aboutData.setBugAddress("https://bugs.kde.org/describecomponents.cgi?product=koko"); 0066 0067 aboutData.addAuthor(xi18nc("@info:credit", "Vishesh Handa"), xi18nc("@info:credit", "Developer"), "vhanda@kde.org"); 0068 0069 aboutData.addAuthor(xi18nc("@info:credit", "Atul Sharma"), xi18nc("@info:credit", "Developer"), "atulsharma406@gmail.com"); 0070 0071 aboutData.addAuthor(xi18nc("@info:credit", "Marco Martin"), xi18nc("@info:credit", "Developer"), "mart@kde.org"); 0072 0073 aboutData.addAuthor(xi18nc("@info:credit", "Nicolas Fella"), xi18nc("@info:credit", "Developer"), "nicolas.fella@gmx.de"); 0074 0075 aboutData.addAuthor(xi18nc("@info:credit", "Carl Schwan"), xi18nc("@info:credit", "Developer"), "carl@carlschwan.eu"); 0076 0077 aboutData.addAuthor(xi18nc("@info:credit", "Mikel Johnson"), xi18nc("@info:credit", "Developer"), "mikel5764@gmail.com"); 0078 0079 KAboutData::setApplicationData(aboutData); 0080 0081 KLocalizedString::setApplicationDomain("koko"); 0082 0083 QCommandLineParser parser; 0084 parser.setApplicationDescription(i18n("Image viewer")); 0085 parser.addOption(QCommandLineOption("reset", i18n("Reset the database"))); 0086 parser.addPositionalArgument("image", i18n("path of image you want to open")); 0087 0088 aboutData.setupCommandLine(&parser); 0089 parser.process(app); 0090 aboutData.processCommandLine(&parser); 0091 0092 QApplication::setApplicationName(aboutData.componentName()); 0093 QApplication::setApplicationDisplayName(aboutData.displayName()); 0094 QApplication::setOrganizationDomain(aboutData.organizationDomain()); 0095 QApplication::setApplicationVersion(aboutData.version()); 0096 QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("koko"))); 0097 0098 if (parser.isSet("reset") || ImageStorage::shouldReset()) { 0099 ImageStorage::reset(); 0100 } 0101 0102 KDBusService service(KDBusService::Unique); 0103 0104 QThread trackerThread; 0105 0106 QStringList locations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); 0107 Q_ASSERT(locations.size() >= 1); 0108 qDebug() << locations; 0109 0110 QUrl currentDirPath = QUrl::fromLocalFile(QDir::currentPath().append('/')); 0111 0112 QStringList directoryUrls; 0113 for (const auto &path : parser.positionalArguments()) { 0114 directoryUrls << currentDirPath.resolved(path).toString(); 0115 } 0116 0117 #ifdef Q_OS_ANDROID 0118 QtAndroid::requestPermissionsSync({"android.permission.WRITE_EXTERNAL_STORAGE"}); 0119 #endif 0120 0121 FileSystemTracker tracker; 0122 tracker.setFolder(locations.first()); 0123 tracker.moveToThread(&trackerThread); 0124 0125 Koko::Processor processor; 0126 QObject::connect(&tracker, &FileSystemTracker::imageAdded, &processor, &Koko::Processor::addFile); 0127 QObject::connect(&tracker, &FileSystemTracker::imageRemoved, &processor, &Koko::Processor::removeFile); 0128 QObject::connect(&tracker, &FileSystemTracker::initialScanComplete, &processor, &Koko::Processor::initialScanCompleted); 0129 0130 QObject::connect(&trackerThread, &QThread::started, &tracker, &FileSystemTracker::setupDb); 0131 0132 trackerThread.start(); 0133 tracker.setSubFolder(tracker.folder()); 0134 0135 KokoConfig config; 0136 // General group 0137 QObject::connect(&config, &KokoConfig::IconSizeChanged, &config, &KokoConfig::save); 0138 QObject::connect(&config, &KokoConfig::ImageViewPreviewChanged, &config, &KokoConfig::save); 0139 QObject::connect(&config, &KokoConfig::SavedFoldersChanged, &config, &KokoConfig::save); 0140 // Slideshow group 0141 QObject::connect(&config, &KokoConfig::NextImageIntervalChanged, &config, &KokoConfig::save); 0142 QObject::connect(&config, &KokoConfig::LoopImagesChanged, &config, &KokoConfig::save); 0143 QObject::connect(&config, &KokoConfig::RandomizeImagesChanged, &config, &KokoConfig::save); 0144 // KokoConfig WindowState group 0145 QObject::connect(&config, &KokoConfig::WidthChanged, &config, &KokoConfig::save); 0146 QObject::connect(&config, &KokoConfig::HeightChanged, &config, &KokoConfig::save); 0147 QObject::connect(&config, &KokoConfig::VisibilityChanged, &config, &KokoConfig::save); 0148 QObject::connect(&config, &KokoConfig::ControlsVisibleChanged, &config, &KokoConfig::save); 0149 0150 QQmlApplicationEngine engine; 0151 engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); 0152 0153 OpenFileModel openFileModel(directoryUrls); 0154 QObject::connect(&service, 0155 &KDBusService::activateRequested, 0156 &openFileModel, 0157 [&openFileModel, &parser, &engine](const QStringList &arguments, const QString &workingDirectory) { 0158 QUrl currentDirPath = QUrl::fromLocalFile(workingDirectory); 0159 0160 parser.parse(arguments); 0161 0162 QStringList directoryUrls; 0163 for (const auto &path : parser.positionalArguments()) { 0164 directoryUrls << currentDirPath.resolved(path).toString(); 0165 } 0166 0167 openFileModel.updateOpenFiles(directoryUrls); 0168 0169 const auto rootObjects = engine.rootObjects(); 0170 for (auto obj : rootObjects) { 0171 auto window = qobject_cast<QQuickWindow *>(obj); 0172 if (window) { 0173 KWindowSystem::updateStartupId(window); 0174 KWindowSystem::activateWindow(window); 0175 return; 0176 } 0177 } 0178 }); 0179 0180 qmlRegisterSingletonInstance("org.kde.koko.private", 0, 1, "OpenFileModel", &openFileModel); 0181 qmlRegisterType<VectorImage>("org.kde.koko.image", 0, 1, "VectorImage"); 0182 qmlRegisterType<FileMenu>("org.kde.koko.private", 0, 1, "FileMenu"); 0183 0184 Controller controller; 0185 qmlRegisterSingletonInstance("org.kde.koko.private", 0, 1, "Controller", &controller); 0186 0187 engine.rootContext()->setContextProperty("kokoProcessor", &processor); 0188 engine.rootContext()->setContextProperty("kokoConfig", &config); 0189 engine.rootContext()->setContextProperty(QStringLiteral("kokoAboutData"), QVariant::fromValue(aboutData)); 0190 0191 // we want different main files on desktop or mobile 0192 // very small difference as they as they are subclasses of the same thing 0193 engine.load(QUrl(QStringLiteral("qrc:/qml/Main.qml"))); 0194 0195 #ifndef Q_OS_ANDROID 0196 const auto rootObjects = engine.rootObjects(); 0197 for (auto obj : rootObjects) { 0198 auto view = qobject_cast<QQuickWindow *>(obj); 0199 if (view) { 0200 KConfig dataResource(QStringLiteral("data"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); 0201 KConfigGroup windowGroup(&dataResource, "Window"); 0202 KWindowConfig::restoreWindowSize(view, windowGroup); 0203 KWindowConfig::restoreWindowPosition(view, windowGroup); 0204 break; 0205 } 0206 } 0207 #endif 0208 0209 int rt = app.exec(); 0210 trackerThread.quit(); 0211 return rt; 0212 }