widgets/notifications: Remove accidental dependency on being an applet

Followup to https://invent.kde.org/plasma/plasma-mobile/-/merge_requests/558 and removes the dependency on being an applet, as it causes the notifications to break on the lockscreen
This commit is contained in:
Devin Lin 2024-07-28 14:54:14 -04:00
parent 56458bad59
commit 8f79654989
4 changed files with 276 additions and 4 deletions

View file

@ -10,6 +10,7 @@ set(mobileshellplugin_SRCS
components/swipearea.cpp
notifications/notificationthumbnailer.cpp
notifications/notificationfilemenu.cpp
notifications/notificationfileinfo.cpp
)
target_include_directories(mobileshellplugin PRIVATE components)
target_include_directories(mobileshellplugin PRIVATE notifications)

View file

@ -0,0 +1,188 @@
/*
SPDX-FileCopyrightText: 2021 Kai Uwe Broulik <kde@broulik.de>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "notificationfileinfo.h"
#include <QAction>
#include <QMimeDatabase>
#include <KApplicationTrader>
#include <KAuthorized>
#include <KIO/ApplicationLauncherJob>
#include <KIO/JobUiDelegateFactory>
#include <KIO/MimeTypeFinderJob>
#include <KIO/OpenUrlJob>
#include <KLocalizedString>
#include <KNotificationJobUiDelegate>
NotificationFileInfo::NotificationFileInfo(QObject *parent)
: QObject(parent)
{
}
NotificationFileInfo::~NotificationFileInfo() = default;
QUrl NotificationFileInfo::url() const
{
return m_url;
}
void NotificationFileInfo::setUrl(const QUrl &url)
{
if (m_url != url) {
m_url = url;
reload();
Q_EMIT urlChanged(url);
}
}
bool NotificationFileInfo::busy() const
{
return m_busy;
}
void NotificationFileInfo::setBusy(bool busy)
{
if (m_busy != busy) {
m_busy = busy;
Q_EMIT busyChanged(busy);
}
}
int NotificationFileInfo::error() const
{
return m_error;
}
void NotificationFileInfo::setError(int error)
{
if (m_error != error) {
m_error = error;
Q_EMIT errorChanged(error);
}
}
QString NotificationFileInfo::mimeType() const
{
return m_mimeType;
}
QString NotificationFileInfo::iconName() const
{
return m_iconName;
}
QAction *NotificationFileInfo::openAction() const
{
return m_openAction;
}
QString NotificationFileInfo::openActionIconName() const
{
return m_openAction ? m_openAction->icon().name() : QString();
}
void NotificationFileInfo::reload()
{
if (!m_url.isValid()) {
return;
}
if (m_job) {
m_job->kill();
}
setError(0);
// Do a quick guess by file name while we wait for the job to find the mime type
QString guessedMimeType;
// NOTE using QUrl::path() for API that accepts local files is usually wrong
// but here we really only care about the file name and its extension.
const auto type = QMimeDatabase().mimeTypeForFile(m_url.path(), QMimeDatabase::MatchExtension);
if (!type.isDefault()) {
guessedMimeType = type.name();
}
mimeTypeFound(guessedMimeType);
m_job = new KIO::MimeTypeFinderJob(m_url);
m_job->setAuthenticationPromptEnabled(false);
const QUrl url = m_url;
connect(m_job, &KIO::MimeTypeFinderJob::result, this, [this, url] {
setError(m_job->error());
if (m_job->error()) {
qWarning() << "Failed to determine mime type for" << url << m_job->errorString();
} else {
mimeTypeFound(m_job->mimeType());
}
setBusy(false);
});
setBusy(true);
m_job->start();
}
void NotificationFileInfo::mimeTypeFound(const QString &mimeType)
{
if (m_mimeType == mimeType) {
return;
}
const QString oldOpenActionIconName = openActionIconName();
bool emitOpenActionChanged = false;
if (!m_openAction) {
m_openAction = new QAction(this);
connect(m_openAction, &QAction::triggered, this, [this] {
auto *job = new KIO::ApplicationLauncherJob(m_preferredApplication);
if (m_preferredApplication) {
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoErrorHandlingEnabled));
} else {
// needs KIO::JobUiDelegate for open with handler
job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoErrorHandlingEnabled, nullptr /*widget*/));
}
job->setUrls({m_url});
job->start();
});
emitOpenActionChanged = true;
}
m_mimeType = mimeType;
m_preferredApplication.reset();
if (!mimeType.isEmpty()) {
const auto type = QMimeDatabase().mimeTypeForName(mimeType);
m_iconName = type.iconName();
m_preferredApplication = KApplicationTrader::preferredService(mimeType);
} else {
m_iconName.clear();
}
if (m_preferredApplication) {
m_openAction->setText(i18n("Open with %1", m_preferredApplication->name()));
m_openAction->setIcon(QIcon::fromTheme(m_preferredApplication->icon()));
m_openAction->setEnabled(true);
} else {
m_openAction->setText(i18n("Open with…"));
m_openAction->setIcon(QIcon::fromTheme(QStringLiteral("system-run")));
m_openAction->setEnabled(KAuthorized::authorizeAction(KAuthorized::OPEN_WITH));
}
Q_EMIT mimeTypeChanged();
if (emitOpenActionChanged) {
Q_EMIT openActionChanged();
}
if (oldOpenActionIconName != openActionIconName()) {
Q_EMIT openActionIconNameChanged();
}
}
#include "moc_notificationfileinfo.cpp"

