File indexing completed on 2024-04-14 15:48:48

0001 /***************************************************************************
0002  *   Copyright (C) 2008-2011 by Daniel Nicoletti                           *
0003  *   dantti12@gmail.com                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; see the file COPYING. If not, write to       *
0017  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0018  *   Boston, MA 02110-1301, USA.                                           *
0019  ***************************************************************************/
0020 
0021 #include "Apper.h"
0022 
0023 #include "BackendDetails.h"
0024 #include "MainUi.h"
0025 
0026 //#include <KGlobal>
0027 //#include <KStartupInfo>
0028 //#include <KStandardDirs>
0029 #include <KConfig>
0030 #include <KConfigGroup>
0031 //#include <KCModuleInfo>
0032 //#include <KWindowSystem>
0033 //#include <KDebug>
0034 #include <QStringList>
0035 #include <QDBusConnection>
0036 #include <QDBusMessage>
0037 #include <QTimer>
0038 #include <QUrl>
0039 #include <KDBusService>
0040 #include <KAboutData>
0041 #include <QCommandLineParser>
0042 #include <KLocalizedString>
0043 
0044 Apper::Apper(int& argc, char** argv)
0045  : QApplication(argc, argv),
0046    m_pkUi(nullptr),
0047    m_running(0)
0048 {
0049     setQuitOnLastWindowClosed(false);
0050 
0051     auto service = new KDBusService(KDBusService::Unique);
0052     connect(this, &Apper::aboutToQuit, service, &KDBusService::deleteLater);
0053     connect(service, &KDBusService::activateRequested, this, &Apper::activate);
0054 }
0055 
0056 Apper::~Apper()
0057 {
0058 }
0059 
0060 void Apper::appClose()
0061 {
0062     //check whether we can close
0063     if (!m_running && !m_pkUi) {
0064         quit();
0065     }
0066 }
0067 
0068 void Apper::kcmFinished()
0069 {
0070     // kcm is finished we set to 0 to be able to quit
0071     m_pkUi->deleteLater();
0072     m_pkUi = nullptr;
0073     appClose();
0074 }
0075 
0076 void Apper::decreaseAndKillRunning()
0077 {
0078     m_running--;
0079     sender()->deleteLater();
0080     appClose();
0081 }
0082 
0083 void Apper::activate(const QStringList& arguments, const QString& workingDirectory)
0084 {
0085     Q_UNUSED(workingDirectory);
0086 
0087     QCommandLineParser parser;
0088     parser.addVersionOption();
0089     parser.addHelpOption();
0090 
0091     QCommandLineOption updatesOpt(QStringList() << QLatin1String("updates"), i18n("Show updates"));
0092     parser.addOption(updatesOpt);
0093 
0094     QCommandLineOption settingsOpt(QStringList() << QLatin1String("settings"), i18n("Show settings"));
0095     parser.addOption(settingsOpt);
0096 
0097     QCommandLineOption backendOpt(QStringList() << QLatin1String("backend-details"), i18n("Show backend details"));
0098     parser.addOption(backendOpt);
0099 
0100     QCommandLineOption mimeTypeOpt(QStringList() << QLatin1String("install-mime-type"), i18n("Mime type installer"), QLatin1String("mime-type"));
0101     parser.addOption(mimeTypeOpt);
0102 
0103     QCommandLineOption nameOpt(QStringList() << QLatin1String("install-package-name"), i18n("Package name installer"), QLatin1String("name"));
0104     parser.addOption(nameOpt);
0105 
0106     QCommandLineOption fileOpt(QStringList() << QLatin1String("file"), i18n("Single file installer"), QLatin1String("file"));
0107     parser.addOption(fileOpt);
0108 
0109     QCommandLineOption resourceOpt(QStringList() << QLatin1String("resource"), i18n("Font resource installer"), QLatin1String("lang"));
0110     parser.addOption(resourceOpt);
0111 
0112     QCommandLineOption catalogOpt(QStringList() << QLatin1String("install-catalog"), i18n("Catalog installer"), QLatin1String("file"));
0113     parser.addOption(catalogOpt);
0114 
0115     QCommandLineOption removeOpt(QStringList() << QLatin1String("remove-package-by-file"), i18n("Single package remover"), QLatin1String("filename"));
0116     parser.addOption(removeOpt);
0117 
0118     parser.addPositionalArgument(QLatin1String("[package]"), i18n("Package file to install"));
0119 
0120     KAboutData::applicationData().setupCommandLine(&parser);
0121     parser.process(arguments);
0122     KAboutData::applicationData().processCommandLine(&parser);
0123 
0124     auto args = parser.positionalArguments();
0125 
0126     if (args.count()) {
0127         // grab the list of files
0128 //        QStringList urls;
0129 //        for (int i = 0; i < args.count(); i++) {
0130 //            urls << args[i];
0131 //        }
0132 
0133         // TODO remote files are copied to /tmp
0134         // what will happen if we call the other process to
0135         // install and this very one closes? will the files
0136         // in /tmp be deleted?
0137         invoke(QLatin1String("InstallPackageFiles"), args);
0138         return;
0139     }
0140 
0141     if (parser.isSet(updatesOpt)) {
0142         QTimer::singleShot(0, this, &Apper::showUpdates);
0143         return;
0144     }
0145     if (parser.isSet(settingsOpt)) {
0146         QTimer::singleShot(0, this, &Apper::showSettings);
0147         return;
0148     }
0149 
0150     if (parser.isSet(mimeTypeOpt)) {
0151         invoke(QLatin1String("InstallMimeTypes"), parser.values(mimeTypeOpt));
0152         return;
0153     }
0154 
0155     if (parser.isSet(nameOpt)) {
0156         invoke(QLatin1String("InstallPackageNames"), parser.values(nameOpt));
0157         return;
0158     }
0159 
0160     if (parser.isSet(QLatin1String("install-provide-file"))) {
0161         invoke(QLatin1String("InstallProvideFiles"), parser.values(QLatin1String("install-provide-file")));
0162         return;
0163     }
0164 
0165     if (parser.isSet(catalogOpt)) {
0166         invoke(QLatin1String("InstallCatalogs"), parser.values(catalogOpt));
0167         return;
0168     }
0169 
0170     if (parser.isSet(removeOpt)) {
0171         invoke(QLatin1String("RemovePackageByFiles"), parser.values(removeOpt));
0172         return;
0173     }
0174 
0175     if (parser.isSet(backendOpt)) {
0176         auto helper = new BackendDetails;
0177         connect(helper, &BackendDetails::rejected, this, &Apper::decreaseAndKillRunning);
0178         QTimer::singleShot(0, helper, &BackendDetails::show);
0179         m_running++;
0180         return;
0181     }
0182 
0183     // If we are here, we neet to show/activate the main UI
0184     QTimer::singleShot(0, this, &Apper::showUi);
0185 }
0186 
0187 void Apper::showUi()
0188 {
0189     if (!m_pkUi) {
0190         m_pkUi = new MainUi();
0191         connect(m_pkUi, &MainUi::finished, this, &Apper::kcmFinished);
0192     }
0193     // Show all
0194     m_pkUi->showAll();
0195     m_pkUi->show();
0196 //    KWindowSystem::forceActiveWindow(m_pkUi->winId());
0197 }
0198 
0199 void Apper::showUpdates()
0200 {
0201     if (!m_pkUi) {
0202         m_pkUi = new MainUi();
0203         connect(m_pkUi, &MainUi::finished, this, &Apper::kcmFinished);
0204     }
0205     m_pkUi->showUpdates();
0206     m_pkUi->show();
0207 //    KWindowSystem::forceActiveWindow(m_pkUi->winId());
0208 }
0209 
0210 void Apper::showSettings()
0211 {
0212     if (!m_pkUi) {
0213         m_pkUi = new MainUi();
0214         connect(m_pkUi, &MainUi::finished, this, &Apper::kcmFinished);
0215     }
0216     m_pkUi->showSettings();
0217     m_pkUi->show();
0218 //    KWindowSystem::forceActiveWindow(m_pkUi->winId());
0219 }
0220 
0221 void Apper::invoke(const QString &method_name, const QStringList &args)
0222 {
0223     QDBusMessage message;
0224     message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.PackageKit"),
0225                                              QLatin1String("/org/freedesktop/PackageKit"),
0226                                              QLatin1String("org.freedesktop.PackageKit.Modify"),
0227                                              method_name);
0228     message << uint(0);
0229     message << args;
0230     message << QString();
0231 
0232     // This call must block otherwise this application closes before
0233     // smarticon is activated
0234     QDBusConnection::sessionBus().call(message, QDBus::BlockWithGui);
0235 
0236     QTimer::singleShot(0, this, &Apper::appClose);
0237 }
0238 
0239 #include "moc_Apper.cpp"