Skip to content
Snippets Groups Projects
systemhandler.cpp 10.9 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>
#include <QDBusVariant>
#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
{
akiraohgaki's avatar
akiraohgaki committed
    QString desktop = "";
akiraohgaki's avatar
akiraohgaki committed
    QString currentDesktop = "";

    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"
                        << "plasma_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") {
        applicableTypes << "wallpapers";
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();

        if (desktop == "kde") {
            if (installType == "wallpapers") {
                return applyKdeWallpaper(path);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "icons") {
                return applyKdeIcon(path);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "cursors") {
                return applyKdeCursor(path);
            }
            else if (installType == "plasma_desktopthemes") {
                return applyKdePlasmaDesktoptheme(path);
            }
            else if (installType == "aurorae_themes") {
                return applyKdeAuroraeTheme(path);
            }
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(path);
            }
akiraohgaki's avatar
akiraohgaki committed
            else if (installType == "cursors") {
akiraohgaki's avatar
akiraohgaki committed
                return applyGnomeCursor(path);
            }
            else if (installType == "gtk3_themes") {
                return applyGnomeGtk3Theme(path);
            }
            else if (installType == "gnome_shell_themes") {
                return applyGnomeGnomeShellTheme(path);
            }
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
        }
    }
akiraohgaki's avatar
akiraohgaki committed

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

#ifdef QTLIB_UNIX
akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdeWallpaper(const QString &path) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    auto message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "evaluateScript");
akiraohgaki's avatar
akiraohgaki committed

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
    QVariantList arguments;
    arguments << QVariant(script);
    message.setArguments(arguments);
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    auto reply = QDBusConnection::sessionBus().call(message);
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    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
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdeIcon(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    auto message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "evaluateScript");

    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('kdeglobals');"
        << "c.group = 'Icons';"
        << "c.writeEntry('Theme', '" + themeName + "');";

    QVariantList arguments;
    arguments << QVariant(script);
    message.setArguments(arguments);

    auto reply = QDBusConnection::sessionBus().call(message);

    if (reply.type() == QDBusMessage::ErrorMessage) {
        qWarning() << reply.errorMessage();
        return false;
    }

akiraohgaki's avatar
akiraohgaki committed
    QProcess::startDetached("kquitapp5 plasmashell");
    QProcess::startDetached("kstart5 plasmashell");

akiraohgaki's avatar
akiraohgaki committed
    return true;
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyKdeCursor(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    auto message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "evaluateScript");

    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('kcminputrc');"
        << "c.group = 'Mouse';"
        << "c.writeEntry('cursorTheme', '" + themeName + "');";

    QVariantList arguments;
    arguments << QVariant(script);
    message.setArguments(arguments);

    auto reply = QDBusConnection::sessionBus().call(message);

    if (reply.type() == QDBusMessage::ErrorMessage) {
        qWarning() << reply.errorMessage();
        return false;
    }

    return true;
}

bool SystemHandler::applyKdePlasmaDesktoptheme(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    auto message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "evaluateScript");

    QString script;
    QTextStream out(&script);
    out << "var c = ConfigFile('plasmarc');"
        << "c.group = 'Theme';"
        << "c.writeEntry('name', '" + themeName + "');";

    QVariantList arguments;
    arguments << QVariant(script);
    message.setArguments(arguments);

    auto reply = QDBusConnection::sessionBus().call(message);

    if (reply.type() == QDBusMessage::ErrorMessage) {
        qWarning() << reply.errorMessage();
        return false;
    }

akiraohgaki's avatar
akiraohgaki committed
    QProcess::startDetached("kquitapp5 plasmashell");
    QProcess::startDetached("kstart5 plasmashell");

bool SystemHandler::applyKdeAuroraeTheme(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    auto message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "evaluateScript");

    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 + "');";

    QVariantList arguments;
    arguments << QVariant(script);
    message.setArguments(arguments);

    auto reply = QDBusConnection::sessionBus().call(message);

    if (reply.type() == QDBusMessage::ErrorMessage) {
        qWarning() << reply.errorMessage();
        return false;
    }

akiraohgaki's avatar
akiraohgaki committed
    auto refreshMessage = QDBusMessage::createMethodCall("org.kde.KWin", "/KWin", "org.kde.KWin", "reconfigure");
    QDBusConnection::sessionBus().call(refreshMessage);

    return true;
}

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

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeIcon(const QString &path) const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    auto themeName = QFileInfo(path).fileName();
    QStringList arguments{"set", "org.gnome.desktop.interface", "icon-theme", themeName};
    return QProcess::startDetached("gsettings", arguments);
}
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyGnomeCursor(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    QStringList arguments{"set", "org.gnome.desktop.interface", "cursor-theme", themeName};
    return QProcess::startDetached("gsettings", arguments);
akiraohgaki's avatar
akiraohgaki committed
}

bool SystemHandler::applyGnomeGtk3Theme(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    QStringList arguments{"set", "org.gnome.desktop.interface", "gtk-theme", themeName};
    return QProcess::startDetached("gsettings", arguments);
}

bool SystemHandler::applyGnomeGnomeShellTheme(const QString &path) const
{
    auto themeName = QFileInfo(path).fileName();
    QStringList arguments{"set", "org.gnome.shell.extensions.user-theme", "name", themeName};
    return QProcess::startDetached("gsettings", arguments);
}

akiraohgaki's avatar
akiraohgaki committed
bool SystemHandler::applyXfceWallpaper(const QString &path) 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

akiraohgaki's avatar
akiraohgaki committed
    QString channelValue = "xfce4-desktop";
    //QString propertyValue = "/backdrop/screen0/monitor0/image-path";
    QString propertyValue = "/backdrop/screen0/monitor0/workspace0/last-image";
    QDBusVariant valueValue(path);

    QVariantList arguments;
    arguments << QVariant(channelValue) << QVariant(propertyValue) << QVariant::fromValue(valueValue);
    message.setArguments(arguments);

    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
}
#endif