You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
349 lines
8.8 KiB
349 lines
8.8 KiB
/* |
|
This file is part of the KDE libraries |
|
SPDX-FileCopyrightText: 2006 Aaron Seigo <aseigo@kde.org> |
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later |
|
*/ |
|
|
|
#include "kautostart.h" |
|
|
|
#include <KConfigGroup> |
|
#include <KDesktopFile> |
|
|
|
#include <QCoreApplication> |
|
#include <QDir> |
|
#include <QFile> |
|
|
|
class KAutostartPrivate |
|
{ |
|
public: |
|
KAutostartPrivate() |
|
: df(nullptr) |
|
, copyIfNeededChecked(false) |
|
{ |
|
} |
|
|
|
~KAutostartPrivate() |
|
{ |
|
delete df; |
|
} |
|
|
|
void copyIfNeeded(); |
|
|
|
QString name; |
|
KDesktopFile *df; |
|
bool copyIfNeededChecked; |
|
}; |
|
|
|
void KAutostartPrivate::copyIfNeeded() |
|
{ |
|
if (copyIfNeededChecked) { |
|
return; |
|
} |
|
|
|
const QString local = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/") + name; |
|
|
|
if (!QFile::exists(local)) { |
|
const QString global = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + name); |
|
if (!global.isEmpty()) { |
|
KDesktopFile *newDf = df->copyTo(local); |
|
delete df; |
|
delete newDf; // Force sync-to-disk |
|
df = new KDesktopFile(QStandardPaths::GenericConfigLocation, QStringLiteral("autostart/") + name); // Recreate from disk |
|
} |
|
} |
|
|
|
copyIfNeededChecked = true; |
|
} |
|
|
|
KAutostart::KAutostart(const QString &entryName, QObject *parent) |
|
: QObject(parent) |
|
, d(new KAutostartPrivate) |
|
{ |
|
const bool isAbsolute = QDir::isAbsolutePath(entryName); |
|
if (isAbsolute) { |
|
d->name = entryName.mid(entryName.lastIndexOf(QLatin1Char('/')) + 1); |
|
} else { |
|
if (entryName.isEmpty()) { |
|
d->name = QCoreApplication::applicationName(); |
|
} else { |
|
d->name = entryName; |
|
} |
|
|
|
if (!d->name.endsWith(QLatin1String(".desktop"))) { |
|
d->name.append(QLatin1String(".desktop")); |
|
} |
|
} |
|
|
|
const QString path = isAbsolute ? entryName : QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + d->name); |
|
if (path.isEmpty()) { |
|
// just a new KDesktopFile, since we have nothing to use |
|
d->df = new KDesktopFile(QStandardPaths::GenericConfigLocation, QLatin1String("autostart/") + d->name); |
|
d->copyIfNeededChecked = true; |
|
} else { |
|
d->df = new KDesktopFile(path); |
|
} |
|
} |
|
|
|
KAutostart::~KAutostart() = default; |
|
|
|
void KAutostart::setAutostarts(bool autostart) |
|
{ |
|
bool currentAutostartState = !d->df->desktopGroup().readEntry("Hidden", false); |
|
if (currentAutostartState == autostart) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writeEntry("Hidden", !autostart); |
|
} |
|
|
|
bool KAutostart::autostarts(const QString &environment, Conditions check) const |
|
{ |
|
// check if this is actually a .desktop file |
|
bool starts = d->df->desktopGroup().exists(); |
|
|
|
// check the hidden field |
|
starts = starts && !d->df->desktopGroup().readEntry("Hidden", false); |
|
|
|
if (!environment.isEmpty()) { |
|
starts = starts && checkAllowedEnvironment(environment); |
|
} |
|
|
|
if (check & CheckCommand) { |
|
starts = starts && d->df->tryExec(); |
|
} |
|
|
|
if (check & CheckCondition) { |
|
starts = starts && checkStartCondition(); |
|
} |
|
|
|
return starts; |
|
} |
|
|
|
bool KAutostart::checkStartCondition() const |
|
{ |
|
return KAutostart::isStartConditionMet(d->df->desktopGroup().readEntry("X-KDE-autostart-condition")); |
|
} |
|
|
|
bool KAutostart::isStartConditionMet(const QString &condition) |
|
{ |
|
if (condition.isEmpty()) { |
|
return true; |
|
} |
|
|
|
const QStringList list = condition.split(QLatin1Char(':')); |
|
if (list.count() < 4) { |
|
return true; |
|
} |
|
|
|
if (list[0].isEmpty() || list[2].isEmpty()) { |
|
return true; |
|
} |
|
|
|
KConfig config(list[0], KConfig::NoGlobals); |
|
KConfigGroup cg(&config, list[1]); |
|
|
|
const bool defaultValue = (list[3].toLower() == QLatin1String("true")); |
|
return cg.readEntry(list[2], defaultValue); |
|
} |
|
|
|
bool KAutostart::checkAllowedEnvironment(const QString &environment) const |
|
{ |
|
const QStringList allowed = allowedEnvironments(); |
|
if (!allowed.isEmpty()) { |
|
return allowed.contains(environment); |
|
} |
|
|
|
const QStringList excluded = excludedEnvironments(); |
|
if (!excluded.isEmpty()) { |
|
return !excluded.contains(environment); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
QString KAutostart::command() const |
|
{ |
|
return d->df->desktopGroup().readEntry("Exec", QString()); |
|
} |
|
|
|
void KAutostart::setCommand(const QString &command) |
|
{ |
|
if (d->df->desktopGroup().readEntry("Exec", QString()) == command) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writeEntry("Exec", command); |
|
} |
|
|
|
QString KAutostart::visibleName() const |
|
{ |
|
return d->df->readName(); |
|
} |
|
|
|
void KAutostart::setVisibleName(const QString &name) |
|
{ |
|
if (d->df->desktopGroup().readEntry("Name", QString()) == name) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writeEntry("Name", name); |
|
} |
|
|
|
bool KAutostart::isServiceRegistered(const QString &entryName) |
|
{ |
|
const QString localDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/"); |
|
return QFile::exists(localDir + entryName + QLatin1String(".desktop")); |
|
} |
|
|
|
QString KAutostart::commandToCheck() const |
|
{ |
|
return d->df->desktopGroup().readPathEntry("TryExec", QString()); |
|
} |
|
|
|
void KAutostart::setCommandToCheck(const QString &exec) |
|
{ |
|
if (d->df->desktopGroup().readEntry("TryExec", QString()) == exec) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writePathEntry("TryExec", exec); |
|
} |
|
|
|
// do not specialize the readEntry template - |
|
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100911 |
|
static KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, KAutostart::StartPhase aDefault) |
|
{ |
|
const QByteArray data = group.readEntry(key, QByteArray()); |
|
|
|
if (data.isNull()) { |
|
return aDefault; |
|
} |
|
|
|
if (data == "0" || data == "BaseDesktop") { |
|
return KAutostart::BaseDesktop; |
|
} else if (data == "1" || data == "DesktopServices") { |
|
return KAutostart::DesktopServices; |
|
} else if (data == "2" || data == "Applications") { |
|
return KAutostart::Applications; |
|
} |
|
|
|
return aDefault; |
|
} |
|
|
|
KAutostart::StartPhase KAutostart::startPhase() const |
|
{ |
|
return readEntry(d->df->desktopGroup(), "X-KDE-autostart-phase", Applications); |
|
} |
|
|
|
void KAutostart::setStartPhase(KAutostart::StartPhase phase) |
|
{ |
|
QString data = QStringLiteral("Applications"); |
|
|
|
switch (phase) { |
|
case BaseDesktop: |
|
data = QStringLiteral("BaseDesktop"); |
|
break; |
|
case DesktopServices: |
|
data = QStringLiteral("DesktopServices"); |
|
break; |
|
case Applications: // This is the default |
|
break; |
|
} |
|
|
|
if (d->df->desktopGroup().readEntry("X-KDE-autostart-phase", QString()) == data) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writeEntry("X-KDE-autostart-phase", data); |
|
} |
|
|
|
QStringList KAutostart::allowedEnvironments() const |
|
{ |
|
return d->df->desktopGroup().readXdgListEntry("OnlyShowIn"); |
|
} |
|
|
|
void KAutostart::setAllowedEnvironments(const QStringList &environments) |
|
{ |
|
if (d->df->desktopGroup().readEntry("OnlyShowIn", QStringList()) == environments) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writeXdgListEntry("OnlyShowIn", environments); |
|
} |
|
|
|
void KAutostart::addToAllowedEnvironments(const QString &environment) |
|
{ |
|
QStringList envs = allowedEnvironments(); |
|
|
|
if (envs.contains(environment)) { |
|
return; |
|
} |
|
|
|
envs.append(environment); |
|
setAllowedEnvironments(envs); |
|
} |
|
|
|
void KAutostart::removeFromAllowedEnvironments(const QString &environment) |
|
{ |
|
QStringList envs = allowedEnvironments(); |
|
int index = envs.indexOf(environment); |
|
|
|
if (index < 0) { |
|
return; |
|
} |
|
|
|
envs.removeAt(index); |
|
setAllowedEnvironments(envs); |
|
} |
|
|
|
QStringList KAutostart::excludedEnvironments() const |
|
{ |
|
return d->df->desktopGroup().readXdgListEntry("NotShowIn"); |
|
} |
|
|
|
void KAutostart::setExcludedEnvironments(const QStringList &environments) |
|
{ |
|
if (d->df->desktopGroup().readEntry("NotShowIn", QStringList()) == environments) { |
|
return; |
|
} |
|
|
|
d->copyIfNeeded(); |
|
d->df->desktopGroup().writeXdgListEntry("NotShowIn", environments); |
|
} |
|
|
|
void KAutostart::addToExcludedEnvironments(const QString &environment) |
|
{ |
|
QStringList envs = excludedEnvironments(); |
|
|
|
if (envs.contains(environment)) { |
|
return; |
|
} |
|
|
|
envs.append(environment); |
|
setExcludedEnvironments(envs); |
|
} |
|
|
|
void KAutostart::removeFromExcludedEnvironments(const QString &environment) |
|
{ |
|
QStringList envs = excludedEnvironments(); |
|
int index = envs.indexOf(environment); |
|
|
|
if (index < 0) { |
|
return; |
|
} |
|
|
|
envs.removeAt(index); |
|
setExcludedEnvironments(envs); |
|
} |
|
|
|
QString KAutostart::startAfter() const |
|
{ |
|
return d->df->desktopGroup().readEntry("X-KDE-autostart-after"); |
|
}
|
|
|