diff --git a/applets/notifications/package/contents/config/main.xml b/applets/notifications/package/contents/config/main.xml
--- a/applets/notifications/package/contents/config/main.xml
+++ b/applets/notifications/package/contents/config/main.xml
@@ -14,6 +14,10 @@
true
+
+
+ true
+
diff --git a/applets/notifications/package/contents/ui/NotificationHistoryDelegate.qml b/applets/notifications/package/contents/ui/NotificationHistoryDelegate.qml
new file mode 100644
--- /dev/null
+++ b/applets/notifications/package/contents/ui/NotificationHistoryDelegate.qml
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2011 Marco Martin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import QtQuick 2.0
+import QtQuick.Controls.Private 1.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+import org.kde.plasma.components 2.0 as PlasmaComponents
+import org.kde.plasma.extras 2.0 as PlasmaExtras
+import org.kde.kquickcontrolsaddons 2.0
+
+PlasmaComponents.ListItem {
+ id: notificationItem
+ width: popupFlickable.width
+
+ opacity: 1-Math.abs(x)/width
+
+ enabled: model.hasDefaultAction
+ checked: notificationItem.containsMouse
+
+ Timer {
+ interval: 10*60*1000
+ repeat: false
+ running: !idleTimeSource.idle
+ onTriggered: {
+ if (!notificationsHistoryModel.inserting)
+ notificationsHistoryModel.remove(index)
+ }
+ }
+
+ MouseArea {
+ width: parent.width
+ height: childrenRect.height
+ acceptedButtons: Qt.NoButtons
+
+ drag {
+ target: notificationItem
+ axis: Drag.XAxis
+ //kind of an hack over Column being too smart
+ minimumX: -parent.width + 1
+ maximumX: parent.width - 1
+ }
+ onReleased: {
+ if (notificationItem.x < -notificationItem.width/2) {
+ removeAnimation.exitFromRight = false
+ removeAnimation.running = true
+ } else if (notificationItem.x > notificationItem.width/2 ) {
+ removeAnimation.exitFromRight = true
+ removeAnimation.running = true
+ } else {
+ resetAnimation.running = true
+ }
+ }
+
+ SequentialAnimation {
+ id: removeAnimation
+ property bool exitFromRight: true
+ NumberAnimation {
+ target: notificationItem
+ properties: "x"
+ to: removeAnimation.exitFromRight ? notificationItem.width-1 : 1-notificationItem.width
+ duration: units.longDuration
+ easing.type: Easing.InOutQuad
+ }
+ NumberAnimation {
+ target: notificationItem
+ properties: "height"
+ to: 0
+ duration: units.longDuration
+ easing.type: Easing.InOutQuad
+ }
+ ScriptAction {
+ script: {
+ closeNotification(model.source);
+ notificationsHistoryModel.remove(index);
+ }
+ }
+ }
+
+ SequentialAnimation {
+ id: resetAnimation
+ NumberAnimation {
+ target: notificationItem
+ properties: "x"
+ to: 0
+ duration: units.longDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ NotificationItem {
+ id: notification
+ width: parent.width
+
+ compact: true
+ icon: appIcon
+ image: model.image
+ summary: model.summary
+ body: model.body
+ configurable: model.configurable && !Settings.isMobile
+ // model.actions JS array is implicitly turned into a ListModel which we can assign directly
+ actions: model.actions
+ created: model.created
+ hasDefaultAction: model.hasDefaultAction
+ hasConfigureAction: model.hasConfigureAction
+ urls: {
+ // QML ListModel tries to be smart and turns our urls Array into a dict with index as key...
+ var urls = []
+
+ var modelUrls = model.urls
+ if (modelUrls) {
+ for (var key in modelUrls) {
+ urls.push(modelUrls[key])
+ }
+ }
+
+ return urls
+ }
+
+ onClose: {
+ if (notificationsHistoryModel.count > 1) {
+ removeAnimation.running = true
+ } else {
+ closeNotification(model.source)
+ notificationsHistoryModel.remove(index)
+ }
+ }
+ onConfigure: {
+ plasmoid.expanded = false
+ configureNotification(model.appRealName, model.eventId)
+ }
+ onAction: {
+ executeAction(model.source, actionId)
+ actions.clear()
+ }
+ onOpenUrl: {
+ plasmoid.expanded = false
+ Qt.openUrlExternally(url)
+ }
+ }
+
+ } //MouseArea
+
+ Component.onCompleted: {
+ mainScrollArea.height = mainScrollArea.implicitHeight
+ }
+ Component.onDestruction: {
+ mainScrollArea.height = mainScrollArea.implicitHeight
+ }
+}
diff --git a/applets/notifications/package/contents/ui/Notifications.qml b/applets/notifications/package/contents/ui/Notifications.qml
--- a/applets/notifications/package/contents/ui/Notifications.qml
+++ b/applets/notifications/package/contents/ui/Notifications.qml
@@ -32,7 +32,16 @@
}
property alias count: notificationsRepeater.count
+ property alias historyCount: notificationsHistoryRepeater.count
+
+ property bool showHistory
+
signal popupShown(var popup)
+
+ onShowHistoryChanged: {
+ if(!showHistory)
+ clearHistory()
+ }
Component.onCompleted: {
// Create the popup components and pass them to the C++ plugin
@@ -74,6 +83,13 @@
notificationsModel.insert(0, notification);
notificationsModel.inserting = false;
}
+ else if (showHistory) {
+ notification.created = new Date();
+
+ notificationsHistoryModel.inserting = true;
+ notificationsHistoryModel.insert(0, notification);
+ notificationsHistoryModel.inserting = false;
+ }
notificationPositioner.displayNotification(notification);
}
@@ -129,6 +145,11 @@
}
notificationsModel.clear()
+ clearHistory()
+ }
+
+ function clearHistory() {
+ notificationsHistoryModel.clear()
}
Component {
@@ -140,6 +161,11 @@
id: notificationsModel
property bool inserting: false
}
+
+ ListModel {
+ id: notificationsHistoryModel
+ property bool inserting: false
+ }
PlasmaCore.DataSource {
id: idleTimeSource
@@ -222,4 +248,12 @@
model: notificationsModel
delegate: NotificationDelegate {}
}
+
+ Repeater {
+ anchors.top: notificationsRepeater.bottom
+
+ id: notificationsHistoryRepeater
+ model: notificationsHistoryModel
+ delegate: NotificationHistoryDelegate {}
+ }
}
diff --git a/applets/notifications/package/contents/ui/configNotifications.qml b/applets/notifications/package/contents/ui/configNotifications.qml
--- a/applets/notifications/package/contents/ui/configNotifications.qml
+++ b/applets/notifications/package/contents/ui/configNotifications.qml
@@ -35,6 +35,7 @@
property alias cfg_showNotifications: showNotificationsCheckBox.checked
property alias cfg_showJobs: showJobsCheckBox.checked
+ property alias cfg_showHistory: showHistoryCheckBox.checked
QtLayouts.ColumnLayout {
anchors.left: parent.left
@@ -47,6 +48,12 @@
id: showJobsCheckBox
text: i18n("Track file transfers and other jobs")
}
+
+ QtControls.CheckBox {
+ id: showHistoryCheckBox
+ text: i18n("Show a history of notifications")
+ }
+
QtControls.CheckBox {
id: useCustomPopupPositionCheckBox
text: i18n("Use custom position for the notification popup")
diff --git a/applets/notifications/package/contents/ui/main.qml b/applets/notifications/package/contents/ui/main.qml
--- a/applets/notifications/package/contents/ui/main.qml
+++ b/applets/notifications/package/contents/ui/main.qml
@@ -51,26 +51,27 @@
property Item notifications: notificationsLoader.item
property Item jobs: jobsLoader.item
-
+
//notifications + jobs
- property int totalCount: (notifications ? notifications.count : 0) + (jobs ? jobs.count : 0)
+ property int activeItemsCount: (notifications ? notifications.count : 0) + (jobs ? jobs.count : 0)
+ property int totalCount: activeItemsCount + (notifications ? notifications.totalCount : 0)
property Item notificationIcon
Plasmoid.switchWidth: units.gridUnit * 20
Plasmoid.switchHeight: units.gridUnit * 30
- Plasmoid.status: totalCount > 0 ? PlasmaCore.Types.ActiveStatus : PlasmaCore.Types.PassiveStatus
+ Plasmoid.status: activeItemsCount > 0 ? PlasmaCore.Types.ActiveStatus : PlasmaCore.Types.PassiveStatus
Plasmoid.icon: {
if (jobs && jobs.count) {
return "notification-active"
}
- return totalCount ? "notification-inactive" : "notification-disabled"
+ return activeItemsCount ? "notification-inactive" : "notification-disabled"
}
Plasmoid.toolTipSubText: {
- if (totalCount == 0) {
+ if (activeItemsCount == 0) {
return i18n("No notifications or jobs")
} else if (!notifications || !notifications.count) {
return i18np("%1 running job", "%1 running jobs", jobs.count)
@@ -91,9 +92,9 @@
state: "default"
hoverEnabled: !UiProperties.touchInput
- onTotalCountChanged: {
- print(" totalCountChanged " + totalCount)
- if (totalCount > 0) {
+ onActiveItemsCountChanged: {
+ print(" activeItemsCountChanged " + activeItemsCount)
+ if (activeItemsCount > 0) {
state = "new-notifications"
} else {
state = "default"
@@ -147,6 +148,9 @@
width: parent.width
source: "Notifications.qml"
active: notificationsApplet.Plasmoid.configuration.showNotifications
+ onLoaded: {
+ notificationsLoader.item.showHistory = Qt.binding(function(){ return notificationsApplet.Plasmoid.configuration.showHistory })
+ }
}
}
}