File indexing completed on 2024-05-19 05:39:09

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2006 Aaron Seigo <aseigo@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "plasmaautostart.h"
0009 
0010 #include <KConfigGroup>
0011 #include <KDesktopFile>
0012 
0013 #include <QCoreApplication>
0014 #include <QDir>
0015 #include <QFile>
0016 
0017 void PlasmaAutostart::copyIfNeeded()
0018 {
0019     if (copyIfNeededChecked) {
0020         return;
0021     }
0022 
0023     const QString local = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/") + name;
0024 
0025     if (!QFile::exists(local)) {
0026         const QString global = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + name);
0027         if (!global.isEmpty()) {
0028             KDesktopFile *newDf = df->copyTo(local);
0029             delete df;
0030             delete newDf; // Force sync-to-disk
0031             df = new KDesktopFile(QStandardPaths::GenericConfigLocation, QStringLiteral("autostart/") + name); // Recreate from disk
0032         }
0033     }
0034 
0035     copyIfNeededChecked = true;
0036 }
0037 
0038 PlasmaAutostart::PlasmaAutostart(const QString &entryName, QObject *parent)
0039     : QObject(parent)
0040 {
0041     const bool isAbsolute = QDir::isAbsolutePath(entryName);
0042     if (isAbsolute) {
0043         name = entryName.mid(entryName.lastIndexOf(QLatin1Char('/')) + 1);
0044     } else {
0045         if (entryName.isEmpty()) {
0046             name = QCoreApplication::applicationName();
0047         } else {
0048             name = entryName;
0049         }
0050 
0051         if (!name.endsWith(QLatin1String(".desktop"))) {
0052             name.append(QLatin1String(".desktop"));
0053         }
0054     }
0055 
0056     const QString path = isAbsolute ? entryName : QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + name);
0057     if (path.isEmpty()) {
0058         // just a new KDesktopFile, since we have nothing to use
0059         df = new KDesktopFile(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + name);
0060         copyIfNeededChecked = true;
0061     } else {
0062         df = new KDesktopFile(path);
0063     }
0064 }
0065 
0066 PlasmaAutostart::~PlasmaAutostart() = default;
0067 
0068 void PlasmaAutostart::setAutostarts(bool autostart)
0069 {
0070     bool currentAutostartState = !df->desktopGroup().readEntry("Hidden", false);
0071     if (currentAutostartState == autostart) {
0072         return;
0073     }
0074 
0075     copyIfNeeded();
0076     df->desktopGroup().writeEntry("Hidden", !autostart);
0077 }
0078 
0079 bool PlasmaAutostart::autostarts(const QString &environment, Conditions check) const
0080 {
0081     // check if this is actually a .desktop file
0082     bool starts = df->desktopGroup().exists();
0083 
0084     // check the hidden field
0085     starts = starts && !df->desktopGroup().readEntry("Hidden", false);
0086 
0087     if (!environment.isEmpty()) {
0088         starts = starts && checkAllowedEnvironment(environment);
0089     }
0090 
0091     if (check & CheckCommand) {
0092         starts = starts && df->tryExec();
0093     }
0094 
0095     if (check & CheckCondition) {
0096         starts = starts && checkStartCondition();
0097     }
0098 
0099     return starts;
0100 }
0101 
0102 bool PlasmaAutostart::checkStartCondition() const
0103 {
0104     return PlasmaAutostart::isStartConditionMet(df->desktopGroup().readEntry("X-KDE-autostart-condition"));
0105 }
0106 
0107 bool PlasmaAutostart::isStartConditionMet(QStringView condition)
0108 {
0109     if (condition.isEmpty()) {
0110         return true;
0111     }
0112 
0113     const auto list = condition.split(QLatin1Char(':'));
0114     if (list.count() < 4) {
0115         return true;
0116     }
0117 
0118     if (list[0].isEmpty() || list[2].isEmpty()) {
0119         return true;
0120     }
0121 
0122     KConfig config(list[0].toString(), KConfig::NoGlobals);
0123     KConfigGroup cg(&config, list[1].toString());
0124 
0125     const bool defaultValue = (list[3].toString().compare(QLatin1String("true"), Qt::CaseInsensitive) == 0);
0126     return cg.readEntry(list[2].toString(), defaultValue);
0127 }
0128 
0129 bool PlasmaAutostart::checkAllowedEnvironment(const QString &environment) const
0130 {
0131     const QStringList allowed = allowedEnvironments();
0132     if (!allowed.isEmpty()) {
0133         return allowed.contains(environment);
0134     }
0135 
0136     const QStringList excluded = excludedEnvironments();
0137     if (!excluded.isEmpty()) {
0138         return !excluded.contains(environment);
0139     }
0140 
0141     return true;
0142 }
0143 
0144 QString PlasmaAutostart::command() const
0145 {
0146     return df->desktopGroup().readEntry("Exec", QString());
0147 }
0148 
0149 void PlasmaAutostart::setCommand(const QString &command)
0150 {
0151     if (df->desktopGroup().readEntry("Exec", QString()) == command) {
0152         return;
0153     }
0154 
0155     copyIfNeeded();
0156     df->desktopGroup().writeEntry("Exec", command);
0157 }
0158 
0159 bool PlasmaAutostart::isServiceRegistered(const QString &entryName)
0160 {
0161     const QString localDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/");
0162     return QFile::exists(localDir + entryName + QLatin1String(".desktop"));
0163 }
0164 
0165 // do not specialize the readEntry template -
0166 // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100911
0167 static PlasmaAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, PlasmaAutostart::StartPhase aDefault)
0168 {
0169     const QByteArray data = group.readEntry(key, QByteArray());
0170 
0171     if (data.isNull()) {
0172         return aDefault;
0173     }
0174 
0175     if (data == "0" || data == "BaseDesktop") {
0176         return PlasmaAutostart::BaseDesktop;
0177     } else if (data == "1" || data == "DesktopServices") {
0178         return PlasmaAutostart::DesktopServices;
0179     } else if (data == "2" || data == "Applications") {
0180         return PlasmaAutostart::Applications;
0181     }
0182 
0183     return aDefault;
0184 }
0185 
0186 PlasmaAutostart::StartPhase PlasmaAutostart::startPhase() const
0187 {
0188     return readEntry(df->desktopGroup(), "X-KDE-autostart-phase", Applications);
0189 }
0190 
0191 QStringList PlasmaAutostart::allowedEnvironments() const
0192 {
0193     return df->desktopGroup().readXdgListEntry("OnlyShowIn");
0194 }
0195 
0196 QStringList PlasmaAutostart::excludedEnvironments() const
0197 {
0198     return df->desktopGroup().readXdgListEntry("NotShowIn");
0199 }
0200 
0201 QString PlasmaAutostart::startAfter() const
0202 {
0203     return df->desktopGroup().readEntry("X-KDE-autostart-after");
0204 }