Commit 5c834677 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇

Make some of the settings actually work

- Uses the NotificationManager::Settings stuff for reading/writing config
- Make some of the settings on main page work
- Make general notification settings work for apps (not the KNotification ones)
- Cleanup screen position selector
- Get rid of Activities stuff, will be added later and/or separately
  by having kactivitymanagerd set an inhibition rather than having the
  notification server watch all the triggers
parent c6598a31
......@@ -71,6 +71,7 @@ set_package_properties(KF5QQC2DeskopStyle PROPERTIES
find_package(LibKWorkspace 5.14.90 CONFIG REQUIRED)
find_package(LibTaskManager 5.14.90 CONFIG REQUIRED)
find_package(LibNotificationManager 5.14.90 CONFIG REQUIRED)
find_package(LibColorCorrect 5.14.90 CONFIG REQUIRED)
find_package(KWinDBusInterface CONFIG REQUIRED)
find_package(ScreenSaverDBusInterface CONFIG REQUIRED)
......
......@@ -9,7 +9,6 @@ set(kcm_notifications_SRCS
add_library(kcm_notifications MODULE ${kcm_notifications_SRCS})
target_link_libraries(kcm_notifications
#Qt5::DBus
KF5::KCMUtils
KF5::Activities
KF5::CoreAddons
......@@ -18,6 +17,7 @@ target_link_libraries(kcm_notifications
KF5::I18n
KF5::QuickAddons
KF5::Service
PW::LibNotificationManager
)
kcoreaddons_desktop_to_json(kcm_notifications "kcm_notifications.desktop")
......
......@@ -40,6 +40,24 @@ void FilterProxyModel::setQuery(const QString &query)
m_query = query;
invalidateFilter();
emit queryChanged();
emit currentIndexChanged();
}
}
int FilterProxyModel::currentIndex() const
{
if (m_currentIndex.isValid()) {
return m_currentIndex.row();
}
return -1;
}
void FilterProxyModel::setCurrentIndex(const QPersistentModelIndex &idx)
{
const int oldIndex = currentIndex();
m_currentIndex = idx;
if (oldIndex != currentIndex()) {
emit currentIndexChanged();
}
}
......@@ -48,7 +66,6 @@ QPersistentModelIndex FilterProxyModel::makePersistentModelIndex(int row) const
return QPersistentModelIndex(index(row, 0));
}
bool FilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if (m_query.isEmpty()) {
......
......@@ -28,6 +28,8 @@ class FilterProxyModel : public QSortFilterProxyModel
Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
Q_PROPERTY(int currentIndex READ currentIndex NOTIFY currentIndexChanged)
public:
FilterProxyModel(QObject *parent = nullptr);
~FilterProxyModel() override;
......@@ -35,14 +37,20 @@ public:
QString query() const;
void setQuery(const QString &query);
int currentIndex() const;
Q_INVOKABLE void setCurrentIndex(const QPersistentModelIndex &idx);
Q_INVOKABLE QPersistentModelIndex makePersistentModelIndex(int row) const;
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
Q_SIGNALS:
void queryChanged();
void currentIndexChanged();
private:
QString m_query;
QPersistentModelIndex m_currentIndex;
};
......@@ -35,12 +35,15 @@
#include "sourcesmodel.h"
#include "filterproxymodel.h"
#include <notificationmanager/settings.h>
K_PLUGIN_FACTORY_WITH_JSON(KCMNotificationsFactory, "kcm_notifications.json", registerPlugin<KCMNotifications>();)
KCMNotifications::KCMNotifications(QObject *parent, const QVariantList &args)
: KQuickAddons::ConfigModule(parent, args)
, m_sourcesModel(new SourcesModel(this))
, m_filteredModel(new FilterProxyModel(this))
, m_settings(new NotificationManager::Settings(this))
, m_activitiesModel(new KActivities::ActivitiesModel(this))
{
const char uri[] = "org.kde.private.kcms.notifications";
......@@ -74,6 +77,11 @@ FilterProxyModel *KCMNotifications::filteredModel() const
return m_filteredModel;
}
NotificationManager::Settings *KCMNotifications::settings() const
{
return m_settings;
}
KActivities::ActivitiesModel *KCMNotifications::activitiesModel() const
{
return m_activitiesModel;
......@@ -81,6 +89,7 @@ KActivities::ActivitiesModel *KCMNotifications::activitiesModel() const
void KCMNotifications::load()
{
m_settings->load();
m_sourcesModel->load();
//m_config->markAsClean();
......@@ -89,13 +98,14 @@ void KCMNotifications::load()
void KCMNotifications::save()
{
setNeedsSave(false);
m_settings->save();
//setNeedsSave(false);
}
void KCMNotifications::defaults()
{
setNeedsSave(true);
m_settings->defaults();
//setNeedsSave(true);
}
#include "kcm.moc"
......@@ -28,6 +28,10 @@
class SourcesModel;
class FilterProxyModel;
namespace NotificationManager {
class Settings;
}
namespace KActivities {
class ActivitiesModel;
}
......@@ -39,6 +43,8 @@ class KCMNotifications : public KQuickAddons::ConfigModule
Q_PROPERTY(SourcesModel *sourcesModel READ sourcesModel CONSTANT)
Q_PROPERTY(FilterProxyModel *filteredModel READ filteredModel CONSTANT)
Q_PROPERTY(NotificationManager::Settings *settings READ settings CONSTANT)
Q_PROPERTY(KActivities::ActivitiesModel *activitiesModel READ activitiesModel CONSTANT)
public:
......@@ -54,6 +60,9 @@ public:
SourcesModel *sourcesModel() const;
FilterProxyModel *filteredModel() const;
NotificationManager::Settings *settings() const;
KActivities::ActivitiesModel *activitiesModel() const;
public Q_SLOTS:
......@@ -65,6 +74,8 @@ private:
SourcesModel *m_sourcesModel;
FilterProxyModel *m_filteredModel;
NotificationManager::Settings *m_settings;
KActivities::ActivitiesModel *m_activitiesModel;
};
......@@ -26,12 +26,37 @@ import QtQuick.Controls 2.3 as QtControls
import org.kde.kirigami 2.7 as Kirigami
import org.kde.kcm 1.2 as KCM
import org.kde.notificationmanager 1.0 as NotificationManager
ColumnLayout {
id: eventsColumn
property var rootIndex
property var appData
property int behavior: {
if (appData.desktopEntry) {
return kcm.settings.applicationBehavior(appData.desktopEntry);
} else if (appData.notifyRcName) {
return kcm.settings.serviceBehavior(appData.notifyRcName);
}
return -1;
}
function setBehavior(flag, enable) {
var newBehavior = behavior;
if (enable) {
newBehavior |= flag;
} else {
newBehavior &= ~flag;
}
property bool customActivitySettings: false
if (appData.desktopEntry) {
return kcm.settings.setApplicationBehavior(appData.desktopEntry, newBehavior);
} else if (appData.notifyRcName) {
return kcm.settings.setServiceBehavior(appData.notifyRcName, newBehavior);
}
}
readonly property var actions: [
{key: "Popup", label: i18n("Show popup"), icon: "dialog-information"},
......@@ -50,7 +75,8 @@ ColumnLayout {
QtControls.CheckBox {
id: showPopupsCheck
text: i18n("Show popups")
checked: true
checked: eventsColumn.behavior & NotificationManager.Settings.ShowPopups
onClicked: eventsColumn.setBehavior(NotificationManager.Settings.ShowPopups, checked)
}
RowLayout {
......@@ -61,12 +87,16 @@ ColumnLayout {
QtControls.CheckBox {
text: i18n("Show in do not disturb mode")
enabled: showPopupsCheck.checked
checked: eventsColumn.behavior & NotificationManager.Settings.ShowPopupsInDoNotDisturbMode
onClicked: eventsColumn.setBehavior(NotificationManager.Settings.ShowPopupsInDoNotDisturbMode, checked)
}
}
QtControls.CheckBox {
text: i18n("Notification badges")
enabled: !!eventsColumn.desktopEntry
enabled: !!eventsColumn.appData.desktopEntry
checked: eventsColumn.behavior & NotificationManager.Settings.ShowBadges
onClicked: eventsColumn.setBehavior(NotificationManager.Settings.ShowBadges, checked)
}
}
......@@ -83,8 +113,6 @@ ColumnLayout {
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
enabled: !eventsColumn.customActivitySettings
Component.onCompleted: background.visible = true
QtControls.ScrollBar.horizontal.visible: false
......@@ -207,19 +235,6 @@ ColumnLayout {
}
}
}
QtControls.Label {
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
right: parent.right
margins: Kirigami.Units.smallSpacing
}
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
text: i18n("Application events cannot be configured on a per-activity basis.")
visible: eventsColumn.customActivitySettings
}
}
// compact layout when event list isnt't shown
......
......@@ -24,9 +24,15 @@ import QtQuick.Controls 2.3 as QtControls
import org.kde.kirigami 2.7 as Kirigami
Kirigami.Page {
id: positionPage
property QtObject settings
title: i18n("Popup Position")
ScreenPositionSelector {
anchors.fill: parent
anchors.horizontalCenter: parent.horizontalCenter
selectedPosition: settings.popupPosition
onSelectedPositionChanged: settings.popupPosition = selectedPosition
}
}
......@@ -25,28 +25,29 @@ import QtQuick.Controls 2.2 as QtControls
import org.kde.kirigami 2.4 as Kirigami
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.private.notifications 1.0
import org.kde.notificationmanager 1.0 as NotificationManager
Item {
id: monitorPanel
property int baseUnit: Kirigami.Units.gridUnit// Math.round(Kirigami.Units.gridUnit / 1.5)
property int baseUnit: Kirigami.Units.gridUnit
implicitWidth: baseUnit * 13 + baseUnit * 2
implicitHeight: (screenRatio * baseUnit * 13) + (baseUnit * 2) + basePart.height
//flat: true
property int selectedPosition
property var disabledPositions: []
property real screenRatio: Screen.height / Screen.width
onEnabledChanged: {
if (!enabled) {
positionRadios.current = null
onSelectedPositionChanged: {
var buttons = positionRadios.buttons.length;
for (var i = 0; i < buttons.length; ++i) {
var button = buttons[i];
if (button.position === selectedPosition) {
button.checked = true;
break;
}
}
selectedPosition = NotificationsHelper.Default
}
PlasmaCore.Svg {
......@@ -164,15 +165,10 @@ Item {
QtControls.ButtonGroup {
id: positionRadios
onCheckedButtonChanged: monitorPanel.selectedPosition = checkedButton.position
}
/*QtControls.ExclusiveGroup {
id: positionRadios
onCurrentChanged: {
monitorPanel.selectedPosition = current.position;
}
}*/
// TODO increase hit area for radio buttons
QtControls.RadioButton {
anchors {
......@@ -180,7 +176,7 @@ Item {
left: leftPart.right
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.TopLeft
readonly property int position: NotificationManager.Settings.TopLeft
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
......@@ -191,7 +187,7 @@ Item {
horizontalCenter: topPart.horizontalCenter
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.TopCenter
readonly property int position: NotificationManager.Settings.TopCenter
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
......@@ -202,40 +198,7 @@ Item {
right: rightPart.left
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.TopRight
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
}
QtControls.RadioButton {
anchors {
left: leftPart.right
verticalCenter: leftPart.verticalCenter
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.Left
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
}
QtControls.RadioButton {
anchors {
horizontalCenter: topPart.horizontalCenter
verticalCenter: leftPart.verticalCenter
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.Center
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
}
QtControls.RadioButton {
anchors {
right: rightPart.left
verticalCenter: rightPart.verticalCenter
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.Right
readonly property int position: NotificationManager.Settings.TopRight
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
......@@ -246,7 +209,7 @@ Item {
left: leftPart.right
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.BottomLeft
readonly property int position: NotificationManager.Settings.BottomLeft
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
......@@ -257,7 +220,7 @@ Item {
horizontalCenter: bottomPart.horizontalCenter
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.BottomCenter
readonly property int position: NotificationManager.Settings.BottomCenter
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
......@@ -268,7 +231,7 @@ Item {
right: rightPart.left
margins: Kirigami.Units.smallSpacing
}
readonly property int position: NotificationsHelper.BottomRight
readonly property int position: NotificationManager.Settings.BottomRight
checked: monitorPanel.selectedPosition == position
visible: monitorPanel.disabledPositions.indexOf(position) == -1
QtControls.ButtonGroup.group: positionRadios
......
......@@ -20,91 +20,41 @@
import QtQuick 2.9
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
//import QtQuick.Dialogs 1.0 as QtDialogs
import QtQuick.Controls 2.3 as QtControls
import org.kde.kirigami 2.4 as Kirigami
//import org.kde.kconfig 1.0 // for KAuthorized
import org.kde.kcm 1.2 as KCM
import org.kde.notificationmanager 1.0 as NotificationManager
KCM.SimpleKCM {
KCM.ConfigModule.quickHelp: i18n("This module lets you manage application and system notifications.")
KCM.ConfigModule.buttons: KCM.ConfigModule.Help/* | KCM.ConfigModule.Default*/ | KCM.ConfigModule.Apply
KCM.ConfigModule.buttons: KCM.ConfigModule.Help | KCM.ConfigModule.Default | KCM.ConfigModule.Apply
implicitHeight: 550 // HACK FIXME
Binding {
target: kcm
property: "needsSave"
value: kcm.settings.dirty // TODO or other stuff
}
Kirigami.FormLayout {
RowLayout {
Kirigami.FormData.label: i18n("Do not disturb mode:")
QtControls.CheckBox {
id: dndTimeCheck
text: i18nc("Enable between hh:mm and hh:mm", "Automatically enable")
text: i18nc("Enable do not disturb during following times", "During following times:")
}
QtControls.Button {
text: i18nc("Set times for automatic do not disturb mode", "Set Times...")
text: i18nc("Choose times for do not disturb mode", "Choose...")
icon.name: "preferences-system-time"
onClicked: kcm.push("DndTimePage.qml")
enabled: dndTimeCheck.checked
}
}
QtControls.CheckBox {
text: i18nc("Apps can enable do not disturb mode", "Applications can enable")
checked: true
}
RowLayout {
QtControls.Label {
text: i18n("Keyboard Shortcut:")
}
// TODO keysequence thing
QtControls.Button {
icon.name: "configure"
text: i18n("Meta+N")
}
QtControls.Button {
icon.name: "edit-clear"
}
}
ColumnLayout {
visible: activitiesDndRepeater.count > 1
QtControls.Label {
text: i18n("Automatically enable in the following activities:")
}
Repeater {
id: activitiesDndRepeater
model: kcm.activitiesModel
QtControls.CheckBox {
id: activityCheck
text: model.name
icon.name: model.iconSource || "preferences-activities"
// FIXME make icons work in QQC2 desktop style CheckBox
contentItem: RowLayout {
Kirigami.Icon {
Layout.leftMargin: indicator.width + Kirigami.Units.smallSpacing
source: activityCheck.icon.name
Layout.preferredWidth: Kirigami.Units.iconSizes.small
Layout.preferredHeight: Kirigami.Units.iconSizes.small
}
QtControls.Label {
text: activityCheck.text
}
}
}
}
}
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
......@@ -112,38 +62,45 @@ KCM.SimpleKCM {
QtControls.CheckBox {
Kirigami.FormData.label: i18n("Critical notifications:")
text: i18n("Show in do not disturb mode")
checked: true
checked: kcm.settings.criticalPopupsInDoNotDisturbMode
onClicked: kcm.settings.criticalPopupsInDoNotDisturbMode = checked
}
QtControls.CheckBox {
text: i18n("Keep always on top")
checked: true
checked: kcm.settings.keepCriticalAlwaysOnTop
onClicked: kcm.settings.keepCriticalAlwaysOnTop = checked
}
QtControls.CheckBox {
Kirigami.FormData.label: i18n("Low priority notifications:")
text: i18n("Show popup")
checked: kcm.settings.lowPriorityPopups
onClicked: kcm.settings.lowPriorityPopups = checked
}
QtControls.ButtonGroup {
id: positionGroup
buttons: [positionCloseToPanel, positionCustomPosition]
buttons: [positionNearWidget, positionCustomPosition]
}
QtControls.RadioButton {
id: positionCloseToPanel
id: positionNearWidget
Kirigami.FormData.label: i18n("Popup position:")
text: i18n("Near the notification icon") // "widget"
checked: true
text: i18nc("Popup position near notification plasmoid", "Near the notification icon") // "widget"
checked: kcm.settings.popupPosition === NotificationManager.Settings.NearWidget
onClicked: kcm.settings.popupPosition = NotificationManager.Settings.NearWidget
}
RowLayout {
QtControls.RadioButton {
id: positionCustomPosition
text: i18n("Custom Position")
checked: kcm.settings.popupPosition !== NotificationManager.Settings.NearWidget
}
QtControls.Button {
text: i18n("Choose...")
icon.name: "preferences-desktop-display"
onClicked: kcm.push("PopupPositionPage.qml")
enabled: positionCustomPosition.checked
}
......@@ -153,14 +110,23 @@ KCM.SimpleKCM {
Layout.fillWidth: false
Kirigami.FormData.label: i18n("Hide popup after:")
textRole: "label"
currentIndex: {
var idx = model.findIndex(function (item) {
return item.value === kcm.settings.popupTimeout;
});
// would be neat if we could add a custom timeout if setting isn't listed
return idx !== -1 ? idx : 0;
}
model: [
{label: i18n("5 seconds"), value: 5},
{label: i18n("7 seconds"), value: 7},
{label: i18n("10 seconds"), value: 10},
{label: i18n("15 seconds"), value: 15},
{label: i18n("30 seconds"), value: 30},
{label: i18n("1 minute"), value: 60}
{label: i18n("5 seconds"), value: 5 * 1000},
{label: i18n("7 seconds"), value: 7 * 1000},
{label: i18n("10 seconds"), value: 10 * 1000},
{label: i18n("15 seconds"), value: 15 * 1000},
{label: i18n("30 seconds"), value: 30 * 1000},
{label: i18n("1 minute"), value: 60 * 1000}
]
onActivated: kcm.settings.popupTimeout = model[index].value
// FIXME proper sizing, especially for the popup
Layout.maximumWidth: Kirigami.Units.gridUnit * 6
}
......@@ -172,27 +138,32 @@ KCM.SimpleKCM {
QtControls.CheckBox {
Kirigami.FormData.label: i18n("Application progress:")
text: i18n("Show in task manager")
checked: true
checked: kcm.settings.jobsInTaskManager
onClicked: kcm.settings.jobsInTaskManager = checked
}
QtControls.CheckBox {
id: applicationJobsEnabledCheck
text: i18n("Show popup")