File indexing completed on 2024-04-28 11:44:24

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 "kautostart.h"
0009 
0010 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 87)
0011 
0012 #include <KConfigGroup>
0013 #include <KDesktopFile>
0014 
0015 #include <QCoreApplication>
0016 #include <QDir>
0017 #include <QFile>
0018 
0019 class KAutostartPrivate
0020 {
0021 public:
0022     KAutostartPrivate()
0023         : df(nullptr)
0024         , copyIfNeededChecked(false)
0025     {
0026     }
0027 
0028     ~KAutostartPrivate()
0029     {
0030         delete df;
0031     }
0032 
0033     void copyIfNeeded();
0034 
0035     QString name;
0036     KDesktopFile *df;
0037     bool copyIfNeededChecked;
0038 };
0039 
0040 void KAutostartPrivate::copyIfNeeded()
0041 {
0042     if (copyIfNeededChecked) {
0043         return;
0044     }
0045 
0046     const QString local = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/") + name;
0047 
0048     if (!QFile::exists(local)) {
0049         const QString global = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + name);
0050         if (!global.isEmpty()) {
0051             KDesktopFile *newDf = df->copyTo(local);
0052             delete df;
0053             delete newDf; // Force sync-to-disk
0054             df = new KDesktopFile(QStandardPaths::GenericConfigLocation, QStringLiteral("autostart/") + name); // Recreate from disk
0055         }
0056     }
0057 
0058     copyIfNeededChecked = true;
0059 }
0060 
0061 KAutostart::KAutostart(const QString &entryName, QObject *parent)
0062     : QObject(parent)
0063     , d(new KAutostartPrivate)
0064 {
0065     const bool isAbsolute = QDir::isAbsolutePath(entryName);
0066     if (isAbsolute) {
0067         d->name = entryName.mid(entryName.lastIndexOf(QLatin1Char('/')) + 1);
0068     } else {
0069         if (entryName.isEmpty()) {
0070             d->name = QCoreApplication::applicationName();
0071         } else {
0072             d->name = entryName;
0073         }
0074 
0075         if (!d->name.endsWith(QLatin1String(".desktop"))) {
0076             d->name.append(QLatin1String(".desktop"));
0077         }
0078     }
0079 
0080     const QString path = isAbsolute ? entryName : QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + d->name);
0081     if (path.isEmpty()) {
0082         // just a new KDesktopFile, since we have nothing to use
0083         d->df = new KDesktopFile(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + d->name);
0084         d->copyIfNeededChecked = true;
0085     } else {
0086         d->df = new KDesktopFile(path);
0087     }
0088 }
0089 
0090 KAutostart::~KAutostart() = default;
0091 
0092 void KAutostart::setAutostarts(bool autostart)
0093 {
0094     bool currentAutostartState = !d->df->desktopGroup().readEntry("Hidden", false);
0095     if (currentAutostartState == autostart) {
0096         return;
0097     }
0098 
0099     d->copyIfNeeded();
0100     d->df->desktopGroup().writeEntry("Hidden", !autostart);
0101 }
0102 
0103 bool KAutostart::autostarts(const QString &environment, Conditions check) const
0104 {
0105     // check if this is actually a .desktop file
0106     bool starts = d->df->desktopGroup().exists();
0107 
0108     // check the hidden field
0109     starts = starts && !d->df->desktopGroup().readEntry("Hidden", false);
0110 
0111     if (!environment.isEmpty()) {
0112         starts = starts && checkAllowedEnvironment(environment);
0113     }
0114 
0115     if (check & CheckCommand) {
0116         starts = starts && d->df->tryExec();
0117     }
0118 
0119     if (check & CheckCondition) {
0120         starts = starts && checkStartCondition();
0121     }
0122 
0123     return starts;
0124 }
0125 
0126 bool KAutostart::checkStartCondition() const
0127 {
0128     return KAutostart::isStartConditionMet(d->df->desktopGroup().readEntry("X-KDE-autostart-condition"));
0129 }
0130 
0131 bool KAutostart::isStartConditionMet(const QString &condition)
0132 {
0133     if (condition.isEmpty()) {
0134         return true;
0135     }
0136 
0137     const QStringList list = condition.split(QLatin1Char(':'));
0138     if (list.count() < 4) {
0139         return true;
0140     }
0141 
0142     if (list[0].isEmpty() || list[2].isEmpty()) {
0143         return true;
0144     }
0145 
0146     KConfig config(list[0], KConfig::NoGlobals);
0147     KConfigGroup cg(&config, list[1]);
0148 
0149     const bool defaultValue = (list[3].toLower() == QLatin1String("true"));
0150     return cg.readEntry(list[2], defaultValue);
0151 }
0152 
0153 bool KAutostart::checkAllowedEnvironment(const QString &environment) const
0154 {
0155     const QStringList allowed = allowedEnvironments();
0156     if (!allowed.isEmpty()) {
0157         return allowed.contains(environment);
0158     }
0159 
0160     const QStringList excluded = excludedEnvironments();
0161     if (!excluded.isEmpty()) {
0162         return !excluded.contains(environment);
0163     }
0164 
0165     return true;
0166 }
0167 
0168 QString KAutostart::command() const
0169 {
0170     return d->df->desktopGroup().readEntry("Exec", QString());
0171 }
0172 
0173 void KAutostart::setCommand(const QString &command)
0174 {
0175     if (d->df->desktopGroup().readEntry("Exec", QString()) == command) {
0176         return;
0177     }
0178 
0179     d->copyIfNeeded();
0180     d->df->desktopGroup().writeEntry("Exec", command);
0181 }
0182 
0183 QString KAutostart::visibleName() const
0184 {
0185     return d->df->readName();
0186 }
0187 
0188 void KAutostart::setVisibleName(const QString &name)
0189 {
0190     if (d->df->desktopGroup().readEntry("Name", QString()) == name) {
0191         return;
0192     }
0193 
0194     d->copyIfNeeded();
0195     d->df->desktopGroup().writeEntry("Name", name);
0196 }
0197 
0198 bool KAutostart::isServiceRegistered(const QString &entryName)
0199 {
0200     const QString localDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/");
0201     return QFile::exists(localDir + entryName + QLatin1String(".desktop"));
0202 }
0203 
0204 QString KAutostart::commandToCheck() const
0205 {
0206     return d->df->desktopGroup().readPathEntry("TryExec", QString());
0207 }
0208 
0209 void KAutostart::setCommandToCheck(const QString &exec)
0210 {
0211     if (d->df->desktopGroup().readEntry("TryExec", QString()) == exec) {
0212         return;
0213     }
0214 
0215     d->copyIfNeeded();
0216     d->df->desktopGroup().writePathEntry("TryExec", exec);
0217 }
0218 
0219 // do not specialize the readEntry template -
0220 // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100911
0221 static KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, KAutostart::StartPhase aDefault)
0222 {
0223     const QByteArray data = group.readEntry(key, QByteArray());
0224 
0225     if (data.isNull()) {
0226         return aDefault;
0227     }
0228 
0229     if (data == "0" || data == "BaseDesktop") {
0230         return KAutostart::BaseDesktop;
0231     } else if (data == "1" || data == "DesktopServices") {
0232         return KAutostart::DesktopServices;
0233     } else if (data == "2" || data == "Applications") {
0234         return KAutostart::Applications;
0235     }
0236 
0237     return aDefault;
0238 }
0239 
0240 KAutostart::StartPhase KAutostart::startPhase() const
0241 {
0242     return readEntry(d->df->desktopGroup(), "X-KDE-autostart-phase", Applications);
0243 }
0244 
0245 void KAutostart::setStartPhase(KAutostart::StartPhase phase)
0246 {
0247     QString data = QStringLiteral("Applications");
0248 
0249     switch (phase) {
0250     case BaseDesktop:
0251         data = QStringLiteral("BaseDesktop");
0252         break;
0253     case DesktopServices:
0254         data = QStringLiteral("DesktopServices");
0255         break;
0256     case Applications: // This is the default
0257         break;
0258     }
0259 
0260     if (d->df->desktopGroup().readEntry("X-KDE-autostart-phase", QString()) == data) {
0261         return;
0262     }
0263 
0264     d->copyIfNeeded();
0265     d->df->desktopGroup().writeEntry("X-KDE-autostart-phase", data);
0266 }
0267 
0268 QStringList KAutostart::allowedEnvironments() const
0269 {
0270     return d->df->desktopGroup().readXdgListEntry("OnlyShowIn");
0271 }
0272 
0273 void KAutostart::setAllowedEnvironments(const QStringList &environments)
0274 {
0275     if (d->df->desktopGroup().readEntry("OnlyShowIn", QStringList()) == environments) {
0276         return;
0277     }
0278 
0279     d->copyIfNeeded();
0280     d->df->desktopGroup().writeXdgListEntry("OnlyShowIn", environments);
0281 }
0282 
0283 void KAutostart::addToAllowedEnvironments(const QString &environment)
0284 {
0285     QStringList envs = allowedEnvironments();
0286 
0287     if (envs.contains(environment)) {
0288         return;
0289     }
0290 
0291     envs.append(environment);
0292     setAllowedEnvironments(envs);
0293 }
0294 
0295 void KAutostart::removeFromAllowedEnvironments(const QString &environment)
0296 {
0297     QStringList envs = allowedEnvironments();
0298     int index = envs.indexOf(environment);
0299 
0300     if (index < 0) {
0301         return;
0302     }
0303 
0304     envs.removeAt(index);
0305     setAllowedEnvironments(envs);
0306 }
0307 
0308 QStringList KAutostart::excludedEnvironments() const
0309 {
0310     return d->df->desktopGroup().readXdgListEntry("NotShowIn");
0311 }
0312 
0313 void KAutostart::setExcludedEnvironments(const QStringList &environments)
0314 {
0315     if (d->df->desktopGroup().readEntry("NotShowIn", QStringList()) == environments) {
0316         return;
0317     }
0318 
0319     d->copyIfNeeded();
0320     d->df->desktopGroup().writeXdgListEntry("NotShowIn", environments);
0321 }
0322 
0323 void KAutostart::addToExcludedEnvironments(const QString &environment)
0324 {
0325     QStringList envs = excludedEnvironments();
0326 
0327     if (envs.contains(environment)) {
0328         return;
0329     }
0330 
0331     envs.append(environment);
0332     setExcludedEnvironments(envs);
0333 }
0334 
0335 void KAutostart::removeFromExcludedEnvironments(const QString &environment)
0336 {
0337     QStringList envs = excludedEnvironments();
0338     int index = envs.indexOf(environment);
0339 
0340     if (index < 0) {
0341         return;
0342     }
0343 
0344     envs.removeAt(index);
0345     setExcludedEnvironments(envs);
0346 }
0347 
0348 QString KAutostart::startAfter() const
0349 {
0350     return d->df->desktopGroup().readEntry("X-KDE-autostart-after");
0351 }
0352 
0353 #include "moc_kautostart.cpp"
0354 
0355 #endif