File indexing completed on 2023-09-24 04:11:07
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