shift-shell/components/mobileshell/shellutil.cpp
Devin Lin 7d3bf39750 mobileshell: Refactor and extract state to mobileshellstate plugin
This avoids mixing plasmashell state with our MobileShell component library (which really shouldn't have state at all).
2022-11-12 11:15:36 -05:00

145 lines
4.1 KiB
C++

/*
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
* SPDX-FileCopyrightText: 2018 Bhushan Shah <bshah@kde.org>
* SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "shellutil.h"
#include "mobileshellsettings.h"
#include "windowutil.h"
#include <KConfigGroup>
#include <KFileUtils>
#include <KLocalizedString>
#include <KNotification>
#include <KNotificationJobUiDelegate>
#include <QDBusPendingReply>
#include <QDateTime>
#include <QDebug>
#include <QFeedbackHapticsEffect>
#include <QFile>
#include <QProcess>
#define FORMAT24H "HH:mm:ss"
ShellUtil::ShellUtil(QObject *parent)
: QObject{parent}
, m_localeConfig{KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::SimpleConfig)}
, m_launchingApp{nullptr}
{
m_localeConfigWatcher = KConfigWatcher::create(m_localeConfig);
// watch for changes to locale config, to update 12/24 hour time
connect(m_localeConfigWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) -> void {
if (group.name() == "Locale") {
// we have to reparse for new changes (from system settings)
m_localeConfig->reparseConfiguration();
Q_EMIT isSystem24HourFormatChanged();
}
});
}
ShellUtil *ShellUtil::instance()
{
static ShellUtil *inst = new ShellUtil(nullptr);
return inst;
}
void ShellUtil::stackItemBefore(QQuickItem *item1, QQuickItem *item2)
{
if (!item1 || !item2 || item1 == item2 || item1->parentItem() != item2->parentItem()) {
return;
}
item1->stackBefore(item2);
}
void ShellUtil::stackItemAfter(QQuickItem *item1, QQuickItem *item2)
{
if (!item1 || !item2 || item1 == item2 || item1->parentItem() != item2->parentItem()) {
return;
}
item1->stackAfter(item2);
}
void ShellUtil::executeCommand(const QString &command)
{
qWarning() << "Executing" << command;
const QStringList commandAndArguments = QProcess::splitCommand(command);
QProcess::startDetached(commandAndArguments.front(), commandAndArguments.mid(1));
}
bool ShellUtil::isSystem24HourFormat()
{
KConfigGroup localeSettings = KConfigGroup(m_localeConfig, "Locale");
QString timeFormat = localeSettings.readEntry("TimeFormat", QStringLiteral(FORMAT24H));
return timeFormat == QStringLiteral(FORMAT24H);
}
void ShellUtil::launchApp(const QString &storageId)
{
// try to activate a running window first
auto windows = WindowUtil::instance()->windowsFromStorageId(storageId);
if (!windows.empty()) {
windows[0]->requestActivate();
return;
}
// now try launching the window
KService::Ptr service = KService::serviceByStorageId(storageId);
if (!service) {
qWarning() << "Could not find" << storageId;
return;
}
auto job = new KIO::ApplicationLauncherJob(service, this);
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled));
job->start();
setLaunchingApp(job);
}
bool ShellUtil::isLaunchingApp()
{
return m_launchingApp != nullptr;
}
void ShellUtil::setLaunchingApp(KIO::ApplicationLauncherJob *launcherJob)
{
m_launchingAppPids = {};
m_launchingApp = launcherJob; // do not assume that the pointer is valid, KJobs destroy themselves
connect(launcherJob, &KIO::ApplicationLauncherJob::result, this, [this](auto *job) {
m_launchingAppPids = m_launchingApp->pids();
});
Q_EMIT isLaunchingAppChanged();
}
void ShellUtil::cancelLaunchingApp()
{
for (auto pid : m_launchingAppPids) {
QProcess::execute("kill", {QString::number(pid)});
}
clearLaunchingApp();
}
void ShellUtil::clearLaunchingApp()
{
m_launchingApp = nullptr;
Q_EMIT isLaunchingAppChanged();
}
void ShellUtil::buttonVibrate()
{
if (MobileShellSettings::self()->vibrationsEnabled()) {
QFeedbackHapticsEffect rumble;
rumble.setDuration(MobileShellSettings::self()->vibrationDuration());
rumble.setIntensity(MobileShellSettings::self()->vibrationIntensity());
rumble.start();
}
}