Skip to content
Snippets Groups Projects
systemhandler.cpp 9.17 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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") {
            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();
    
    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
            }
        }
    
    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 && 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
        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 && 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::createMethodCall("org.kde.KWin", "/KWin", "org.kde.KWin", "reconfigure");
            QDBusConnection::sessionBus().call(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
    #endif