Skip to content
Snippets Groups Projects
systemhandler.cpp 11.1 KiB
Newer Older
akiraohgaki's avatar
akiraohgaki committed
#include "systemhandler.h"

akiraohgaki's avatar
akiraohgaki committed
#include <QUrl>
#include <QDesktopServices>

akiraohgaki's avatar
akiraohgaki committed
#ifdef QTLIB_UNIX
#include <QFileInfo>
#include <QProcess>
#include <QDBusMessage>
#include <QDBusConnection>
akiraohgaki's avatar
akiraohgaki committed
#include <QDBusVariant>
akiraohgaki's avatar
akiraohgaki committed
#include <QDebug>
#endif

akiraohgaki's avatar
akiraohgaki committed
#ifdef Q_OS_ANDROID
#include "qtlib_package.h"
#endif

akiraohgaki's avatar
akiraohgaki committed
SystemHandler::SystemHandler(QObject *parent)
    : QObject(parent)
{}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::isUnix() const
akiraohgaki's avatar
akiraohgaki committed
{
#ifdef QTLIB_UNIX
    return true;
#endif
    return false;
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::isMobileDevice() const
akiraohgaki's avatar
akiraohgaki committed
{
#if defined(APP_MOBILE)
    return true;
#elif defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_WINPHONE)
    return true;
#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM) // Ubuntu Phone, Plasma Phone
    return true;
#endif
    return false;
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::openUrl(const QString &url) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    auto path = url;
akiraohgaki's avatar
akiraohgaki committed
    path.replace("file://localhost", "", Qt::CaseInsensitive);
    path.replace("file://", "", Qt::CaseInsensitive);

#ifdef QTLIB_UNIX
    if ((path.endsWith(".appimage", Qt::CaseInsensitive) || path.endsWith(".exe", Qt::CaseInsensitive))
            && QFileInfo(path).isExecutable()) {
        return QProcess::startDetached(path);
    }
#endif

#ifdef Q_OS_ANDROID
    if (path.endsWith(".apk", Qt::CaseInsensitive)) {
        return qtlib::Package(path).installAsApk();
    }
#endif

    return QDesktopServices::openUrl(QUrl(url));
}

akiraohgaki's avatar
akiraohgaki committed
QString SystemHandler::desktopEnvironment() const
akiraohgaki's avatar
akiraohgaki committed
{
    QString desktop;
    QString currentDesktop;
akiraohgaki's avatar
akiraohgaki committed

    if (!qgetenv("XDG_CURRENT_DESKTOP").isEmpty()) {
        currentDesktop = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP").constData()).toLower();
    }
    else if (!qgetenv("XDG_SESSION_DESKTOP").isEmpty()) {
        currentDesktop = QString::fromLocal8Bit(qgetenv("XDG_SESSION_DESKTOP").constData()).toLower();
    }
    else if (!qgetenv("DESKTOP_SESSION").isEmpty()) {
        currentDesktop = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION").constData()).toLower();
    }

    if (currentDesktop.contains("kde") || currentDesktop.contains("plasma")) {
        desktop = "kde";
    }
    else if (currentDesktop.contains("gnome") || currentDesktop.contains("unity")) {
        desktop = "gnome";
    }
    else if (currentDesktop.contains("xfce")) {
        desktop = "xfce";
    }
    return desktop;
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::isApplicableType(const QString &installType) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    auto desktop = desktopEnvironment();
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    QStringList applicableTypes;

    if (desktop == "kde") {
akiraohgaki's avatar
akiraohgaki committed
        applicableTypes << "wallpapers"
akiraohgaki's avatar
akiraohgaki committed
                        << "icons"
                        << "cursors"
akiraohgaki's avatar
akiraohgaki committed
                        << "plasma5_desktopthemes"
                        << "aurorae_themes";
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (desktop == "gnome") {
        applicableTypes << "wallpapers"
                        << "icons"
                        << "cursors"
                        << "gtk3_themes"
                        << "gnome_shell_themes";
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    else if (desktop == "xfce") {
akiraohgaki's avatar
akiraohgaki committed
        applicableTypes << "wallpapers"
akiraohgaki's avatar
akiraohgaki committed
                        << "icons"
akiraohgaki's avatar
akiraohgaki committed
                        << "cursors"
                        << "gtk2_themes"
                        << "xfwm4_themes";
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed

    return applicableTypes.contains(installType);
akiraohgaki's avatar
akiraohgaki committed
}

#ifdef QTLIB_UNIX
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyFile(const QString &path, const QString &installType) const
akiraohgaki's avatar
akiraohgaki committed
{
    if (QFileInfo::exists(path) && isApplicableType(installType)) {
akiraohgaki's avatar
akiraohgaki committed
        auto desktop = desktopEnvironment();
akiraohgaki's avatar
akiraohgaki committed
        auto themeName = QFileInfo(path).fileName();
akiraohgaki's avatar
akiraohgaki committed

        if (desktop == "kde") {
            if (installType == "wallpapers") {
                return applyKdeWallpaper(path);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "icons") {
akiraohgaki's avatar
akiraohgaki committed
                return applyKdeIcon(themeName);
akiraohgaki's avatar
akiraohgaki committed
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "cursors") {
akiraohgaki's avatar
akiraohgaki committed
                return applyKdeCursor(themeName);
akiraohgaki's avatar
akiraohgaki committed
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "plasma5_desktopthemes") {
akiraohgaki's avatar
akiraohgaki committed
                return applyKdePlasmaDesktoptheme(themeName);
            else if (installType == "aurorae_themes") {
akiraohgaki's avatar
akiraohgaki committed
                return applyKdeAuroraeTheme(themeName);
akiraohgaki's avatar
akiraohgaki committed
        }
akiraohgaki's avatar
akiraohgaki committed
        else if (desktop == "gnome") {
            if (installType == "wallpapers") {
                return applyGnomeWallpaper(path);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "icons") {
akiraohgaki's avatar
akiraohgaki committed
                return applyGnomeIcon(themeName);
akiraohgaki's avatar
akiraohgaki committed
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "cursors") {
akiraohgaki's avatar
akiraohgaki committed
                return applyGnomeCursor(themeName);
akiraohgaki's avatar
akiraohgaki committed
            }
            else if (installType == "gtk3_themes") {
akiraohgaki's avatar
akiraohgaki committed
                return applyGnomeGtk3Theme(themeName);
            else if (installType == "gnome_shell_themes") {
akiraohgaki's avatar
akiraohgaki committed
                return applyGnomeGnomeShellTheme(themeName);
akiraohgaki's avatar
akiraohgaki committed
        }
akiraohgaki's avatar
akiraohgaki committed
        else if (desktop == "xfce") {
            if (installType == "wallpapers") {
                return applyXfceWallpaper(path);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "icons") {
                return applyXfceIcon(themeName);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "cursors") {
                return applyXfceCursor(themeName);
            }
            else if (installType == "gtk2_themes") {
                return applyXfceGtk2Theme(themeName);
            else if (installType == "xfwm4_themes") {
                return applyXfceXfwm4Theme(themeName);
            }
akiraohgaki's avatar
akiraohgaki committed
        }
    }
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    return false;
}
#endif

#ifdef QTLIB_UNIX
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::setConfigWithPlasmaShell(const QString &script) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    auto message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "evaluateScript");
    message.setArguments(QVariantList() << QVariant(script));
    auto reply = QDBusConnection::sessionBus().call(message);

    if (reply.type() == QDBusMessage::ErrorMessage) {
        qWarning() << reply.errorMessage();
        return false;
    }
    return true;
}
akiraohgaki's avatar
akiraohgaki committed

bool SystemHandler::applyKdeWallpaper(const QString &path) const
{
akiraohgaki's avatar
akiraohgaki committed
    QString script;
    QTextStream out(&script);
    out << "for (var key in desktops()) {"
        << "var d = desktops()[key];"
        << "d.wallpaperPlugin = 'org.kde.image';"
        << "d.currentConfigGroup = ['Wallpaper', 'org.kde.image', 'General'];"
        << "d.writeConfig('Image', 'file://" + path + "');"
        << "}";
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithPlasmaShell(script);
akiraohgaki's avatar
akiraohgaki committed
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdeIcon(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
{
    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('kdeglobals');"
        << "c.group = 'Icons';"
        << "c.writeEntry('Theme', '" + themeName + "');";

akiraohgaki's avatar
akiraohgaki committed
    if (setConfigWithPlasmaShell(script)) {
akiraohgaki's avatar
akiraohgaki committed
        QProcess::startDetached("kquitapp5 plasmashell");
        QProcess::startDetached("kstart5 plasmashell");
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdeCursor(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
{
    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('kcminputrc');"
        << "c.group = 'Mouse';"
        << "c.writeEntry('cursorTheme', '" + themeName + "');";

akiraohgaki's avatar
akiraohgaki committed
    /*if (setConfigWithPlasmaShell(script)) {
        auto envMessage = QDBusMessage::createMethodCall("org.kde.klauncher5", "/KLauncher", "org.kde.KLauncher", "setLaunchEnv");
        envMessage.setArguments(QVariantList() << QVariant(QString("XCURSOR_THEME")) << QVariant(themeName));
        QDBusConnection::sessionBus().call(envMessage);

        auto notifyMessage = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange");
        notifyMessage.setArguments(QVariantList() << QVariant(qint32(5)) << QVariant(qint32(0)));
        QDBusConnection::sessionBus().send(notifyMessage);
        return true;
    }
    return false;*/
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithPlasmaShell(script);
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdePlasmaDesktoptheme(const QString &themeName) const
{
    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('plasmarc');"
        << "c.group = 'Theme';"
        << "c.writeEntry('name', '" + themeName + "');";

akiraohgaki's avatar
akiraohgaki committed
    if (setConfigWithPlasmaShell(script)) {
akiraohgaki's avatar
akiraohgaki committed
        QProcess::startDetached("kquitapp5 plasmashell");
        QProcess::startDetached("kstart5 plasmashell");
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdeAuroraeTheme(const QString &themeName) const
{
    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('kwinrc');"
        << "c.group = 'org.kde.kdecoration2';"
        << "c.writeEntry('library', 'org.kde.kwin.aurorae');"
        << "c.writeEntry('theme', '__aurorae__svg__" + themeName + "');";

akiraohgaki's avatar
akiraohgaki committed
    if (setConfigWithPlasmaShell(script)) {
akiraohgaki's avatar
akiraohgaki committed
        auto message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
        QDBusConnection::sessionBus().send(message);
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::setConfigWithGsettings(const QString &schema, const QString &key, const QString &value) const
{
    return QProcess::startDetached("gsettings", QStringList() << "set" << schema << key << value);
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeWallpaper(const QString &path) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithGsettings("org.gnome.desktop.background", "picture-uri", "file://" + path);
akiraohgaki's avatar
akiraohgaki committed
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeIcon(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithGsettings("org.gnome.desktop.interface", "icon-theme", themeName);
akiraohgaki's avatar
akiraohgaki committed
}
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeCursor(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithGsettings("org.gnome.desktop.interface", "cursor-theme", themeName);
akiraohgaki's avatar
akiraohgaki committed
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeGtk3Theme(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithGsettings("org.gnome.desktop.interface", "gtk-theme", themeName);
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeGnomeShellTheme(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithGsettings("org.gnome.shell.extensions.user-theme", "name", themeName);
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::setConfigWithXfconf(const QString &channel, const QString &property, const QString &value) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    auto message = QDBusMessage::createMethodCall("org.xfce.Xfconf", "/org/xfce/Xfconf", "org.xfce.Xfconf", "SetProperty");
akiraohgaki's avatar
akiraohgaki committed
    message.setArguments(QVariantList() << QVariant(channel) << QVariant(property) << QVariant::fromValue(QDBusVariant(value)));
akiraohgaki's avatar
akiraohgaki committed
    auto reply = QDBusConnection::sessionBus().call(message);

    if (reply.type() == QDBusMessage::ErrorMessage) {
        qWarning() << reply.errorMessage();
        return false;
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
    return true;
akiraohgaki's avatar
akiraohgaki committed
}

bool SystemHandler::applyXfceWallpaper(const QString &path) const
{
akiraohgaki's avatar
akiraohgaki committed
    return setConfigWithXfconf("xfce4-desktop", "/backdrop/screen0/monitor0/workspace0/last-image", path);
akiraohgaki's avatar
akiraohgaki committed

bool SystemHandler::applyXfceIcon(const QString &themeName) const
{
    return setConfigWithXfconf("xsettings", "/Net/IconThemeName", themeName);
}
akiraohgaki's avatar
akiraohgaki committed

bool SystemHandler::applyXfceCursor(const QString &themeName) const
{
    return setConfigWithXfconf("xsettings", "/Gtk/CursorThemeName", themeName);
}
bool SystemHandler::applyXfceGtk2Theme(const QString &themeName) const
akiraohgaki's avatar
akiraohgaki committed
{
    return setConfigWithXfconf("xsettings", "/Net/ThemeName", themeName);
}

bool SystemHandler::applyXfceXfwm4Theme(const QString &themeName) const
{
    return setConfigWithXfconf("xfwm4", "/general/theme", themeName);
}
akiraohgaki's avatar
akiraohgaki committed
#endif