diff --git a/kcms/notifications/CMakeLists.txt b/kcms/notifications/CMakeLists.txt --- a/kcms/notifications/CMakeLists.txt +++ b/kcms/notifications/CMakeLists.txt @@ -12,6 +12,7 @@ KF5::KCMUtils KF5::CoreAddons KF5::Declarative + KF5::GlobalAccel KF5::GuiAddons KF5::I18n KF5::QuickAddons diff --git a/kcms/notifications/kcm.h b/kcms/notifications/kcm.h --- a/kcms/notifications/kcm.h +++ b/kcms/notifications/kcm.h @@ -22,6 +22,10 @@ #include +#include + +class QAction; + class SourcesModel; class FilterProxyModel; @@ -38,6 +42,11 @@ Q_PROPERTY(NotificationManager::Settings *settings READ settings CONSTANT) + Q_PROPERTY(QKeySequence toggleDoNotDisturbShortcut + READ toggleDoNotDisturbShortcut + WRITE setToggleDoNotDisturbShortcut + NOTIFY toggleDoNotDisturbShortcutChanged) + // So it can show the respective settings module right away Q_PROPERTY(QString initialDesktopEntry READ initialDesktopEntry WRITE setInitialDesktopEntry NOTIFY initialDesktopEntryChanged) Q_PROPERTY(QString initialNotifyRcName READ initialNotifyRcName WRITE setInitialNotifyRcName NOTIFY initialNotifyRcNameChanged) @@ -52,6 +61,10 @@ NotificationManager::Settings *settings() const; + QKeySequence toggleDoNotDisturbShortcut() const; + void setToggleDoNotDisturbShortcut(const QKeySequence &shortcut); + Q_SIGNAL void toggleDoNotDisturbShortcutChanged(); + QString initialDesktopEntry() const; void setInitialDesktopEntry(const QString &desktopEntry); @@ -81,6 +94,10 @@ NotificationManager::Settings *m_settings; + QAction *m_toggleDoNotDisturbAction; + QKeySequence m_toggleDoNotDisturbShortcut; + bool m_toggleDoNotDisturbShortcutDirty = false; + QString m_initialDesktopEntry; QString m_initialNotifyRcName; QString m_initialEventId; diff --git a/kcms/notifications/kcm.cpp b/kcms/notifications/kcm.cpp --- a/kcms/notifications/kcm.cpp +++ b/kcms/notifications/kcm.cpp @@ -20,6 +20,7 @@ #include "kcm.h" +#include #include #include #include @@ -33,6 +34,7 @@ #include #include +#include #include #include #include @@ -51,12 +53,14 @@ , m_sourcesModel(new SourcesModel(this)) , m_filteredModel(new FilterProxyModel(this)) , m_settings(new NotificationManager::Settings(this)) + , m_toggleDoNotDisturbAction(new QAction(this)) { const char uri[] = "org.kde.private.kcms.notifications"; qmlRegisterUncreatableType(uri, 1, 0, "SourcesModel", QStringLiteral("Cannot create instances of SourcesModel")); qmlRegisterType(); + qmlRegisterType(); qmlProtectModule(uri, 1); KAboutData *about = new KAboutData(QStringLiteral("kcm_notifications"), i18n("Notifications"), @@ -66,6 +70,13 @@ m_filteredModel->setSourceModel(m_sourcesModel); + // for KGlobalAccel... + // keep in sync with globalshortcuts.cpp in notification plasmoid! + m_toggleDoNotDisturbAction->setObjectName(QStringLiteral("toggle do not disturb")); + m_toggleDoNotDisturbAction->setProperty("componentName", QStringLiteral("plasmashell")); + m_toggleDoNotDisturbAction->setText(i18n("Toggle do not disturb")); + m_toggleDoNotDisturbAction->setIcon(QIcon::fromTheme(QStringLiteral("notifications-disabled"))); + QStringList stringArgs; stringArgs.reserve(args.count() + 1); // need to add a fake argv[0] for QCommandLineParser @@ -110,6 +121,23 @@ return m_settings; } +QKeySequence KCMNotifications::toggleDoNotDisturbShortcut() const +{ + return m_toggleDoNotDisturbShortcut; +} + +void KCMNotifications::setToggleDoNotDisturbShortcut(const QKeySequence &shortcut) +{ + if (m_toggleDoNotDisturbShortcut == shortcut) { + return; + } + + m_toggleDoNotDisturbShortcut = shortcut; + m_toggleDoNotDisturbShortcutDirty = true; + emit toggleDoNotDisturbShortcutChanged(); + setNeedsSave(true); +} + QString KCMNotifications::initialDesktopEntry() const { return m_initialDesktopEntry; @@ -194,16 +222,39 @@ void KCMNotifications::load() { m_settings->load(); + + const QKeySequence toggleDoNotDisturbShortcut = KGlobalAccel::self()->globalShortcut( + m_toggleDoNotDisturbAction->property("componentName").toString(), + m_toggleDoNotDisturbAction->objectName()).value(0); + + if (m_toggleDoNotDisturbShortcut != toggleDoNotDisturbShortcut) { + m_toggleDoNotDisturbShortcut = toggleDoNotDisturbShortcut; + emit toggleDoNotDisturbShortcutChanged(); + } + + m_toggleDoNotDisturbShortcutDirty = false; + setNeedsSave(false); } void KCMNotifications::save() { m_settings->save(); + + if (m_toggleDoNotDisturbShortcutDirty) { + // KeySequenceItem will already have checked whether the shortcut is available + KGlobalAccel::self()->setShortcut(m_toggleDoNotDisturbAction, + {m_toggleDoNotDisturbShortcut}, + KGlobalAccel::NoAutoloading); + } + + setNeedsSave(false); } void KCMNotifications::defaults() { m_settings->defaults(); + + setToggleDoNotDisturbShortcut(QKeySequence()); } #include "kcm.moc" diff --git a/kcms/notifications/package/contents/ui/main.qml b/kcms/notifications/package/contents/ui/main.qml --- a/kcms/notifications/package/contents/ui/main.qml +++ b/kcms/notifications/package/contents/ui/main.qml @@ -22,6 +22,7 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 as QtControls import org.kde.kirigami 2.4 as Kirigami +import org.kde.kquickcontrols 2.0 as KQuickControls import org.kde.kcm 1.2 as KCM import org.kde.notificationmanager 1.0 as NotificationManager @@ -94,6 +95,17 @@ enabled: root.notificationsAvailable } + RowLayout { + QtControls.Label { + text: i18nc("Turn do not disturb mode on/off with keyboard shortcut", "Toggle with:") + } + + KQuickControls.KeySequenceItem { + keySequence: kcm.toggleDoNotDisturbShortcut + onKeySequenceChanged: kcm.toggleDoNotDisturbShortcut = keySequence + } + } + QtControls.CheckBox { Kirigami.FormData.label: i18n("Critical notifications:") text: i18n("Always keep on top")