View file

@ -0,0 +1,84 @@
/*
SPDX-FileCopyrightText: 2021 Kai Uwe Broulik <kde@broulik.de>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once
#include <QObject>
#include <QPointer>
#include <QString>
#include <QUrl>
#include <KService>
#include <qqmlregistration.h>
class QAction;
namespace KIO
{
class MimeTypeFinderJob;
}
class NotificationFileInfo : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
Q_PROPERTY(int error READ error NOTIFY errorChanged)
Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged)
Q_PROPERTY(QString iconName READ iconName NOTIFY mimeTypeChanged)
Q_PROPERTY(QAction *openAction READ openAction NOTIFY openActionChanged)
// QML can't deal with QIcon...
Q_PROPERTY(QString openActionIconName READ openActionIconName NOTIFY openActionIconNameChanged)
public:
explicit NotificationFileInfo(QObject *parent = nullptr);
~NotificationFileInfo() override;
QUrl url() const;
void setUrl(const QUrl &url);
Q_SIGNAL void urlChanged(const QUrl &url);
bool busy() const;
Q_SIGNAL void busyChanged(bool busy);
int error() const;
Q_SIGNAL void errorChanged(bool error);
QString mimeType() const;
Q_SIGNAL void mimeTypeChanged();
QString iconName() const;
Q_SIGNAL void iconNameChanged(const QString &iconName);
QAction *openAction() const;
Q_SIGNAL void openActionChanged();
QString openActionIconName() const;
Q_SIGNAL void openActionIconNameChanged();
private:
void reload();
void mimeTypeFound(const QString &mimeType);
void setBusy(bool busy);
void setError(int error);
QUrl m_url;
QPointer<KIO::MimeTypeFinderJob> m_job;
bool m_busy = false;
int m_error = 0;
QString m_mimeType;
QString m_iconName;
KService::Ptr m_preferredApplication;
QAction *m_openAction = nullptr;
};

View file

@ -9,11 +9,10 @@ import QtQml 2.15
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.kirigami 2.20 as Kirigami
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.notificationmanager as NotificationManager
import org.kde.plasma.private.notifications 2.0 as Notifications
ColumnLayout {
id: jobItem
@ -59,7 +58,7 @@ ColumnLayout {
spacing: Kirigami.Units.smallSpacing
Notifications.FileInfo {
MobileShell.NotificationFileInfo {
id: fileInfo
url: jobItem.totalFiles === 1 && jobItem.url ? jobItem.url : ""
}
@ -196,7 +195,7 @@ ColumnLayout {
enabled: parent.text === ""
}
Notifications.FileMenu {
MobileShell.NotificationFileMenu {
id: otherFileActionsMenu
url: jobItem.url || ""
onActionTriggered: jobItem.fileActionInvoked(action)