File indexing completed on 2024-05-05 16:07:10
0001 /* 0002 SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <QApplication> 0008 0009 #include <KLocalizedString> 0010 #include <QCommandLineOption> 0011 #include <QCommandLineParser> 0012 #include <QQuickItem> 0013 0014 #include <KAboutData> 0015 #include <QQmlContext> 0016 #include <QQmlEngine> 0017 #include <QQmlExpression> 0018 #include <QQmlProperty> 0019 #include <QQuickWindow> 0020 #include <QStandardPaths> 0021 #include <kdeclarative/qmlobject.h> 0022 #include <kpackage/package.h> 0023 #include <kpackage/packageloader.h> 0024 0025 int main(int argc, char **argv) 0026 { 0027 QCommandLineParser parser; 0028 QApplication app(argc, argv); 0029 0030 const QString description = i18n("KPackage QML application shell"); 0031 0032 app.setApplicationVersion(QStringLiteral("0.1")); 0033 parser.addVersionOption(); 0034 parser.addHelpOption(); 0035 parser.setApplicationDescription(description); 0036 0037 QCommandLineOption appPluginOption(QCommandLineOption(QStringList() << QStringLiteral("a") << QStringLiteral("app"), 0038 i18n("The unique name of the application (mandatory)"), 0039 QStringLiteral("app"))); 0040 0041 parser.addOption(appPluginOption); 0042 0043 parser.process(app); 0044 0045 QString packagePath; 0046 if (parser.isSet(appPluginOption)) { 0047 packagePath = parser.value(appPluginOption); 0048 } else { 0049 parser.showHelp(1); 0050 } 0051 0052 // usually we have an ApplicationWindow here, so we do not need to create a window by ourselves 0053 KDeclarative::QmlObject obj; 0054 obj.setTranslationDomain(packagePath); 0055 obj.setInitializationDelayed(true); 0056 obj.loadPackage(packagePath); 0057 if (!obj.package().isValid()) { 0058 qWarning() << "The specified Application package is not valid."; 0059 return 1; 0060 } 0061 obj.engine()->rootContext()->setContextProperty(QStringLiteral("commandlineArguments"), parser.positionalArguments()); 0062 QVariantMap paths; 0063 paths[QStringLiteral("desktop")] = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); 0064 paths[QStringLiteral("documents")] = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); 0065 paths[QStringLiteral("music")] = QStandardPaths::writableLocation(QStandardPaths::MusicLocation); 0066 paths[QStringLiteral("movies")] = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); 0067 paths[QStringLiteral("pictures")] = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); 0068 paths[QStringLiteral("home")] = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); 0069 obj.engine()->rootContext()->setContextProperty(QStringLiteral("userPaths"), paths); 0070 obj.completeInitialization(); 0071 0072 if (!obj.package().metadata().isValid()) { 0073 return -1; 0074 } 0075 0076 KPluginMetaData data = obj.package().metadata(); 0077 // About data 0078 KAboutData aboutData(data.pluginId(), data.name(), data.version(), data.description(), KAboutLicense::byKeyword(data.license()).key()); 0079 0080 const auto authors = data.authors(); 0081 for (auto &author : authors) { 0082 aboutData.addAuthor(author.name(), author.task(), author.emailAddress(), author.webAddress(), author.ocsUsername()); 0083 } 0084 // We assume that desktop file in applications dir is named similar as 0085 // the pluginId, this is required to get icons working on wayland for example 0086 aboutData.setDesktopFileName(data.pluginId()); 0087 0088 KAboutData::setApplicationData(aboutData); 0089 0090 // The root is not a window? 0091 // have to use a normal QQuickWindow since the root item is already created 0092 QQuickItem *item = qobject_cast<QQuickItem *>(obj.rootObject()); 0093 QWindow *window = qobject_cast<QWindow *>(obj.rootObject()); 0094 if (item) { 0095 QQuickWindow view; 0096 item->setParentItem(view.contentItem()); 0097 if (item->implicitWidth() > 0 && item->implicitHeight() > 0) { 0098 view.resize(item->implicitWidth(), item->implicitHeight()); 0099 } else { 0100 view.resize(item->width(), item->height()); 0101 } 0102 0103 // set anchors 0104 QQmlExpression expr(obj.engine()->rootContext(), obj.rootObject(), QStringLiteral("parent")); 0105 QQmlProperty prop(obj.rootObject(), QStringLiteral("anchors.fill")); 0106 prop.write(expr.evaluate()); 0107 view.setTitle(obj.package().metadata().name()); 0108 view.setIcon(QIcon::fromTheme(obj.package().metadata().iconName())); 0109 0110 // Forward Qt.quit() in QML code to QApplication::quit() 0111 QObject::connect(obj.engine(), &QQmlEngine::quit, &app, &QCoreApplication::quit); 0112 0113 view.show(); 0114 return app.exec(); 0115 } else if (window) { 0116 window->setTitle(obj.package().metadata().name()); 0117 window->setIcon(QIcon::fromTheme(obj.package().metadata().iconName())); 0118 } else { 0119 qWarning() << "The root Qml Item should be either a kind of window or a QQuickItem"; 0120 return 1; 0121 } 0122 0123 return app.exec(); 0124 }