File indexing completed on 2024-05-05 05:39:28

0001 /**
0002  * SPDX-FileCopyrightText: 2009 Ben Cooksley <bcooksley@kde.org>
0003  *
0004  * This file was sourced from the System Settings package
0005  * SPDX-FileCopyrightText: 2005 Benjamin C Meyer <ben+systempreferences at meyerhome dot net>
0006  *
0007  * SPDX-License-Identifier: GPL-2.0-or-later
0008  */
0009 
0010 #include <KAboutData>
0011 #include <KCrash>
0012 #include <QApplication>
0013 #include <QCommandLineParser>
0014 #include <QSurfaceFormat>
0015 
0016 #include <KDBusService>
0017 #include <KLocalizedString>
0018 #include <KPluginMetaData>
0019 #include <KWindowSystem>
0020 #include <iostream>
0021 
0022 #include "../core/kcmmetadatahelpers.h"
0023 #include "SettingsBase.h"
0024 
0025 int main(int argc, char *argv[])
0026 {
0027     auto format = QSurfaceFormat::defaultFormat();
0028     format.setOption(QSurfaceFormat::ResetNotification);
0029     QSurfaceFormat::setDefaultFormat(format);
0030 
0031     // Make sure the binary name is either kinfocenter or systemsettings,
0032     // Anything else will just be considered as "systemsettings"
0033     const QString executableName = QString::fromUtf8(argv[0]);
0034     QString binaryName = QStringLiteral("systemsettings");
0035     BaseMode::ApplicationMode mode = BaseMode::SystemSettings;
0036     if (executableName.endsWith(QLatin1String("kinfocenter"))) {
0037         binaryName = QStringLiteral("kinfocenter");
0038         mode = BaseMode::InfoCenter;
0039     }
0040 
0041     // exec is systemsettings, but we need the QPT to use the right config from the qApp constructor
0042     // which is before KAboutData::setApplicationData
0043     QCoreApplication::setApplicationName(binaryName);
0044 
0045     QApplication application(argc, argv);
0046     // The ki18n application domain must be set before we make any i18n() calls.
0047     KLocalizedString::setApplicationDomain(QByteArrayLiteral("systemsettings"));
0048 
0049     KAboutData aboutData;
0050 
0051     if (mode == BaseMode::InfoCenter) {
0052         // About data
0053         aboutData = KAboutData(QStringLiteral("kinfocenter"),
0054                                i18n("Info Center"),
0055                                QStringLiteral(PROJECT_VERSION),
0056                                i18n("Centralized and convenient overview of system information."),
0057                                KAboutLicense::GPL,
0058                                i18n("(c) 2009, Ben Cooksley"));
0059         aboutData.setDesktopFileName(QStringLiteral("org.kde.kinfocenter"));
0060 
0061         application.setWindowIcon(QIcon::fromTheme(QStringLiteral("hwinfo")));
0062 
0063     } else {
0064         aboutData = KAboutData(QStringLiteral("systemsettings"),
0065                                i18n("System Settings"),
0066                                QStringLiteral(PROJECT_VERSION),
0067                                i18n("Central configuration center by KDE."),
0068                                KAboutLicense::GPL,
0069                                i18n("(c) 2009, Ben Cooksley"));
0070 
0071         if (qEnvironmentVariableIsSet("KDE_FULL_SESSION")) {
0072             aboutData.setDesktopFileName(QStringLiteral("systemsettings"));
0073         } else {
0074             aboutData.setDesktopFileName(QStringLiteral("kdesystemsettings"));
0075         }
0076 
0077         application.setWindowIcon(QIcon::fromTheme(QStringLiteral("preferences-system")));
0078     }
0079 
0080     aboutData.addAuthor(i18n("Ben Cooksley"), i18n("Maintainer"), QStringLiteral("bcooksley@kde.org"));
0081     aboutData.addAuthor(i18n("Marco Martin"), i18n("Author"), QStringLiteral("mart@kde.org"));
0082     aboutData.addAuthor(i18n("Mathias Soeken"), i18n("Developer"), QStringLiteral("msoeken@informatik.uni-bremen.de"));
0083     aboutData.addAuthor(i18n("Will Stephenson"), i18n("Internal module representation, internal module model"), QStringLiteral("wstephenson@kde.org"));
0084 
0085     KAboutData::setApplicationData(aboutData);
0086 
0087     QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
0088 
0089     QCommandLineParser parser;
0090 
0091     parser.addOption(QCommandLineOption(QStringLiteral("list"), i18n("List all possible modules")));
0092     parser.addPositionalArgument(QStringLiteral("module"), i18n("Configuration module to open"));
0093     parser.addOption(QCommandLineOption(QStringLiteral("args"), i18n("Arguments for the module"), QStringLiteral("arguments")));
0094 
0095     aboutData.setupCommandLine(&parser);
0096 
0097     parser.process(application);
0098     aboutData.processCommandLine(&parser);
0099 
0100     if (parser.isSet(QStringLiteral("list"))) {
0101         std::cout << i18n("The following modules are available:").toLocal8Bit().data() << std::endl;
0102 
0103         auto source = mode == BaseMode::InfoCenter ? MetaDataSource::KInfoCenter : MetaDataSource::SystemSettings;
0104         const auto modules = findKCMsMetaData(source) << findExternalKCMModules(source);
0105 
0106         int maxLen = 0;
0107 
0108         for (const auto &metaData : modules) {
0109             const int len = metaData.pluginId().length();
0110             if (len > maxLen) {
0111                 maxLen = len;
0112             }
0113         }
0114 
0115         for (const auto &metaData : modules) {
0116             QString entry(QStringLiteral("%1 - %2"));
0117 
0118             entry = entry.arg(metaData.pluginId().leftJustified(maxLen, QLatin1Char(' ')),
0119                               !metaData.description().isEmpty() ? metaData.description() : i18n("No description available"));
0120 
0121             std::cout << entry.toLocal8Bit().data() << std::endl;
0122         }
0123         return 0;
0124     }
0125 
0126     if (parser.positionalArguments().count() > 1) {
0127         std::cerr << "Only one module argument may be passed" << std::endl;
0128         return -1;
0129     }
0130 
0131     const QStringList args = parser.value(QStringLiteral("args")).split(QRegularExpression(QStringLiteral(" +")), Qt::SkipEmptyParts);
0132     QString startupModule;
0133 
0134     if (parser.positionalArguments().count() == 1) {
0135         startupModule = parser.positionalArguments().constFirst();
0136     }
0137 
0138     if (!args.isEmpty() && startupModule.isEmpty()) {
0139         std::cerr << "Arguments may only be passed when specifying a module" << std::endl;
0140         return -1;
0141     }
0142 
0143     KDBusService service(KDBusService::Unique);
0144 
0145     KCrash::initialize();
0146 
0147     auto mainWindow = new SettingsBase(mode, startupModule, args);
0148 
0149     QObject::connect(&service, &KDBusService::activateRequested, mainWindow, [mainWindow](const QStringList &arguments) {
0150         // We can't use startupModule and args from above since they come from the existing instance, so we need to parse arguments.
0151         // We don't need to do the error checking again though.
0152         QCommandLineParser parser;
0153         parser.addPositionalArgument(QStringLiteral("module"), i18n("Configuration module to open"));
0154         parser.addOption(QCommandLineOption(QStringLiteral("args"), i18n("Arguments for the module"), QStringLiteral("arguments")));
0155 
0156         parser.parse(arguments);
0157 
0158         const QStringList args = parser.value(QStringLiteral("args")).split(QRegularExpression(QStringLiteral(" +")), Qt::SkipEmptyParts);
0159         QString startupModule;
0160 
0161         if (parser.positionalArguments().count() == 1) {
0162             startupModule = parser.positionalArguments().constFirst();
0163         }
0164 
0165         if (!startupModule.isEmpty()) {
0166             mainWindow->setStartupModule(startupModule);
0167             mainWindow->setStartupModuleArgs(args);
0168             mainWindow->reloadStartupModule();
0169         }
0170 
0171         KWindowSystem::updateStartupId(mainWindow->windowHandle());
0172         KWindowSystem::activateWindow(mainWindow->windowHandle());
0173     });
0174 
0175     return application.exec();
0176 }