Gentoo Archives: gentoo-commits

From: "Andreas Hüttel" <dilfridge@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] dev/dilfridge:master commit in: kde-base/plasma-workspace/files/, kde-base/plasma-workspace/
Date: Tue, 29 Apr 2014 22:47:47
Message-Id: 1398811654.e8643b94912d0327564600ee9196efebc06394ec.dilfridge@gentoo
1 commit: e8643b94912d0327564600ee9196efebc06394ec
2 Author: Andreas K. Huettel (dilfridge) <dilfridge <AT> gentoo <DOT> org>
3 AuthorDate: Tue Apr 29 22:47:09 2014 +0000
4 Commit: Andreas Hüttel <dilfridge <AT> gentoo <DOT> org>
5 CommitDate: Tue Apr 29 22:47:34 2014 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=dev/dilfridge.git;a=commit;h=e8643b94
7
8 [kde-base/plasma-workspace] clean up
9
10 ---
11 kde-base/plasma-workspace/Manifest | 1 -
12 kde-base/plasma-workspace/files/oldnotify.patch | 8557 --------------------
13 .../plasma-workspace-4.10.1-noplasmalock.patch | 11 -
14 kde-base/plasma-workspace/metadata.xml | 9 -
15 .../plasma-workspace-4.11.2-r2.ebuild | 125 -
16 5 files changed, 8703 deletions(-)
17
18 diff --git a/kde-base/plasma-workspace/Manifest b/kde-base/plasma-workspace/Manifest
19 deleted file mode 100644
20 index 48cd387..0000000
21 --- a/kde-base/plasma-workspace/Manifest
22 +++ /dev/null
23 @@ -1 +0,0 @@
24 -DIST kde-workspace-4.11.2.tar.xz 13870828 SHA256 260e46f30b8faaa1ad834d9fa69465ab1f565cb18a174bd814327083bb28d917 SHA512 8d034e147ebb630941465b77e302aa2385c2f1419847e8a65ac19d445846435b61d78323fdb094b9a71089ab183c96af141db93c7c9c53a9b30c84ae69bddf2a WHIRLPOOL 0db07ef64caf873c0aa6398a28b92fdc9334eb04897c9a71ed0e3c54ad77e9e8dc23b13b6343844650a2ec7c2784664185f01cf64424d694a8c33167affb5720
25
26 diff --git a/kde-base/plasma-workspace/files/oldnotify.patch b/kde-base/plasma-workspace/files/oldnotify.patch
27 deleted file mode 100644
28 index c4c5c3b..0000000
29 --- a/kde-base/plasma-workspace/files/oldnotify.patch
30 +++ /dev/null
31 @@ -1,8557 +0,0 @@
32 -diff --git a/plasma/generic/applets/notifications/CMakeLists.txt b/plasma/generic/applets/notifications/CMakeLists.txt
33 -index 02afb93..a38fe47 100644
34 ---- a/plasma/generic/applets/notifications/CMakeLists.txt
35 -+++ b/plasma/generic/applets/notifications/CMakeLists.txt
36 -@@ -1,2 +1,47 @@
37 --installPackage(. org.kde.notifications)
38 -+project(plasma-notifications)
39 -+#TODO: see if is still the case
40 -+# 'engineName' causes error
41 -+kde4_no_enable_final(plasma-notifications)
42 -
43 -+set(notifications_SRCS
44 -+
45 -+ core/notificationsmanager.cpp
46 -+ core/protocol.cpp
47 -+ core/notification.cpp
48 -+ core/completedjobnotification.cpp
49 -+ core/job.cpp
50 -+
51 -+ protocols/notifications/dbusnotificationprotocol.cpp
52 -+ protocols/notifications/dbusnotification.cpp
53 -+
54 -+ protocols/jobs/dbusjobprotocol.cpp
55 -+ protocols/jobs/dbusjob.cpp
56 -+
57 -+ ui/busywidget.cpp
58 -+ ui/notifications.cpp
59 -+ ui/notificationwidget.cpp
60 -+ ui/jobtotalswidget.cpp
61 -+ ui/jobwidget.cpp
62 -+ ui/notificationgroup.cpp
63 -+ ui/notificationstack.cpp
64 -+ ui/stackdialog.cpp
65 -+ )
66 -+
67 -+kde4_add_ui_files(notifications_SRCS
68 -+ ui/notificationsconfig.ui)
69 -+
70 -+
71 -+include (CheckLibraryExists)
72 -+check_library_exists (Xss XScreenSaverQueryInfo "" HAVE_LIBXSS)
73 -+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config-notifications.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-notifications.h)
74 -+IF (HAVE_LIBXSS)
75 -+ SET (IDLE_DETECTION_LIB "Xss")
76 -+ENDIF (HAVE_LIBXSS)
77 -+
78 -+
79 -+kde4_add_plugin(plasma_applet_notifications ${notifications_SRCS})
80 -+include_directories(${CMAKE_SOURCE_DIR})
81 -+target_link_libraries(plasma_applet_notifications ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${X11_LIBRARIES} ${X11_Xrender_LIB} ${X11_Xfixes_LIB} ${X11_Xdamage_LIB} ${X11_Xcomposite_LIB} ${KDE4_SOLID_LIBS} ${IDLE_DETECTION_LIB})
82 -+
83 -+install(TARGETS plasma_applet_notifications DESTINATION ${PLUGIN_INSTALL_DIR})
84 -+install(FILES plasma-applet-notifications.desktop DESTINATION ${SERVICES_INSTALL_DIR})
85 -diff --git a/plasma/generic/applets/notifications/Messages.sh b/plasma/generic/applets/notifications/Messages.sh
86 -old mode 100644
87 -new mode 100755
88 -index bd3e2d9..5582bc6
89 ---- a/plasma/generic/applets/notifications/Messages.sh
90 -+++ b/plasma/generic/applets/notifications/Messages.sh
91 -@@ -1,5 +1,4 @@
92 - #! /usr/bin/env bash
93 --$EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp
94 --$XGETTEXT `find . -name \*.qml` -L Java -o $podir/plasma_applet_org.kde.notifications.pot
95 --$XGETTEXT rc.cpp -jo $podir/plasma_applet_org.kde.notifications.pot
96 -+$EXTRACTRC `find . -name '*.ui'` >> rc.cpp
97 -+$XGETTEXT `find . -name '*.cpp'` -o $podir/plasma_applet_notifications.pot
98 - rm -f rc.cpp
99 -diff --git a/plasma/generic/applets/notifications/config-notifications.h.cmake b/plasma/generic/applets/notifications/config-notifications.h.cmake
100 -new file mode 100644
101 -index 0000000..aac3113
102 ---- /dev/null
103 -+++ b/plasma/generic/applets/notifications/config-notifications.h.cmake
104 -@@ -0,0 +1 @@
105 -+#cmakedefine HAVE_LIBXSS
106 -diff --git a/plasma/generic/applets/notifications/contents/config/main.xml b/plasma/generic/applets/notifications/contents/config/main.xml
107 -deleted file mode 100644
108 -index 399159d..0000000
109 ---- a/plasma/generic/applets/notifications/contents/config/main.xml
110 -+++ /dev/null
111 -@@ -1,23 +0,0 @@
112 --<?xml version="1.0" encoding="UTF-8"?>
113 --<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
114 -- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
115 -- xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
116 -- http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
117 -- <kcfgfile name=""/>
118 --
119 -- <group name="General">
120 -- <entry name="CustomPosition" type="Point">
121 -- <label>where the notification popup will be</label>
122 -- <default>-1,-1</default>
123 -- </entry>
124 -- <entry name="ShowNotifications" type="Bool">
125 -- <label>Show the notifications</label>
126 -- <default>true</default>
127 -- </entry>
128 -- <entry name="ShowJobs" type="Bool">
129 -- <label>Show the jobs progress</label>
130 -- <default>true</default>
131 -- </entry>
132 -- </group>
133 --
134 --</kcfg>
135 -diff --git a/plasma/generic/applets/notifications/contents/ui/JobDelegate.qml b/plasma/generic/applets/notifications/contents/ui/JobDelegate.qml
136 -deleted file mode 100644
137 -index e94866d..0000000
138 ---- a/plasma/generic/applets/notifications/contents/ui/JobDelegate.qml
139 -+++ /dev/null
140 -@@ -1,310 +0,0 @@
141 --/*
142 -- * Copyright 2011 Marco Martin <notmart@×××××.com>
143 -- *
144 -- * This program is free software; you can redistribute it and/or modify
145 -- * it under the terms of the GNU Library General Public License as
146 -- * published by the Free Software Foundation; either version 2, or
147 -- * (at your option) any later version.
148 -- *
149 -- * This program is distributed in the hope that it will be useful,
150 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
151 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
152 -- * GNU Library General Public License for more details
153 -- *
154 -- * You should have received a copy of the GNU Library General Public
155 -- * License along with this program; if not, write to the
156 -- * Free Software Foundation, Inc.,
157 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
158 -- */
159 --
160 --import QtQuick 1.0
161 --import org.kde.plasma.core 0.1 as PlasmaCore
162 --import org.kde.plasma.components 0.1 as PlasmaComponents
163 --import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets
164 --import org.kde.qtextracomponents 0.1
165 --
166 --PlasmaComponents.ListItem {
167 -- id: notificationItem
168 -- width: popupFlickable.width
169 --
170 -- property int toolIconSize: theme.smallMediumIconSize
171 -- property int layoutSpacing: 4
172 --
173 -- function getData(data, name, defaultValue) {
174 -- return data[modelData] ? (data[modelData][name] ? data[modelData][name] : defaultValue) : defaultValue;
175 -- }
176 --
177 -- property string labelName0: getData(jobsSource.data, "labelName0", '')
178 -- property string label0: getData(jobsSource.data, "label0", '')
179 -- property string labelName1: getData(jobsSource.data, "labelName1", '')
180 -- property string label1: getData(jobsSource.data, "label1", '')
181 -- property string jobstate: getData(jobsSource.data, "state", '')
182 -- property int eta: getData(jobsSource.data, "eta", 0)
183 -- property string speed: getData(jobsSource.data, "speed", '')
184 --
185 -- Column {
186 -- spacing: notificationItem.layoutSpacing
187 -- width: parent.width
188 -- PlasmaComponents.Label {
189 -- text: getData(jobsSource.data, "infoMessage", '')
190 -- font.bold: true
191 -- color: theme.textColor
192 -- anchors.horizontalCenter: parent.horizontalCenter
193 -- }
194 -- Grid {
195 -- anchors {
196 -- left: parent.left
197 -- right: parent.right
198 -- rightMargin: notificationItem.layoutSpacing
199 -- }
200 -- spacing: notificationItem.layoutSpacing
201 -- rows: 4
202 -- columns: 2
203 --
204 -- PlasmaComponents.Label {
205 -- id: labelName0Text
206 -- text: labelName0 ? i18n("%1:", labelName0) : ''
207 -- width: Math.max(paintedWidth, labelName1Text.paintedWidth)
208 -- horizontalAlignment: Text.AlignRight
209 -- visible: labelName0 != ''
210 -- }
211 -- PlasmaComponents.Label {
212 -- id: label0Text
213 -- text: label0 ? label0 : ''
214 -- width: parent.width - labelName0Text.width
215 -- elide: Text.ElideMiddle
216 -- visible: label0 != ''
217 --
218 -- PlasmaCore.ToolTip {
219 -- target: label0Text
220 -- subText: label0Text.truncated ? label0 : ""
221 -- }
222 --
223 -- }
224 -- PlasmaComponents.Label {
225 -- id: labelName1Text
226 -- text: labelName1 ? i18n("%1:", labelName1) : ''
227 -- width: Math.max(paintedWidth, labelName0Text.paintedWidth)
228 -- horizontalAlignment: Text.AlignRight
229 -- visible: labelName1 != ''
230 -- }
231 -- PlasmaComponents.Label {
232 -- id: label1Text
233 -- text: label1 ? label1 : ''
234 -- width: parent.width - labelName0Text.width
235 -- elide: Text.ElideMiddle
236 -- visible: label1 != ''
237 --
238 -- PlasmaCore.ToolTip {
239 -- target: label1Text
240 -- subText: label1Text.truncated ? label1 : ""
241 -- }
242 -- }
243 -- QIconItem {
244 -- icon: getData(jobsSource.data, "appIconName", '')
245 -- width: notificationItem.toolIconSize
246 -- height: width
247 -- anchors {
248 -- verticalCenter: progressItem.verticalCenter
249 -- right: progressItem.left
250 -- rightMargin: notificationItem.layoutSpacing
251 -- }
252 -- }
253 -- Item {
254 -- id: progressItem
255 -- width: parent.width - labelName0Text.width
256 -- height: childrenRect.height
257 -- PlasmaComponents.ProgressBar {
258 -- width: parent.width - pauseButton.width*2 - theme.largeIconSize - notificationItem.layoutSpacing*3
259 -- height: 16
260 -- orientation: Qt.Horizontal
261 -- minimumValue: 0
262 -- maximumValue: 100
263 -- //percentage doesn't always exist, so doesn't get in the model
264 -- value: getData(jobsSource.data, "percentage", 0)
265 --
266 -- anchors {
267 -- left: parent.left
268 -- right: buttonsRow.left
269 -- verticalCenter: parent.verticalCenter
270 -- rightMargin: notificationItem.layoutSpacing
271 -- }
272 -- }
273 -- Row {
274 -- id: buttonsRow
275 -- spacing: notificationItem.layoutSpacing
276 -- anchors.right: parent.right
277 -- PlasmaComponents.ToolButton {
278 -- id: pauseButton
279 -- width: notificationItem.toolIconSize
280 -- height: width
281 -- iconSource: jobstate == "suspended" ? "media-playback-start" : "media-playback-pause"
282 -- flat: false
283 -- onClicked: {
284 -- var operationName = "suspend"
285 -- if (jobstate == "suspended") {
286 -- operationName = "resume"
287 -- }
288 -- var service = jobsSource.serviceForSource(modelData)
289 -- var operation = service.operationDescription(operationName)
290 -- service.startOperationCall(operation)
291 -- }
292 -- }
293 -- PlasmaComponents.ToolButton {
294 -- id: stopButton
295 -- width: notificationItem.toolIconSize
296 -- height: width
297 -- iconSource: "media-playback-stop"
298 -- flat: false
299 -- onClicked: {
300 -- var service = jobsSource.serviceForSource(modelData)
301 -- var operation = service.operationDescription("stop")
302 -- service.startOperationCall(operation)
303 -- }
304 -- }
305 -- }
306 -- }
307 -- PlasmaComponents.ToolButton {
308 -- id: expandButton
309 -- width: notificationItem.toolIconSize
310 -- height: width
311 -- flat: false
312 -- iconSource: checked ? "list-remove" : "list-add"
313 -- checkable: true
314 -- anchors {
315 -- right: speedLabel.left
316 -- rightMargin: notificationItem.layoutSpacing
317 -- verticalCenter: speedLabel.verticalCenter
318 -- }
319 -- }
320 -- PlasmaComponents.Label {
321 -- id: speedLabel
322 -- text: eta > 0 ? i18nc("Speed and estimated time to completition", "%1 (%2 remaining)", speed, locale.prettyFormatDuration(eta)) : speed
323 -- }
324 -- }
325 --
326 --
327 -- Item {
328 -- id: detailsItem
329 -- state: expandButton.checked ? "expanded" : "collapsed"
330 -- anchors {
331 -- left: parent.left
332 -- right: parent.right
333 -- leftMargin: speedLabel.x
334 -- }
335 -- property Item contentsItem
336 -- Component {
337 -- id: detailsComponent
338 -- Column {
339 -- id: detailsColumn
340 -- anchors {
341 -- left: parent.left
342 -- right: parent.right
343 -- }
344 --
345 -- function localizeProcessedAmount(id) {
346 -- //if bytes localise the unit
347 -- if (jobsSource.data[modelData]["processedUnit"+id] == "bytes") {
348 -- return i18nc("How much many bytes (or whether unit in the locale has been copied over total", "%1 of %2",
349 -- locale.formatByteSize(jobsSource.data[modelData]["processedAmount"+id]),
350 -- locale.formatByteSize(jobsSource.data[modelData]["totalAmount"+id]))
351 -- //else print something only if is interesting data (ie more than one file/directory etc to copy
352 -- } else if (jobsSource.data[modelData]["totalAmount"+id] > 1) {
353 -- return i18n( "%1 of %2 %3",
354 -- jobsSource.data[modelData]["processedAmount"+id],
355 -- jobsSource.data[modelData]["totalAmount"+id],
356 -- jobsSource.data[modelData]["processedUnit"+id])
357 -- } else {
358 -- return ""
359 -- }
360 -- }
361 -- PlasmaComponents.Label {
362 -- text: jobsSource.data[modelData] ? detailsColumn.localizeProcessedAmount(0) : ""
363 -- anchors.left: parent.left
364 -- visible: text != ""
365 -- }
366 -- PlasmaComponents.Label {
367 -- text: jobsSource.data[modelData] ? detailsColumn.localizeProcessedAmount(1) : ""
368 -- anchors.left: parent.left
369 -- visible: text != ""
370 -- }
371 -- PlasmaComponents.Label {
372 -- text: jobsSource.data[modelData] ? detailsColumn.localizeProcessedAmount(2) : ""
373 -- anchors.left: parent.left
374 -- visible: text != ""
375 -- }
376 -- PlasmaWidgets.SignalPlotter {
377 -- id: plotter
378 -- width: parent.width
379 -- useAutoRange: true
380 -- showVerticalLines: false
381 -- unit: i18n("KiB/s")
382 -- height: theme.defaultFont.mSize.height * 5
383 -- Component.onCompleted: plotter.addPlot(theme.highlightColor)
384 -- }
385 -- Connections {
386 -- target: jobsSource
387 -- onDataChanged: {
388 -- plotter.addSample([jobsSource.data[modelData]["numericSpeed"]/1000])
389 -- }
390 -- }
391 -- }
392 -- }
393 --
394 -- states: [
395 -- State {
396 -- name: "expanded"
397 -- PropertyChanges {
398 -- target: detailsItem
399 -- height: detailsItem.childrenRect.height
400 -- }
401 -- },
402 -- State {
403 -- name: "collapsed"
404 -- PropertyChanges {
405 -- target: detailsItem
406 -- height: 0
407 -- }
408 -- }
409 -- ]
410 -- transitions : [
411 -- Transition {
412 -- from: "collapsed"
413 -- to: "expanded"
414 -- SequentialAnimation {
415 -- ScriptAction {
416 -- script: {
417 -- detailsItem.visible = true
418 -- detailsItem.clip = true
419 -- //create the contents if they don't exist yet
420 -- if (!detailsItem.contentsItem) {
421 -- detailsItem.contentsItem = detailsComponent.createObject(detailsItem)
422 -- }
423 -- }
424 -- }
425 -- NumberAnimation {
426 -- duration: 250
427 -- properties: "height"
428 -- easing: PropertyAnimation.EaseInOut
429 -- }
430 -- ScriptAction {script: detailsItem.clip = false}
431 -- }
432 -- },
433 -- Transition {
434 -- from: "expanded"
435 -- to: "collapsed"
436 -- SequentialAnimation {
437 -- ScriptAction {script: detailsItem.clip = true}
438 -- NumberAnimation {
439 -- duration: 250
440 -- properties: "height"
441 -- easing: PropertyAnimation.EaseInOut
442 -- }
443 -- //TODO: delete the details?
444 -- ScriptAction {script: detailsItem.visible = false}
445 -- }
446 -- }
447 -- ]
448 -- }
449 -- }
450 --}
451 -diff --git a/plasma/generic/applets/notifications/contents/ui/Jobs.qml b/plasma/generic/applets/notifications/contents/ui/Jobs.qml
452 -deleted file mode 100644
453 -index 7e2f2a2..0000000
454 ---- a/plasma/generic/applets/notifications/contents/ui/Jobs.qml
455 -+++ /dev/null
456 -@@ -1,105 +0,0 @@
457 --/*
458 -- * Copyright 2012 Marco Martin <notmart@×××××.com>
459 -- *
460 -- * This program is free software; you can redistribute it and/or modify
461 -- * it under the terms of the GNU Library General Public License as
462 -- * published by the Free Software Foundation; either version 2, or
463 -- * (at your option) any later version.
464 -- *
465 -- * This program is distributed in the hope that it will be useful,
466 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
467 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
468 -- * GNU Library General Public License for more details
469 -- *
470 -- * You should have received a copy of the GNU Library General Public
471 -- * License along with this program; if not, write to the
472 -- * Free Software Foundation, Inc.,
473 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
474 -- */
475 --
476 --import QtQuick 1.1
477 --import org.kde.plasma.core 0.1 as PlasmaCore
478 --import org.kde.plasma.components 0.1 as PlasmaComponents
479 --
480 --Column {
481 -- id: jobsRoot
482 -- property alias count: jobsRepeater.count
483 -- anchors {
484 -- left: parent.left
485 -- right: parent.right
486 -- }
487 --
488 -- PlasmaCore.DataSource {
489 -- id: jobsSource
490 -- engine: "applicationjobs"
491 -- interval: 0
492 --
493 -- onSourceAdded: {
494 -- connectSource(source);
495 -- }
496 -- property variant runningJobs
497 --
498 -- onSourceRemoved: {
499 -- if (!notifications) {
500 -- return
501 -- }
502 -- var message = runningJobs[source]["label1"] ? runningJobs[source]["label1"] : runningJobs[source]["label0"]
503 -- notifications.addNotification(
504 -- source,
505 -- runningJobs[source]["appIconName"],
506 -- 0,
507 -- runningJobs[source]["appName"],
508 -- i18n("%1 [Finished]", runningJobs[source]["infoMessage"]),
509 -- message,
510 -- 0,
511 -- 0,
512 -- [{"id": message, "text": i18n("Open")}])
513 -- delete runningJobs[source]
514 -- }
515 -- Component.onCompleted: {
516 -- jobsSource.runningJobs = new Object
517 -- connectedSources = sources
518 -- }
519 -- onNewData: {
520 -- var jobs = runningJobs
521 -- jobs[sourceName] = data
522 -- runningJobs = jobs
523 -- }
524 -- onDataChanged: {
525 -- var total = 0
526 -- for (var i = 0; i < sources.length; ++i) {
527 -- if (jobsSource.data[sources[i]]["percentage"]) {
528 -- total += jobsSource.data[sources[i]]["percentage"]
529 -- }
530 -- }
531 --
532 -- total /= sources.length
533 -- notificationsApplet.globalProgress = total/100
534 -- }
535 -- }
536 --
537 -- Title {
538 -- visible: jobsRepeater.count > 0 && notifications && notifications.count > 0
539 -- text: i18n("Transfers")
540 -- }
541 -- PlasmaComponents.ListItem {
542 -- visible: jobsRepeater.count > 1
543 -- PlasmaComponents.ProgressBar {
544 -- anchors {
545 -- verticalCenter: parent.verticalCenter
546 -- left: parent.left
547 -- right: parent.right
548 -- }
549 -- minimumValue: 0
550 -- maximumValue: 100
551 -- value: notificationsApplet.globalProgress * 100
552 -- }
553 -- }
554 -- Repeater {
555 -- id: jobsRepeater
556 -- model: jobsSource.sources
557 -- delegate: JobDelegate {
558 -- toolIconSize: notificationsApplet.toolIconSize
559 -- }
560 -- }
561 --}
562 -\ No newline at end of file
563 -diff --git a/plasma/generic/applets/notifications/contents/ui/LastNotificationPopup.qml b/plasma/generic/applets/notifications/contents/ui/LastNotificationPopup.qml
564 -deleted file mode 100644
565 -index 26bce0f..0000000
566 ---- a/plasma/generic/applets/notifications/contents/ui/LastNotificationPopup.qml
567 -+++ /dev/null
568 -@@ -1,414 +0,0 @@
569 --/***************************************************************************
570 -- * Copyright 2011 Davide Bettio <davide.bettio@×××××××.net> *
571 -- * Copyright 2011 Marco Martin <mart@×××.org> *
572 -- * *
573 -- * This program is free software; you can redistribute it and/or modify *
574 -- * it under the terms of the GNU Library General Public License as published by *
575 -- * the Free Software Foundation; either version 2 of the License, or *
576 -- * (at your option) any later version. *
577 -- * *
578 -- * This program is distributed in the hope that it will be useful, *
579 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
580 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
581 -- * GNU Library General Public License for more details. *
582 -- * *
583 -- * You should have received a copy of the GNU Library General Public License *
584 -- * along with this program; if not, write to the *
585 -- * Free Software Foundation, Inc., *
586 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
587 -- ***************************************************************************/
588 --
589 --import QtQuick 1.1
590 --import org.kde.plasma.core 0.1 as PlasmaCore
591 --import org.kde.plasma.components 0.1 as PlasmaComponents
592 --import org.kde.qtextracomponents 0.1
593 --import org.kde.plasma.extras 0.1 as PlasmaExtras
594 --
595 --
596 --PlasmaCore.Dialog {
597 -- id: lastNotificationPopup
598 --
599 -- property variant savedPos
600 -- property bool customPosition: false
601 --
602 -- onHeightChanged: setCustomPosition(lastNotificationPopup.savedPos, false)
603 -- onWidthChanged: setCustomPosition(lastNotificationPopup.savedPos, false)
604 --
605 -- function popup(notification)
606 -- {
607 -- if (!lastNotificationPopup.visible) {
608 -- lastNotificationsModel.clear()
609 -- }
610 -- lastNotificationsModel.append(notification)
611 --
612 -- setCustomPosition(lastNotificationPopup.savedPos, false)
613 --
614 -- lastNotificationPopup.visible = true
615 -- lastNotificationTimer.interval = Math.max(4000, Math.min(60*1000, notificationsModel.get(0).expireTimeout))
616 -- notificationsView.currentIndex = lastNotificationsModel.count - 1
617 -- lastNotificationTimer.restart()
618 -- mainItem.buttonPressed = false
619 -- }
620 --
621 -- function setCustomPosition(pos, writeConfig)
622 -- {
623 -- var popupPos = lastNotificationPopup.popupPosition(notificationIcon, Qt.AlignCenter)
624 -- var finalPos
625 --
626 -- //custom
627 -- if ((pos.x >= 0 || pos.y >= 0) &&
628 -- (Math.abs(popupPos.x - pos.x) > 40 ||
629 -- Math.abs(popupPos.y - pos.y) > 40)) {
630 -- finalPos = pos
631 -- if (writeConfig) {
632 -- plasmoid.writeConfig("CustomPosition", pos)
633 -- lastNotificationPopup.savedPos = pos
634 -- lastNotificationPopup.customPosition = true
635 -- }
636 -- } else {
637 -- finalPos = popupPos
638 -- if (writeConfig) {
639 -- plasmoid.writeConfig("CustomPosition", QPoint(-1,-1))
640 -- lastNotificationPopup.savedPos = QPoint(-1,-1)
641 -- lastNotificationPopup.customPosition = false
642 -- }
643 -- }
644 -- lastNotificationPopup.x = finalPos.x
645 -- lastNotificationPopup.y = finalPos.y
646 -- }
647 --
648 -- location: customPosition ? Floating : plasmoid.location
649 -- windowFlags: Qt.WindowStaysOnTopHint
650 -- Component.onCompleted: {
651 -- setAttribute(Qt.WA_X11NetWmWindowTypeDock, true)
652 --
653 -- lastNotificationPopup.savedPos = plasmoid.readConfig("CustomPosition")
654 -- setCustomPosition(lastNotificationPopup.savedPos, true)
655 -- plasmoid.popupEvent.connect(lastNotificationPopup.popupEvent)
656 -- }
657 --
658 -- function popupEvent(popupShowing)
659 -- {
660 -- if(popupShowing) {
661 -- lastNotificationPopup.visible = false
662 -- }
663 -- }
664 --
665 -- mainItem: MouseEventListener {
666 -- id: mainItem
667 -- width: maximumWidth
668 -- height: maximumHeight
669 -- property int maximumWidth: theme.defaultFont.mSize.width * 35
670 -- property int maximumHeight: theme.defaultFont.mSize.width * 10
671 -- property int minimumWidth: maximumWidth
672 -- property int minimumHeight: maximumHeight
673 --
674 -- property int startX: 0
675 -- property int startY: 0
676 -- property int startScreenX: 0
677 -- property int startScreenY: 0
678 -- hoverEnabled: true
679 -- property bool buttonPressed: false
680 --
681 -- state: "controlsHidden"
682 -- onContainsMouseChanged: {
683 -- if (containsMouse) {
684 -- mainItem.state = "controlsShown"
685 -- lastNotificationTimer.running = false
686 -- } else {
687 -- mainItem.state = "controlsHidden"
688 -- lastNotificationTimer.restart()
689 -- }
690 -- }
691 -- onPressed: {
692 -- startX = mouse.x + lastNotificationPopup.margins.left
693 -- startY = mouse.y + lastNotificationPopup.margins.top
694 -- startScreenX = mouse.screenX
695 -- startScreenY = mouse.screenY
696 -- lastNotificationTimer.running = false
697 -- }
698 -- onReleased: {
699 -- //FIXME: bind startdragdistance
700 -- if ((navigationButtonsColumn.visible && mouse.x < navigationButtonsColumn.width) ||
701 -- buttonPressed ||
702 -- Math.sqrt(Math.pow(startScreenX - mouse.screenX, 2) + Math.pow(startScreenY - mouse.screenY, 2)) > 4) {
703 -- } else {
704 -- lastNotificationPopup.visible = false
705 -- }
706 --
707 -- setCustomPosition(QPoint(Math.max(0, mouse.screenX - startX), Math.max(mouse.screenY - startY)), true)
708 -- }
709 -- onPositionChanged: {
710 -- lastNotificationPopup.x = Math.max(0, mouse.screenX - startX)
711 -- lastNotificationPopup.y = Math.max(0, mouse.screenY - startY)
712 -- }
713 -- onWheelMoved: {
714 -- if (notificationsView.moving) {
715 -- return
716 -- }
717 --
718 -- if (wheel.delta > 0) {
719 -- notificationsView.currentIndex = Math.max(0, notificationsView.currentIndex-1)
720 -- } else {
721 -- notificationsView.currentIndex = Math.min(notificationsView.count-1, notificationsView.currentIndex+1)
722 -- }
723 -- }
724 --
725 -- Timer {
726 -- id: lastNotificationTimer
727 -- interval: 4000
728 -- repeat: false
729 -- running: false
730 -- onTriggered: lastNotificationPopup.visible = false
731 -- }
732 --
733 -- ListView {
734 -- id: notificationsView
735 -- clip: true
736 -- snapMode: ListView.SnapOneItem
737 -- orientation: ListView.Horizontal
738 -- anchors.fill: parent
739 -- model: ListModel {
740 -- id: lastNotificationsModel
741 -- }
742 -- interactive: false
743 -- delegate: Item {
744 -- height: notificationsView.height
745 -- width: notificationsView.width
746 --
747 -- PlasmaComponents.Label {
748 -- id: titleLabel
749 -- text: model.summary
750 -- //font.weight: Font.Bold
751 -- visible: model.summary.length > 0
752 -- height: model.summary.length > 0 ? paintedHeight : 0
753 -- horizontalAlignment: Text.AlignHCenter
754 -- color: theme.textColor
755 -- elide: Text.ElideRight
756 -- anchors {
757 -- left: appIconItem.y > y + height ? parent.left : appIconItem.right
758 -- right: parent.right
759 -- rightMargin: settingsButton.visible ? settingsButton.width + closeButton.width : closeButton.width
760 -- top: parent.top
761 -- topMargin: 6
762 -- leftMargin: 6
763 -- }
764 -- onLinkActivated: plasmoid.openUrl(link)
765 -- }
766 --
767 -- QIconItem {
768 -- id: appIconItem
769 -- icon: model.appIcon
770 -- width: (model.appIcon.length > 0 || imageItem.visible) ? theme.largeIconSize : 0
771 -- height: theme.largeIconSize
772 -- visible: !imageItem.visible
773 -- anchors {
774 -- left: parent.left
775 -- verticalCenter: parent.verticalCenter
776 -- leftMargin: navigationButtonsColumn.width
777 -- }
778 -- }
779 -- QImageItem {
780 -- id: imageItem
781 -- anchors.fill: appIconItem
782 -- image: model.image
783 -- smooth: true
784 -- visible: nativeWidth > 0
785 -- }
786 -- /*
787 -- * this extra item is for clip the overflowed body text
788 -- * maximumLineCount cannot control the behavior of rich text,
789 -- * so manual clip is required.
790 -- */
791 -- Item {
792 -- id: bodyLabel
793 -- clip: true
794 -- height: Math.min(parent.height - (titleLabel.height+titleLabel.y), lastNotificationText.height)
795 -- property bool tallText: bodyLabel.height >= (bodyLabel.parent.height - (titleLabel.height+titleLabel.y)*2)
796 -- anchors {
797 -- top: tallText ? titleLabel.bottom : undefined
798 -- verticalCenter: tallText ? undefined : parent.verticalCenter
799 -- left: appIconItem.right
800 -- right: actionsColumn.left
801 -- leftMargin: 6
802 -- rightMargin: 6
803 -- }
804 -- PlasmaComponents.Label {
805 -- id: lastNotificationText
806 -- text: model.body
807 -- width: parent.width
808 -- //textFormat: Text.PlainText
809 -- color: theme.textColor
810 -- wrapMode: Text.Wrap
811 -- elide: Text.ElideRight
812 -- maximumLineCount: 4
813 -- onLinkActivated: plasmoid.openUrl(link)
814 -- }
815 -- }
816 -- Column {
817 -- id: actionsColumn
818 -- spacing: 6
819 -- anchors {
820 -- right: parent.right
821 -- rightMargin: 6
822 -- verticalCenter: parent.verticalCenter
823 -- }
824 -- Repeater {
825 -- model: actions
826 -- PlasmaComponents.Button {
827 -- text: model.text
828 -- width: theme.defaultFont.mSize.width * 8
829 -- height: theme.defaultFont.mSize.width * 2
830 -- onPressedChanged: {
831 -- if (pressed) {
832 -- mainItem.buttonPressed = true
833 -- } else {
834 -- mainItem.buttonPressed = false
835 -- }
836 -- }
837 -- onClicked: {
838 -- executeAction(source, model.id)
839 -- actionsColumn.visible = false
840 -- }
841 -- }
842 -- }
843 -- }
844 -- }
845 -- }
846 --
847 -- Column {
848 -- id: navigationButtonsColumn
849 -- opacity: 0
850 -- visible: backButton.enabled || nextButton.enabled
851 -- anchors {
852 -- left: parent.left
853 -- verticalCenter: parent.verticalCenter
854 -- }
855 --
856 -- PlasmaComponents.ToolButton {
857 -- id: nextButton
858 -- iconSource: "go-next"
859 -- width: theme.smallMediumIconSize
860 -- height: mainItem.height/2 - 4
861 -- enabled: notificationsView.currentIndex < notificationsView.count-1
862 -- onPressedChanged: {
863 -- if (pressed) {
864 -- mainItem.buttonPressed = true
865 -- } else {
866 -- mainItem.buttonPressed = false
867 -- }
868 -- }
869 -- onClicked: {
870 -- notificationsView.currentIndex = Math.min(notificationsView.count-1, notificationsView.currentIndex+1)
871 -- }
872 -- }
873 --
874 -- PlasmaComponents.ToolButton {
875 -- id: backButton
876 -- iconSource: "go-previous"
877 -- width: theme.smallMediumIconSize
878 -- height: mainItem.height/2 - 4
879 -- enabled: notificationsView.currentIndex > 0
880 -- onPressedChanged: {
881 -- if (pressed) {
882 -- mainItem.buttonPressed = true
883 -- } else {
884 -- mainItem.buttonPressed = false
885 -- }
886 -- }
887 -- onClicked: {
888 -- notificationsView.currentIndex = Math.max(0, notificationsView.currentIndex-1)
889 -- }
890 -- }
891 -- }
892 -- PlasmaComponents.ToolButton {
893 -- id: closeButton
894 -- opacity: 0
895 -- iconSource: "window-close"
896 -- width: theme.smallMediumIconSize
897 -- height: width
898 -- anchors {
899 -- right: parent.right
900 -- top: parent.top
901 -- }
902 -- onPressedChanged: {
903 -- if (pressed) {
904 -- mainItem.buttonPressed = true
905 -- } else {
906 -- mainItem.buttonPressed = false
907 -- }
908 -- }
909 -- onClicked: {
910 -- lastNotificationPopup.visible = false
911 -- lastNotificationTimer.running = false
912 -- closeNotification(notificationsModel.get((notificationsView.count-1)-notificationsView.currentIndex).source)
913 -- notificationsModel.remove((notificationsView.count-1)-notificationsView.currentIndex)
914 -- }
915 -- }
916 -- PlasmaComponents.ToolButton {
917 -- id: settingsButton
918 -- opacity: 0
919 -- iconSource: "configure"
920 -- width: theme.smallMediumIconSize
921 -- height: width
922 -- visible: notificationsModel.get((notificationsView.count-1)-notificationsView.currentIndex).configurable
923 -- anchors {
924 -- right: closeButton.left
925 -- top: parent.top
926 -- rightMargin: 5
927 -- }
928 -- onPressedChanged: {
929 -- if (pressed) {
930 -- mainItem.buttonPressed = true
931 -- } else {
932 -- mainItem.buttonPressed = false
933 -- }
934 -- }
935 -- onClicked: {
936 -- lastNotificationPopup.visible = false
937 -- configureNotification(notificationsModel.get((notificationsView.count-1)-notificationsView.currentIndex).appRealName)
938 -- }
939 -- }
940 -- states: [
941 -- State {
942 -- name: "controlsShown"
943 -- PropertyChanges {
944 -- target: navigationButtonsColumn
945 -- opacity: 1
946 -- }
947 -- PropertyChanges {
948 -- target: closeButton
949 -- opacity: 1
950 -- }
951 -- PropertyChanges {
952 -- target: settingsButton
953 -- opacity: 1
954 -- }
955 -- },
956 -- State {
957 -- name: "controlsHidden"
958 -- PropertyChanges {
959 -- target: navigationButtonsColumn
960 -- opacity: 0
961 -- }
962 -- PropertyChanges {
963 -- target: closeButton
964 -- opacity: 0
965 -- }
966 -- PropertyChanges {
967 -- target: settingsButton
968 -- opacity: 0
969 -- }
970 -- }
971 -- ]
972 -- transitions: [
973 -- Transition {
974 -- NumberAnimation {
975 -- properties: "opacity"
976 -- easing.type: Easing.InOutQuad
977 -- duration: 250
978 -- }
979 -- }
980 -- ]
981 -- }
982 --}
983 -diff --git a/plasma/generic/applets/notifications/contents/ui/NotificationDelegate/NotificationDelegate.qml b/plasma/generic/applets/notifications/contents/ui/NotificationDelegate/NotificationDelegate.qml
984 -deleted file mode 100644
985 -index bf33eb1..0000000
986 ---- a/plasma/generic/applets/notifications/contents/ui/NotificationDelegate/NotificationDelegate.qml
987 -+++ /dev/null
988 -@@ -1,253 +0,0 @@
989 --/*
990 -- * Copyright 2011 Marco Martin <notmart@×××××.com>
991 -- *
992 -- * This program is free software; you can redistribute it and/or modify
993 -- * it under the terms of the GNU Library General Public License as
994 -- * published by the Free Software Foundation; either version 2, or
995 -- * (at your option) any later version.
996 -- *
997 -- * This program is distributed in the hope that it will be useful,
998 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
999 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1000 -- * GNU Library General Public License for more details
1001 -- *
1002 -- * You should have received a copy of the GNU Library General Public
1003 -- * License along with this program; if not, write to the
1004 -- * Free Software Foundation, Inc.,
1005 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1006 -- */
1007 --
1008 --import QtQuick 1.1
1009 --import org.kde.plasma.core 0.1 as PlasmaCore
1010 --import org.kde.plasma.components 0.1 as PlasmaComponents
1011 --import org.kde.qtextracomponents 0.1
1012 --
1013 --PlasmaComponents.ListItem {
1014 -- id: notificationItem
1015 -- opacity: 1-Math.abs(x)/width
1016 -- width: popupFlickable.width
1017 -- property int toolIconSize: theme.smallMediumIconSize
1018 -- property int layoutSpacing: 4
1019 --
1020 -- visible: appTabBar.currentTab == allAppsTab || appTabBar.currentTab.text == appName
1021 --
1022 -- Component.onCompleted: {
1023 -- allApplicationsModel.addApplication(appIcon, appName)
1024 -- mainScrollArea.height = mainScrollArea.implicitHeight
1025 -- }
1026 -- Component.onDestruction: {
1027 -- allApplicationsModel.removeApplication(model.appName)
1028 -- mainScrollArea.height = mainScrollArea.implicitHeight
1029 -- }
1030 -- Timer {
1031 -- interval: 10*60*1000
1032 -- repeat: false
1033 -- running: !idleTimeSource.idle
1034 -- onTriggered: {
1035 -- notificationsModel.remove(index)
1036 -- }
1037 -- }
1038 --
1039 -- MouseArea {
1040 -- width: parent.width
1041 -- height: childrenRect.height
1042 -- drag {
1043 -- target: notificationItem
1044 -- axis: Drag.XAxis
1045 -- //kind of an hack over Column being too smart
1046 -- minimumX: -parent.width + 1
1047 -- maximumX: parent.width - 1
1048 -- }
1049 -- onReleased: {
1050 -- if (notificationItem.x < -notificationItem.width/2) {
1051 -- removeAnimation.exitFromRight = false
1052 -- removeAnimation.running = true
1053 -- } else if (notificationItem.x > notificationItem.width/2 ) {
1054 -- removeAnimation.exitFromRight = true
1055 -- removeAnimation.running = true
1056 -- } else {
1057 -- resetAnimation.running = true
1058 -- }
1059 -- }
1060 -- SequentialAnimation {
1061 -- id: removeAnimation
1062 -- property bool exitFromRight: true
1063 -- NumberAnimation {
1064 -- target: notificationItem
1065 -- properties: "x"
1066 -- to: removeAnimation.exitFromRight ? notificationItem.width-1 : 1-notificationItem.width
1067 -- duration: 250
1068 -- easing.type: Easing.InOutQuad
1069 -- }
1070 -- NumberAnimation {
1071 -- target: notificationItem
1072 -- properties: "height"
1073 -- to: 0
1074 -- duration: 250
1075 -- easing.type: Easing.InOutQuad
1076 -- }
1077 -- ScriptAction {
1078 -- script: notificationsModel.remove(index)
1079 -- }
1080 -- }
1081 -- SequentialAnimation {
1082 -- id: resetAnimation
1083 -- NumberAnimation {
1084 -- target: notificationItem
1085 -- properties: "x"
1086 -- to: 0
1087 -- duration: 250
1088 -- easing.type: Easing.InOutQuad
1089 -- }
1090 -- }
1091 -- Column {
1092 -- spacing: notificationItem.layoutSpacing
1093 -- width: parent.width
1094 -- Item {
1095 -- width: parent.width
1096 -- height: summaryLabel.height
1097 --
1098 -- PlasmaComponents.Label {
1099 -- id: summaryLabel
1100 -- text: summary
1101 -- height: paintedHeight
1102 -- anchors {
1103 -- left: parent.left
1104 -- right: parent.right
1105 -- leftMargin: closeButton.width
1106 -- rightMargin: settingsButton.visible ? settingsButton.width + closeButton.width : closeButton.width
1107 -- }
1108 -- horizontalAlignment: Text.AlignHCenter
1109 -- elide: Text.ElideRight
1110 -- onLinkActivated: plasmoid.openUrl(link)
1111 -- }
1112 --
1113 -- PlasmaComponents.ToolButton {
1114 -- id: closeButton
1115 -- iconSource: "window-close"
1116 -- width: notificationItem.toolIconSize
1117 -- height: width
1118 -- onClicked: {
1119 -- if (notificationsModel.count > 1) {
1120 -- removeAnimation.running = true
1121 -- } else {
1122 -- closeNotification(model.source)
1123 -- notificationsModel.remove(index)
1124 -- }
1125 -- }
1126 -- anchors {
1127 -- top: parent.top
1128 -- right: parent.right
1129 -- }
1130 -- }
1131 --
1132 -- PlasmaComponents.ToolButton {
1133 -- id: settingsButton
1134 -- iconSource: "configure"
1135 -- width: notificationItem.toolIconSize
1136 -- height: width
1137 -- visible: model.configurable
1138 -- onClicked: {
1139 -- plasmoid.hidePopup()
1140 -- configureNotification(model.appRealName)
1141 -- }
1142 -- anchors {
1143 -- top: parent.top
1144 -- right: closeButton.left
1145 -- rightMargin: 5
1146 -- }
1147 -- }
1148 -- }
1149 --
1150 -- Item {
1151 -- height: childrenRect.height
1152 -- width: parent.width
1153 -- QIconItem {
1154 -- id: appIconItem
1155 -- icon: QIcon(appIcon)
1156 -- width: theme.largeIconSize
1157 -- height: theme.largeIconSize
1158 -- visible: !imageItem.visible
1159 -- anchors {
1160 -- left: parent.left
1161 -- verticalCenter: parent.verticalCenter
1162 -- }
1163 -- }
1164 -- QImageItem {
1165 -- id: imageItem
1166 -- anchors.fill: appIconItem
1167 -- image: model.image
1168 -- smooth: true
1169 -- visible: nativeWidth > 0
1170 -- }
1171 -- PlasmaComponents.ContextMenu {
1172 -- id: contextMenu
1173 -- visualParent: contextMouseArea
1174 -- PlasmaComponents.MenuItem {
1175 -- text: i18n("Copy")
1176 -- onClicked: bodyText.copy()
1177 -- }
1178 -- PlasmaComponents.MenuItem {
1179 -- text: i18n("Select All")
1180 -- onClicked: bodyText.selectAll()
1181 -- }
1182 -- }
1183 -- MouseArea {
1184 -- id: contextMouseArea
1185 -- anchors {
1186 -- left: appIconItem.right
1187 -- right: actionsColumn.left
1188 -- verticalCenter: parent.verticalCenter
1189 -- leftMargin: 6
1190 -- rightMargin: 6
1191 -- }
1192 -- acceptedButtons: Qt.RightButton
1193 -- height: bodyText.paintedHeight
1194 -- preventStealing: true
1195 -- onPressed: contextMenu.open(mouse.x, mouse.y)
1196 -- TextEdit {
1197 -- id: bodyText
1198 -- anchors.fill: parent
1199 -- text: body
1200 -- color: theme.textColor
1201 -- font.capitalization: theme.defaultFont.capitalization
1202 -- font.family: theme.defaultFont.family
1203 -- font.italic: theme.defaultFont.italic
1204 -- font.letterSpacing: theme.defaultFont.letterSpacing
1205 -- font.pointSize: theme.defaultFont.pointSize
1206 -- font.strikeout: theme.defaultFont.strikeout
1207 -- font.underline: theme.defaultFont.underline
1208 -- font.weight: theme.defaultFont.weight
1209 -- font.wordSpacing: theme.defaultFont.wordSpacing
1210 -- selectByMouse: true
1211 -- readOnly: true
1212 -- wrapMode: Text.Wrap
1213 -- textFormat: TextEdit.RichText
1214 -- onLinkActivated: plasmoid.openUrl(link)
1215 -- }
1216 -- }
1217 -- Column {
1218 -- id: actionsColumn
1219 -- spacing: notificationItem.layoutSpacing
1220 -- anchors {
1221 -- right: parent.right
1222 -- rightMargin: 6
1223 -- verticalCenter: parent.verticalCenter
1224 -- }
1225 -- Repeater {
1226 -- model: actions
1227 -- PlasmaComponents.Button {
1228 -- text: model.text
1229 -- width: theme.defaultFont.mSize.width * 8
1230 -- height: theme.defaultFont.mSize.width * 2
1231 -- onClicked: {
1232 -- executeAction(source, model.id)
1233 -- actionsColumn.visible = false
1234 -- }
1235 -- }
1236 -- }
1237 -- }
1238 -- }
1239 -- }
1240 -- }
1241 --}
1242 -diff --git a/plasma/generic/applets/notifications/contents/ui/NotificationDelegate/qmldir b/plasma/generic/applets/notifications/contents/ui/NotificationDelegate/qmldir
1243 -deleted file mode 100644
1244 -index 88fc37a..0000000
1245 ---- a/plasma/generic/applets/notifications/contents/ui/NotificationDelegate/qmldir
1246 -+++ /dev/null
1247 -@@ -1 +0,0 @@
1248 --NotificationDelegate 0.1 NotificationDelegate.qml
1249 -diff --git a/plasma/generic/applets/notifications/contents/ui/NotificationIcon.qml b/plasma/generic/applets/notifications/contents/ui/NotificationIcon.qml
1250 -deleted file mode 100644
1251 -index f12cd56..0000000
1252 ---- a/plasma/generic/applets/notifications/contents/ui/NotificationIcon.qml
1253 -+++ /dev/null
1254 -@@ -1,188 +0,0 @@
1255 --/***************************************************************************
1256 -- * Copyright 2011 Davide Bettio <davide.bettio@×××××××.net> *
1257 -- * Copyright 2011 Marco Martin <mart@×××.org> *
1258 -- * *
1259 -- * This program is free software; you can redistribute it and/or modify *
1260 -- * it under the terms of the GNU Library General Public License as published by *
1261 -- * the Free Software Foundation; either version 2 of the License, or *
1262 -- * (at your option) any later version. *
1263 -- * *
1264 -- * This program is distributed in the hope that it will be useful, *
1265 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
1266 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
1267 -- * GNU Library General Public License for more details. *
1268 -- * *
1269 -- * You should have received a copy of the GNU Library General Public License *
1270 -- * along with this program; if not, write to the *
1271 -- * Free Software Foundation, Inc., *
1272 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
1273 -- ***************************************************************************/
1274 --
1275 --import QtQuick 1.1
1276 --import org.kde.plasma.core 0.1 as PlasmaCore
1277 --import org.kde.plasma.components 0.1 as PlasmaComponents
1278 --import org.kde.qtextracomponents 0.1
1279 --import org.kde.plasma.extras 0.1 as PlasmaExtras
1280 --
1281 --
1282 --Item {
1283 -- PlasmaCore.SvgItem {
1284 -- id: notificationSvgItem
1285 -- svg: notificationSvg
1286 -- elementId: "notification-disabled"
1287 -- anchors.centerIn: parent
1288 -- width: Math.min(parent.width, parent.height)
1289 -- height: width
1290 -- state: notificationsApplet.state
1291 --
1292 -- PlasmaCore.Svg {
1293 -- id: notificationSvg
1294 -- imagePath: "icons/notification"
1295 -- }
1296 --
1297 -- Item {
1298 -- id: jobProgressItem
1299 -- width: notificationSvgItem.width * globalProgress
1300 -- clip: true
1301 -- visible: jobs.count > 0
1302 -- anchors {
1303 -- left: parent.left
1304 -- top: parent.top
1305 -- bottom: parent.bottom
1306 -- }
1307 -- PlasmaCore.SvgItem {
1308 -- svg: notificationSvg
1309 -- elementId: "notification-progress-active"
1310 -- anchors {
1311 -- left: parent.left
1312 -- top: parent.top
1313 -- bottom: parent.bottom
1314 -- }
1315 -- width: notificationSvgItem.width
1316 -- }
1317 -- }
1318 -- PlasmaComponents.BusyIndicator {
1319 -- anchors.fill: parent
1320 -- visible: jobs ? jobs.count > 0 : false
1321 -- running: visible
1322 -- }
1323 --
1324 -- Column {
1325 -- id: countColumn
1326 -- visible: false
1327 -- anchors.centerIn: parent
1328 -- PlasmaCore.SvgItem {
1329 -- svg: notificationSvg
1330 -- elementId: {
1331 -- switch (plasmoid.location) {
1332 -- case TopEdge:
1333 -- return "expander-top"
1334 -- case LeftEdge:
1335 -- return "expander-left"
1336 -- case RightEdge:
1337 -- return "expander-right"
1338 -- default:
1339 -- return "expander-bottom"
1340 -- }
1341 -- }
1342 -- width: naturalSize.width
1343 -- height: naturalSize.height
1344 -- anchors.horizontalCenter: parent.horizontalCenter
1345 -- }
1346 -- PlasmaComponents.Label {
1347 -- property int totalCount: notificationsApplet.totalCount
1348 -- text: totalCount
1349 --
1350 -- property int oldTotalCount: 0
1351 -- font.pointSize: theme.smallestFont.pointSize
1352 -- height: paintedHeight - 3
1353 -- onTotalCountChanged: {
1354 -- if (totalCount > oldTotalCount) {
1355 -- notificationAnimation.running = true
1356 -- }
1357 -- oldTotalCount = totalCount
1358 -- }
1359 -- }
1360 -- }
1361 --
1362 -- PlasmaCore.SvgItem {
1363 -- id: notificationAnimatedItem
1364 -- anchors.fill: parent
1365 -- svg: notificationSvg
1366 -- elementId: "notification-active"
1367 -- opacity: 0
1368 -- scale: 2
1369 --
1370 -- SequentialAnimation {
1371 -- id: notificationAnimation
1372 -- NumberAnimation {
1373 -- target: notificationAnimatedItem
1374 -- duration: 250
1375 -- properties: "opacity, scale"
1376 -- to: 1
1377 -- easing.type: Easing.InOutQuad
1378 -- }
1379 -- PauseAnimation { duration: 500 }
1380 -- ParallelAnimation {
1381 -- NumberAnimation {
1382 -- target: notificationAnimatedItem
1383 -- duration: 250
1384 -- properties: "opacity"
1385 -- to: 0
1386 -- easing.type: Easing.InOutQuad
1387 -- }
1388 -- NumberAnimation {
1389 -- target: notificationAnimatedItem
1390 -- duration: 250
1391 -- properties: "scale"
1392 -- to: 2
1393 -- easing.type: Easing.InOutQuad
1394 -- }
1395 -- }
1396 -- }
1397 -- }
1398 -- MouseArea {
1399 -- anchors.fill: parent
1400 -- onClicked: {
1401 -- if (notificationsApplet.totalCount > 0) {
1402 -- plasmoid.togglePopup()
1403 -- } else {
1404 -- plasmoid.hidePopup()
1405 -- }
1406 -- }
1407 -- }
1408 -- states: [
1409 -- State {
1410 -- name: "default"
1411 -- PropertyChanges {
1412 -- target: notificationSvgItem
1413 -- elementId: "notification-disabled"
1414 -- }
1415 -- PropertyChanges {
1416 -- target: countColumn
1417 -- visible: false
1418 -- }
1419 -- PropertyChanges {
1420 -- target: plasmoid
1421 -- status: PassiveStatus
1422 -- }
1423 -- },
1424 -- State {
1425 -- name: "new-notifications"
1426 -- PropertyChanges {
1427 -- target: notificationSvgItem
1428 -- elementId: jobs.count > 0 ? "notification-progress-inactive" : "notification-empty"
1429 -- }
1430 -- PropertyChanges {
1431 -- target: countColumn
1432 -- visible: true
1433 -- }
1434 -- PropertyChanges {
1435 -- target: plasmoid
1436 -- status: ActiveStatus
1437 -- }
1438 -- }
1439 -- ]
1440 -- }
1441 --}
1442 --
1443 -diff --git a/plasma/generic/applets/notifications/contents/ui/Notifications.qml b/plasma/generic/applets/notifications/contents/ui/Notifications.qml
1444 -deleted file mode 100644
1445 -index 114ead2..0000000
1446 ---- a/plasma/generic/applets/notifications/contents/ui/Notifications.qml
1447 -+++ /dev/null
1448 -@@ -1,227 +0,0 @@
1449 --/*
1450 -- * Copyright 2012 Marco Martin <notmart@×××××.com>
1451 -- *
1452 -- * This program is free software; you can redistribute it and/or modify
1453 -- * it under the terms of the GNU Library General Public License as
1454 -- * published by the Free Software Foundation; either version 2, or
1455 -- * (at your option) any later version.
1456 -- *
1457 -- * This program is distributed in the hope that it will be useful,
1458 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1459 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1460 -- * GNU Library General Public License for more details
1461 -- *
1462 -- * You should have received a copy of the GNU Library General Public
1463 -- * License along with this program; if not, write to the
1464 -- * Free Software Foundation, Inc.,
1465 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1466 -- */
1467 --
1468 --import QtQuick 1.1
1469 --import org.kde.plasma.core 0.1 as PlasmaCore
1470 --import org.kde.plasma.components 0.1 as PlasmaComponents
1471 --
1472 --import "plasmapackage:/ui/NotificationDelegate"
1473 --
1474 --Column {
1475 -- id: notificationsRoot
1476 -- property alias count: notificationsRepeater.count
1477 -- anchors {
1478 -- left: parent.left
1479 -- right: parent.right
1480 -- }
1481 --
1482 -- function addNotification(source, appIcon, image, appName, summary, body, expireTimeout, urgency, appRealName, configurable, actions) {
1483 -- // Do not show duplicated notifications
1484 -- for (var i = 0; i < notificationsModel.count; ++i) {
1485 -- if (notificationsModel.get(i).source == source &&
1486 -- notificationsModel.get(i).appName == appName &&
1487 -- notificationsModel.get(i).summary == summary &&
1488 -- notificationsModel.get(i).body == body) {
1489 -- return
1490 -- }
1491 -- }
1492 --
1493 -- for (var i = 0; i < notificationsModel.count; ++i) {
1494 -- if (notificationsModel.get(i).source == source) {
1495 -- notificationsModel.remove(i)
1496 -- break
1497 -- }
1498 -- }
1499 -- if (notificationsModel.count > 20) {
1500 -- notificationsModel.remove(notificationsModel.count-1)
1501 -- }
1502 -- var notification = {"source" : source,
1503 -- "appIcon" : appIcon,
1504 -- "image" : image,
1505 -- "appName" : appName,
1506 -- "summary" : summary,
1507 -- "body" : body,
1508 -- "expireTimeout": expireTimeout,
1509 -- "urgency" : urgency,
1510 -- "configurable": configurable,
1511 -- "appRealName": appRealName,
1512 -- "actions" : actions}
1513 -- notificationsModel.insert(0, notification);
1514 -- if (plasmoid.popupShowing) {
1515 -- return
1516 -- }
1517 -- if (!lastNotificationPopup) {
1518 -- lastNotificationPopup = lastNotificationPopupComponent.createObject(notificationsRoot)
1519 -- }
1520 -- lastNotificationPopup.popup(notification)
1521 -- }
1522 --
1523 -- function executeAction(source, id) {
1524 -- //try to use the service
1525 -- if (source.indexOf("notification") !== -1) {
1526 -- var service = notificationsSource.serviceForSource(source)
1527 -- var op = service.operationDescription("invokeAction")
1528 -- op["actionId"] = id
1529 --
1530 -- service.startOperationCall(op)
1531 -- //try to open the id as url
1532 -- } else if (source.indexOf("Job") !== -1) {
1533 -- plasmoid.openUrl(id)
1534 -- }
1535 -- }
1536 --
1537 -- function configureNotification(appRealName) {
1538 -- var service = notificationsSource.serviceForSource("notification")
1539 -- var op = service.operationDescription("configureNotification")
1540 -- op["appRealName"] = appRealName;
1541 -- service.startOperationCall(op)
1542 -- }
1543 --
1544 -- function closeNotification(source) {
1545 -- var service = notificationsSource.serviceForSource(source)
1546 -- var op = service.operationDescription("userClosed")
1547 -- service.startOperationCall(op)
1548 -- }
1549 --
1550 -- property QtObject lastNotificationPopup
1551 -- Component {
1552 -- id: lastNotificationPopupComponent
1553 -- LastNotificationPopup {
1554 -- }
1555 -- }
1556 --
1557 -- ListModel {
1558 -- id: notificationsModel
1559 -- }
1560 -- ListModel {
1561 -- id: allApplicationsModel
1562 -- function addApplication(icon, name)
1563 -- {
1564 -- for (var i = 0; i < count; ++i) {
1565 -- var item = get(i)
1566 -- if (item.name == name) {
1567 -- setProperty(i, "count", item.count + 1)
1568 -- return
1569 -- }
1570 -- }
1571 -- append({"icon": icon, "name": name, "count": 1})
1572 -- }
1573 -- function removeApplication(name)
1574 -- {
1575 -- for (var i = 0; i < count; ++i) {
1576 -- var item = get(i)
1577 -- if (item.name == name) {
1578 -- if (item.count <= 1) {
1579 -- remove(i)
1580 -- appTabBar.currentTab = allAppsTab
1581 -- return
1582 -- }
1583 -- setProperty(i, "count", item.count - 1)
1584 -- return
1585 -- }
1586 -- }
1587 -- }
1588 -- }
1589 --
1590 -- PlasmaCore.DataSource {
1591 -- id: idleTimeSource
1592 -- engine: "powermanagement"
1593 -- interval: 30000
1594 -- connectedSources: ["UserActivity"]
1595 -- //Idle whith more than 5 minutes of user inactivity
1596 -- property bool idle: data["UserActivity"]["IdleTime"] > 300000
1597 -- }
1598 --
1599 -- PlasmaCore.DataSource {
1600 -- id: notificationsSource
1601 -- engine: "notifications"
1602 -- interval: 0
1603 --
1604 -- onSourceAdded: {
1605 -- connectSource(source);
1606 -- }
1607 --
1608 -- onNewData: {
1609 -- var actions = new Array()
1610 -- if (data["actions"] && data["actions"].length % 2 == 0) {
1611 -- for (var i = 0; i < data["actions"].length; i += 2) {
1612 -- var action = new Object()
1613 -- action["id"] = data["actions"][i]
1614 -- action["text"] = data["actions"][i+1]
1615 -- actions.push(action)
1616 -- }
1617 -- }
1618 -- notificationsRoot.addNotification(
1619 -- sourceName,
1620 -- data["appIcon"],
1621 -- data["image"],
1622 -- data["appName"],
1623 -- data["summary"],
1624 -- data["body"],
1625 -- data["expireTimeout"],
1626 -- data["urgency"],
1627 -- data["appRealName"],
1628 -- data["configurable"],
1629 -- actions)
1630 -- }
1631 --
1632 -- }
1633 --
1634 -- Title {
1635 -- visible: notificationsRepeater.count > 1 || (jobs && jobs.count > 0 && notificationsRepeater.count > 0)
1636 -- text: i18n("Notifications")
1637 -- PlasmaComponents.ToolButton {
1638 -- iconSource: "window-close"
1639 -- width: notificationsApplet.toolIconSize
1640 -- height: width
1641 -- anchors {
1642 -- right: parent.right
1643 -- verticalCenter: parent.verticalCenter
1644 -- }
1645 -- onClicked: notificationsModel.clear()
1646 -- }
1647 -- }
1648 -- PlasmaComponents.ListItem {
1649 -- visible: allApplicationsModel.count > 1
1650 -- PlasmaComponents.TabBar {
1651 -- id: appTabBar
1652 -- anchors.horizontalCenter: parent.horizontalCenter
1653 -- width: Math.min(implicitWidth, parent.width-8)
1654 -- PlasmaComponents.TabButton {
1655 -- id: allAppsTab
1656 -- text: i18n("All")
1657 -- iconSource: "dialog-information"
1658 -- }
1659 -- Repeater {
1660 -- model: allApplicationsModel
1661 -- PlasmaComponents.TabButton {
1662 -- text: name
1663 -- iconSource: icon
1664 -- }
1665 -- }
1666 -- }
1667 -- }
1668 -- Repeater {
1669 -- id: notificationsRepeater
1670 -- model: notificationsModel
1671 -- delegate: NotificationDelegate {
1672 -- toolIconSize: notificationsApplet.toolIconSize
1673 -- }
1674 -- }
1675 --}
1676 -diff --git a/plasma/generic/applets/notifications/contents/ui/Title.qml b/plasma/generic/applets/notifications/contents/ui/Title.qml
1677 -deleted file mode 100644
1678 -index dff4f72..0000000
1679 ---- a/plasma/generic/applets/notifications/contents/ui/Title.qml
1680 -+++ /dev/null
1681 -@@ -1,43 +0,0 @@
1682 --/*
1683 -- * Copyright 2012 Marco Martin <notmart@×××××.com>
1684 -- *
1685 -- * This program is free software; you can redistribute it and/or modify
1686 -- * it under the terms of the GNU Library General Public License as
1687 -- * published by the Free Software Foundation; either version 2, or
1688 -- * (at your option) any later version.
1689 -- *
1690 -- * This program is distributed in the hope that it will be useful,
1691 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1692 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1693 -- * GNU Library General Public License for more details
1694 -- *
1695 -- * You should have received a copy of the GNU Library General Public
1696 -- * License along with this program; if not, write to the
1697 -- * Free Software Foundation, Inc.,
1698 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1699 -- */
1700 --
1701 --import QtQuick 1.1
1702 --import org.kde.plasma.core 0.1 as PlasmaCore
1703 --import org.kde.plasma.components 0.1 as PlasmaComponents
1704 --
1705 --PlasmaComponents.ListItem {
1706 -- id: root
1707 -- property alias text: titleLabel.text
1708 --
1709 --
1710 -- sectionDelegate: true
1711 --
1712 -- width: parent.width
1713 --
1714 -- PlasmaComponents.Label {
1715 -- id: titleLabel
1716 -- horizontalAlignment: Text.AlignHCenter
1717 -- elide: Text.ElideRight
1718 -- anchors {
1719 -- verticalCenter: parent.verticalCenter
1720 -- left: parent.left
1721 -- right: parent.right
1722 -- }
1723 -- }
1724 --}
1725 -diff --git a/plasma/generic/applets/notifications/contents/ui/config.ui b/plasma/generic/applets/notifications/contents/ui/config.ui
1726 -deleted file mode 100644
1727 -index 7769bba..0000000
1728 ---- a/plasma/generic/applets/notifications/contents/ui/config.ui
1729 -+++ /dev/null
1730 -@@ -1,69 +0,0 @@
1731 --<?xml version="1.0" encoding="UTF-8"?>
1732 --<ui version="4.0">
1733 -- <class>feedsConfig</class>
1734 -- <widget class="QWidget" name="feedsConfig">
1735 -- <property name="geometry">
1736 -- <rect>
1737 -- <x>0</x>
1738 -- <y>0</y>
1739 -- <width>337</width>
1740 -- <height>181</height>
1741 -- </rect>
1742 -- </property>
1743 -- <layout class="QFormLayout" name="formLayout">
1744 -- <item row="1" column="0">
1745 -- <widget class="QLabel" name="label_2">
1746 -- <property name="text">
1747 -- <string>&amp;Application notifications:</string>
1748 -- </property>
1749 -- <property name="buddy">
1750 -- <cstring>kcfg_ShowNotifications</cstring>
1751 -- </property>
1752 -- </widget>
1753 -- </item>
1754 -- <item row="1" column="1">
1755 -- <widget class="QCheckBox" name="kcfg_ShowNotifications">
1756 -- <property name="text">
1757 -- <string/>
1758 -- </property>
1759 -- </widget>
1760 -- </item>
1761 -- <item row="2" column="0">
1762 -- <widget class="QLabel" name="label_3">
1763 -- <property name="text">
1764 -- <string>&amp;File transfers and jobs:</string>
1765 -- </property>
1766 -- <property name="buddy">
1767 -- <cstring>kcfg_ShowJobs</cstring>
1768 -- </property>
1769 -- </widget>
1770 -- </item>
1771 -- <item row="2" column="1">
1772 -- <widget class="QCheckBox" name="kcfg_ShowJobs">
1773 -- <property name="text">
1774 -- <string/>
1775 -- </property>
1776 -- </widget>
1777 -- </item>
1778 -- <item row="0" column="0" colspan="2">
1779 -- <widget class="QLabel" name="label">
1780 -- <property name="font">
1781 -- <font>
1782 -- <weight>75</weight>
1783 -- <bold>true</bold>
1784 -- </font>
1785 -- </property>
1786 -- <property name="text">
1787 -- <string>Choose which information to show</string>
1788 -- </property>
1789 -- </widget>
1790 -- </item>
1791 -- </layout>
1792 -- </widget>
1793 -- <tabstops>
1794 -- <tabstop>kcfg_ShowNotifications</tabstop>
1795 -- <tabstop>kcfg_ShowJobs</tabstop>
1796 -- </tabstops>
1797 -- <resources/>
1798 -- <connections/>
1799 --</ui>
1800 -diff --git a/plasma/generic/applets/notifications/contents/ui/main.qml b/plasma/generic/applets/notifications/contents/ui/main.qml
1801 -deleted file mode 100644
1802 -index 4d4b0f7..0000000
1803 ---- a/plasma/generic/applets/notifications/contents/ui/main.qml
1804 -+++ /dev/null
1805 -@@ -1,171 +0,0 @@
1806 --/***************************************************************************
1807 -- * Copyright 2011 Davide Bettio <davide.bettio@×××××××.net> *
1808 -- * Copyright 2011 Marco Martin <mart@×××.org> *
1809 -- * *
1810 -- * This program is free software; you can redistribute it and/or modify *
1811 -- * it under the terms of the GNU Library General Public License as published by *
1812 -- * the Free Software Foundation; either version 2 of the License, or *
1813 -- * (at your option) any later version. *
1814 -- * *
1815 -- * This program is distributed in the hope that it will be useful, *
1816 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
1817 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
1818 -- * GNU Library General Public License for more details. *
1819 -- * *
1820 -- * You should have received a copy of the GNU Library General Public License *
1821 -- * along with this program; if not, write to the *
1822 -- * Free Software Foundation, Inc., *
1823 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
1824 -- ***************************************************************************/
1825 --
1826 --import QtQuick 1.1
1827 --import org.kde.plasma.core 0.1 as PlasmaCore
1828 --import org.kde.plasma.components 0.1 as PlasmaComponents
1829 --import org.kde.qtextracomponents 0.1
1830 --import org.kde.plasma.extras 0.1 as PlasmaExtras
1831 --import org.kde.locale 0.1 as KLocale
1832 --
1833 --import "plasmapackage:/ui/uiproperties.js" as UiProperties
1834 --
1835 --
1836 --MouseEventListener {
1837 -- id: notificationsApplet
1838 -- state: "default"
1839 -- width: 32
1840 -- height: 32
1841 -- property int minimumWidth: mainScrollArea.implicitWidth
1842 -- property int minimumHeight: mainScrollArea.implicitHeight
1843 -- property int maximumWidth: -1
1844 -- property int maximumHeight: mainScrollArea.implicitHeight
1845 --
1846 -- property int toolIconSize: UiProperties.toolIconSize
1847 -- property int layoutSpacing: UiProperties.layoutSpacing
1848 --
1849 -- property real globalProgress: 0
1850 --
1851 -- property bool showNotifications: false
1852 -- property bool showJobs: false
1853 --
1854 -- property Item notifications: notificationsLoader.item
1855 -- property Item jobs: jobsLoader.item
1856 --
1857 -- //notifications + jobs
1858 -- property int totalCount: (notifications ? notifications.count : 0) + (jobs ? jobs.count : 0)
1859 -- onTotalCountChanged: {
1860 -- if (totalCount > 0) {
1861 -- state = "new-notifications"
1862 -- } else {
1863 -- state = "default"
1864 -- plasmoid.hidePopup()
1865 -- }
1866 --
1867 -- var data = new Object
1868 -- data["image"] = "preferences-desktop-notification"
1869 -- data["mainText"] = i18n("Notifications and Jobs")
1870 -- if (totalCount == 0) {
1871 -- data["subText"] = i18n("No notifications or jobs")
1872 -- } else if (!notifications.count) {
1873 -- data["subText"] = i18np("%1 running job", "%1 running jobs", jobs.count)
1874 -- } else if (!jobs.count) {
1875 -- data["subText"] = i18np("%1 notification", "%1 notifications", notifications.count)
1876 -- } else {
1877 -- data["subText"] = i18np("%1 running job", "%1 running jobs", jobs.count) + "<br/>" + i18np("%1 notification", "%1 notifications", notifications.count)
1878 -- }
1879 -- plasmoid.popupIconToolTip = data
1880 -- plasmoid.passivePopup = jobs.count != 0
1881 -- }
1882 --
1883 -- property Item notificationIcon
1884 --
1885 -- Component.onCompleted: {
1886 -- //plasmoid.popupIcon = QIcon("preferences-desktop-notification")
1887 -- plasmoid.aspectRatioMode = "ConstrainedSquare"
1888 -- plasmoid.status = PassiveStatus
1889 -- allApplications = new Object
1890 -- plasmoid.addEventListener('ConfigChanged', configChanged);
1891 -- configChanged()
1892 -- }
1893 --
1894 -- function configChanged()
1895 -- {
1896 -- showNotifications = plasmoid.readConfig("ShowNotifications")
1897 -- showJobs = plasmoid.readConfig("ShowJobs")
1898 -- }
1899 --
1900 -- KLocale.Locale {
1901 -- id: locale
1902 -- }
1903 --
1904 -- PlasmaCore.Svg {
1905 -- id: configIconsSvg
1906 -- imagePath: "widgets/configuration-icons"
1907 -- }
1908 --
1909 -- property Component compactRepresentation: Component {
1910 -- NotificationIcon {
1911 -- id: notificationIcon
1912 -- Component.onCompleted: notificationsApplet.notificationIcon = notificationIcon
1913 -- }
1914 -- }
1915 --
1916 -- hoverEnabled: !UiProperties.touchInput
1917 --
1918 -- PlasmaExtras.ScrollArea {
1919 -- id: mainScrollArea
1920 -- anchors.fill: parent
1921 -- implicitWidth: theme.defaultFont.mSize.width * 40
1922 -- implicitHeight: Math.min(theme.defaultFont.mSize.height * 40, Math.max(theme.defaultFont.mSize.height * 6, contentsColumn.height))
1923 -- state: ""
1924 --
1925 -- states: [
1926 -- State {
1927 -- name: "underMouse"
1928 -- when: notificationsApplet.containsMouse
1929 -- PropertyChanges {
1930 -- target: mainScrollArea
1931 -- implicitHeight: implicitHeight
1932 -- }
1933 -- },
1934 -- State {
1935 -- name: ""
1936 -- when: !notificationsApplet.containsMouse
1937 -- PropertyChanges {
1938 -- target: mainScrollArea
1939 -- implicitHeight: Math.min(theme.defaultFont.mSize.height * 40, Math.max(theme.defaultFont.mSize.height * 6, contentsColumn.height))
1940 -- }
1941 -- }
1942 -- ]
1943 --
1944 -- Flickable {
1945 -- id: popupFlickable
1946 -- anchors.fill:parent
1947 --
1948 -- contentWidth: width
1949 -- contentHeight: contentsColumn.height
1950 -- clip: true
1951 --
1952 -- Column {
1953 -- id: contentsColumn
1954 -- width: popupFlickable.width
1955 --
1956 -- //TODO: load those on demand based on configuration
1957 -- Loader {
1958 -- id: jobsLoader
1959 -- source: showJobs ? "Jobs.qml" : ""
1960 -- anchors {
1961 -- left: parent.left
1962 -- right: parent.right
1963 -- }
1964 -- }
1965 -- Loader {
1966 -- id: notificationsLoader
1967 -- source: showNotifications ? "Notifications.qml" : ""
1968 -- anchors {
1969 -- left: parent.left
1970 -- right: parent.right
1971 -- }
1972 -- }
1973 -- }
1974 -- }
1975 -- }
1976 --}
1977 -diff --git a/plasma/generic/applets/notifications/contents/ui/uiproperties.js b/plasma/generic/applets/notifications/contents/ui/uiproperties.js
1978 -deleted file mode 100644
1979 -index efad371..0000000
1980 ---- a/plasma/generic/applets/notifications/contents/ui/uiproperties.js
1981 -+++ /dev/null
1982 -@@ -1,23 +0,0 @@
1983 --/*
1984 -- * Copyright 2012 Marco Martin <notmart@×××××.com>
1985 -- *
1986 -- * This program is free software; you can redistribute it and/or modify
1987 -- * it under the terms of the GNU Library General Public License as
1988 -- * published by the Free Software Foundation; either version 2, or
1989 -- * (at your option) any later version.
1990 -- *
1991 -- * This program is distributed in the hope that it will be useful,
1992 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1993 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1994 -- * GNU Library General Public License for more details
1995 -- *
1996 -- * You should have received a copy of the GNU Library General Public
1997 -- * License along with this program; if not, write to the
1998 -- * Free Software Foundation, Inc.,
1999 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2000 -- */
2001 --
2002 --
2003 --var toolIconSize = theme.smallMediumIconSize
2004 --var layoutSpacing = 4
2005 --var touchInput = false
2006 -diff --git a/plasma/generic/applets/notifications/core/completedjobnotification.cpp b/plasma/generic/applets/notifications/core/completedjobnotification.cpp
2007 -new file mode 100644
2008 -index 0000000..9a08390
2009 ---- /dev/null
2010 -+++ b/plasma/generic/applets/notifications/core/completedjobnotification.cpp
2011 -@@ -0,0 +1,99 @@
2012 -+/***************************************************************************
2013 -+ * completedjobnotification.h *
2014 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
2015 -+ * *
2016 -+ * This program is free software; you can redistribute it and/or modify *
2017 -+ * it under the terms of the GNU General Public License as published by *
2018 -+ * the Free Software Foundation; either version 2 of the License, or *
2019 -+ * (at your option) any later version. *
2020 -+ * *
2021 -+ * This program is distributed in the hope that it will be useful, *
2022 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2023 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2024 -+ * GNU General Public License for more details. *
2025 -+ * *
2026 -+ * You should have received a copy of the GNU General Public License *
2027 -+ * along with this program; if not, write to the *
2028 -+ * Free Software Foundation, Inc., *
2029 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
2030 -+ ***************************************************************************/
2031 -+
2032 -+#include "completedjobnotification.h"
2033 -+#include "job.h"
2034 -+
2035 -+#include <QProcess>
2036 -+
2037 -+#include <KIcon>
2038 -+#include <KLocale>
2039 -+#include <KDebug>
2040 -+
2041 -+
2042 -+static const int completedJobExpireDelay = 60 * 1000;
2043 -+static const int completedShortJobExpireDelay = 8 * 1000;
2044 -+static const uint shortJobsLength = 30 * 1000;
2045 -+
2046 -+CompletedJobNotification::CompletedJobNotification(QObject *parent)
2047 -+ : Notification(parent)
2048 -+{
2049 -+}
2050 -+
2051 -+CompletedJobNotification::~CompletedJobNotification()
2052 -+{
2053 -+}
2054 -+
2055 -+void CompletedJobNotification::setJob(Job *job)
2056 -+{
2057 -+ setApplicationName(job->applicationName());
2058 -+ setApplicationIcon(KIcon(job->applicationIconName()));
2059 -+ setSummary(i18n("%1 [Finished]", job->message()));
2060 -+
2061 -+ if (job->error().isEmpty()) {
2062 -+ setMessage(job->completedMessage());
2063 -+ } else {
2064 -+ setMessage(job->error());
2065 -+ }
2066 -+
2067 -+ if (job->elapsed() < shortJobsLength) {
2068 -+ setTimeout(completedShortJobExpireDelay);
2069 -+ } else {
2070 -+ setTimeout(completedJobExpireDelay);
2071 -+ }
2072 -+
2073 -+ if (job->destination().isValid()) {
2074 -+ QHash<QString, QString> actions;
2075 -+ actions.insert("open", i18n("Open"));
2076 -+ setActions(actions);
2077 -+ setActionOrder(QStringList()<<"open");
2078 -+
2079 -+ // create location url as is done in job->completedMessage()
2080 -+ KUrl location(job->destination());
2081 -+ if (job->totalAmounts().value("files") > 1) {
2082 -+ location.setFileName(QString());
2083 -+ }
2084 -+
2085 -+ m_destinationPrettyUrl = location.prettyUrl();
2086 -+ }
2087 -+
2088 -+ m_job = job;
2089 -+}
2090 -+
2091 -+void CompletedJobNotification::linkActivated(const QString &url)
2092 -+{
2093 -+ kDebug() << "open " << url;
2094 -+ QProcess::startDetached("kde-open", QStringList() << url);
2095 -+}
2096 -+
2097 -+Job *CompletedJobNotification::job() const
2098 -+{
2099 -+ return m_job;
2100 -+}
2101 -+
2102 -+void CompletedJobNotification::triggerAction(const QString &actionId)
2103 -+{
2104 -+ if (actionId == "open" && !m_destinationPrettyUrl.isNull()) {
2105 -+ linkActivated(m_destinationPrettyUrl);
2106 -+ }
2107 -+}
2108 -+
2109 -+
2110 -+#include "completedjobnotification.moc"
2111 -diff --git a/plasma/generic/applets/notifications/core/completedjobnotification.h b/plasma/generic/applets/notifications/core/completedjobnotification.h
2112 -new file mode 100644
2113 -index 0000000..b5e1f15
2114 ---- /dev/null
2115 -+++ b/plasma/generic/applets/notifications/core/completedjobnotification.h
2116 -@@ -0,0 +1,51 @@
2117 -+/***************************************************************************
2118 -+ * completedjobnotification.h *
2119 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
2120 -+ * *
2121 -+ * This program is free software; you can redistribute it and/or modify *
2122 -+ * it under the terms of the GNU General Public License as published by *
2123 -+ * the Free Software Foundation; either version 2 of the License, or *
2124 -+ * (at your option) any later version. *
2125 -+ * *
2126 -+ * This program is distributed in the hope that it will be useful, *
2127 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2128 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2129 -+ * GNU General Public License for more details. *
2130 -+ * *
2131 -+ * You should have received a copy of the GNU General Public License *
2132 -+ * along with this program; if not, write to the *
2133 -+ * Free Software Foundation, Inc., *
2134 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
2135 -+ ***************************************************************************/
2136 -+
2137 -+#ifndef COMPLETEDJOBNOTIFICATION_H
2138 -+#define COMPLETEDJOBNOTIFICATION_H
2139 -+
2140 -+#include "notification.h"
2141 -+
2142 -+
2143 -+class Job;
2144 -+
2145 -+class CompletedJobNotification : public Notification
2146 -+{
2147 -+ Q_OBJECT
2148 -+
2149 -+public:
2150 -+ CompletedJobNotification(QObject *parent = 0);
2151 -+ virtual ~CompletedJobNotification();
2152 -+
2153 -+ void setJob(Job *job);
2154 -+ Job *job() const;
2155 -+
2156 -+public Q_SLOTS:
2157 -+ void linkActivated(const QString &link);
2158 -+ void triggerAction(const QString &actionId);
2159 -+
2160 -+private:
2161 -+ Job *m_job;
2162 -+ QString m_destinationPrettyUrl;
2163 -+};
2164 -+
2165 -+
2166 -+#endif
2167 -+
2168 -diff --git a/plasma/generic/applets/notifications/core/job.cpp b/plasma/generic/applets/notifications/core/job.cpp
2169 -new file mode 100644
2170 -index 0000000..77ea03f
2171 ---- /dev/null
2172 -+++ b/plasma/generic/applets/notifications/core/job.cpp
2173 -@@ -0,0 +1,360 @@
2174 -+/***************************************************************************
2175 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
2176 -+ * *
2177 -+ * This program is free software; you can redistribute it and/or modify *
2178 -+ * it under the terms of the GNU General Public License as published by *
2179 -+ * the Free Software Foundation; either version 2 of the License, or *
2180 -+ * (at your option) any later version. *
2181 -+ * *
2182 -+ * This program is distributed in the hope that it will be useful, *
2183 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2184 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2185 -+ * GNU General Public License for more details. *
2186 -+ * *
2187 -+ * You should have received a copy of the GNU General Public License *
2188 -+ * along with this program; if not, write to the *
2189 -+ * Free Software Foundation, Inc., *
2190 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
2191 -+ ***************************************************************************/
2192 -+
2193 -+#include "job.h"
2194 -+
2195 -+#include <QtCore/QTimer>
2196 -+#include <QtCore/QTime>
2197 -+#include <QTextDocument>
2198 -+#include <QFontMetrics>
2199 -+#include <QApplication>
2200 -+
2201 -+#include <KDebug>
2202 -+#include <KUrl>
2203 -+#include <KLocalizedString>
2204 -+
2205 -+
2206 -+class Job::Private
2207 -+{
2208 -+public:
2209 -+ Private() :
2210 -+ numericSpeed(0),
2211 -+ finalElapsed(0),
2212 -+ state(Running),
2213 -+ percentage(0),
2214 -+ eta(0),
2215 -+ timerId(0),
2216 -+ killable(false),
2217 -+ suspendable(false),
2218 -+ shown(false)
2219 -+ {
2220 -+ }
2221 -+
2222 -+ QString applicationName;
2223 -+ QString applicationIconName;
2224 -+ QString message;
2225 -+ QString error;
2226 -+ QString speed;
2227 -+ QString destination;
2228 -+ qlonglong numericSpeed;
2229 -+
2230 -+
2231 -+ QMap<QString, qlonglong> totalAmounts;
2232 -+ QMap<QString, qlonglong> processedAmounts;
2233 -+
2234 -+ QList<QPair<QString, QString> > labels;
2235 -+
2236 -+ QTime elapsed;
2237 -+ uint finalElapsed;
2238 -+
2239 -+ State state;
2240 -+ uint percentage;
2241 -+ uint eta;
2242 -+ int timerId;
2243 -+
2244 -+ bool killable : 1;
2245 -+ bool suspendable : 1;
2246 -+ bool shown : 1;
2247 -+};
2248 -+
2249 -+Job::Job(QObject *parent)
2250 -+ : QObject(parent),
2251 -+ d(new Private)
2252 -+{
2253 -+ //delay a little the job to avoid the user to be distracted with short ones
2254 -+ QTimer::singleShot(1500, this, SLOT(show()));
2255 -+ d->elapsed.restart();
2256 -+}
2257 -+
2258 -+Job::~Job()
2259 -+{
2260 -+ delete d;
2261 -+}
2262 -+
2263 -+void Job::destroy()
2264 -+{
2265 -+ emit destroyed(this);
2266 -+ deleteLater();
2267 -+}
2268 -+
2269 -+QString Job::applicationName() const
2270 -+{
2271 -+ return d->applicationName;
2272 -+}
2273 -+
2274 -+void Job::setApplicationName(const QString &applicationName)
2275 -+{
2276 -+ if (d->applicationName != applicationName) {
2277 -+ d->applicationName = applicationName;
2278 -+ scheduleChangedSignal();
2279 -+ }
2280 -+}
2281 -+
2282 -+QString Job::applicationIconName() const
2283 -+{
2284 -+ return d->applicationIconName;
2285 -+}
2286 -+
2287 -+void Job::setApplicationIconName(const QString &applicationIcon)
2288 -+{
2289 -+ if (d->applicationIconName != applicationIcon) {
2290 -+ d->applicationIconName = applicationIcon;
2291 -+ scheduleChangedSignal();
2292 -+ }
2293 -+}
2294 -+
2295 -+QString Job::message() const
2296 -+{
2297 -+ return d->message;
2298 -+}
2299 -+
2300 -+void Job::setMessage(const QString &message)
2301 -+{
2302 -+ if (d->message != message) {
2303 -+ d->message = message;
2304 -+ scheduleChangedSignal();
2305 -+ }
2306 -+}
2307 -+
2308 -+QString Job::error() const
2309 -+{
2310 -+ return d->error;
2311 -+}
2312 -+
2313 -+void Job::setError(const QString &error)
2314 -+{
2315 -+ if (d->error != error) {
2316 -+ d->error = error;
2317 -+ scheduleChangedSignal();
2318 -+ }
2319 -+}
2320 -+
2321 -+QString Job::speed() const
2322 -+{
2323 -+ return d->speed;
2324 -+}
2325 -+
2326 -+void Job::setSpeed(const QString &speed)
2327 -+{
2328 -+ if (d->speed != speed) {
2329 -+ d->speed = speed;
2330 -+ scheduleChangedSignal();
2331 -+ }
2332 -+}
2333 -+
2334 -+qlonglong Job::numericSpeed() const
2335 -+{
2336 -+ return d->numericSpeed;
2337 -+}
2338 -+
2339 -+void Job::setNumericSpeed(const qlonglong speed)
2340 -+{
2341 -+ if (d->numericSpeed != speed) {
2342 -+ d->numericSpeed = speed;
2343 -+ scheduleChangedSignal();
2344 -+ }
2345 -+}
2346 -+
2347 -+QString Job::completedMessage() const
2348 -+{
2349 -+ KUrl location(d->destination);
2350 -+ if (location.isValid()) {
2351 -+ if (totalAmounts().value("files") > 1) {
2352 -+ location.setFileName(QString());
2353 -+ }
2354 -+
2355 -+ QString destinationString;
2356 -+ if (location.isLocalFile()) {
2357 -+ destinationString = location.toLocalFile();
2358 -+ } else {
2359 -+ destinationString = location.prettyUrl();
2360 -+ }
2361 -+
2362 -+ //FIXME: this is visualization stuff, but putting html here is not so model as well
2363 -+
2364 -+ kDebug() << "href = " << location.url();
2365 -+ QString destinationLink = QString("<a href=\"%1\">%2</a>").arg(location.url())
2366 -+ .arg(Qt::escape(destinationString));
2367 -+
2368 -+ if (totalAmounts().value("files") > 1) {
2369 -+ return i18np("%1 file, to: %2", "%1 files, to: %2", totalAmounts().value("files"),
2370 -+ destinationLink);
2371 -+ } else {
2372 -+ return destinationLink;
2373 -+ }
2374 -+ } else {
2375 -+ return QString("%1: %2").arg(labels().value(0).first).arg(labels().value(0).second);
2376 -+ }
2377 -+}
2378 -+
2379 -+KUrl Job::destination() const
2380 -+{
2381 -+ return d->destination;
2382 -+}
2383 -+
2384 -+ulong Job::eta() const
2385 -+{
2386 -+ return d->eta;
2387 -+}
2388 -+
2389 -+void Job::setEta(ulong eta)
2390 -+{
2391 -+ d->eta = eta;
2392 -+}
2393 -+
2394 -+QMap<QString, qlonglong> Job::totalAmounts() const
2395 -+{
2396 -+ return d->totalAmounts;
2397 -+}
2398 -+
2399 -+void Job::setTotalAmounts(QMap<QString, qlonglong> amounts)
2400 -+{
2401 -+ d->totalAmounts = amounts;
2402 -+ scheduleChangedSignal();
2403 -+}
2404 -+
2405 -+QMap<QString, qlonglong> Job::processedAmounts() const
2406 -+{
2407 -+ return d->processedAmounts;
2408 -+}
2409 -+
2410 -+void Job::setProcessedAmounts(QMap<QString, qlonglong> amounts)
2411 -+{
2412 -+ d->processedAmounts = amounts;
2413 -+ scheduleChangedSignal();
2414 -+}
2415 -+
2416 -+Job::State Job::state() const
2417 -+{
2418 -+ return d->state;
2419 -+}
2420 -+
2421 -+void Job::setState(State state)
2422 -+{
2423 -+ if (d->state != state) {
2424 -+ d->state = state;
2425 -+ show();
2426 -+ if (state == Stopped) {
2427 -+ d->finalElapsed = d->elapsed.elapsed();
2428 -+ }
2429 -+ emit stateChanged(this);
2430 -+ }
2431 -+}
2432 -+
2433 -+QList<QPair<QString, QString> > Job::labels() const
2434 -+{
2435 -+ return d->labels;
2436 -+}
2437 -+
2438 -+void Job::setLabels(QList<QPair<QString, QString> > labels)
2439 -+{
2440 -+ d->labels = labels;
2441 -+ if (d->labels.count() > 1 && d->destination.isEmpty()) {
2442 -+ d->destination = d->labels.value(1).second;
2443 -+ }
2444 -+ scheduleChangedSignal();
2445 -+}
2446 -+
2447 -+uint Job::percentage() const
2448 -+{
2449 -+ return d->percentage;
2450 -+}
2451 -+
2452 -+void Job::setPercentage(uint percentage)
2453 -+{
2454 -+ if (d->percentage != percentage) {
2455 -+ d->percentage = percentage;
2456 -+ scheduleChangedSignal();
2457 -+ }
2458 -+}
2459 -+
2460 -+uint Job::elapsed() const
2461 -+{
2462 -+ if (d->finalElapsed) {
2463 -+ return d->finalElapsed;
2464 -+ } else {
2465 -+ return d->elapsed.elapsed();
2466 -+ }
2467 -+}
2468 -+
2469 -+bool Job::isSuspendable() const
2470 -+{
2471 -+ return d->suspendable;
2472 -+}
2473 -+
2474 -+void Job::setSuspendable(bool suspendable)
2475 -+{
2476 -+ if (d->suspendable != suspendable) {
2477 -+ d->suspendable = suspendable;
2478 -+ scheduleChangedSignal();
2479 -+ }
2480 -+}
2481 -+
2482 -+bool Job::isKillable() const
2483 -+{
2484 -+ return d->killable;
2485 -+}
2486 -+
2487 -+void Job::setKillable(bool killable)
2488 -+{
2489 -+ if (d->killable != killable) {
2490 -+ d->killable = killable;
2491 -+ scheduleChangedSignal();
2492 -+ }
2493 -+}
2494 -+
2495 -+void Job::suspend()
2496 -+{
2497 -+ kWarning() << "Suspend is not implemented in this job provider.";
2498 -+}
2499 -+
2500 -+void Job::resume()
2501 -+{
2502 -+ kWarning() << "Resume is not implemented in this job provider.";
2503 -+}
2504 -+
2505 -+void Job::stop()
2506 -+{
2507 -+ kWarning() << "Stop is not implemented in this job provider.";
2508 -+}
2509 -+
2510 -+void Job::show()
2511 -+{
2512 -+ if (state() == Job::Running && !d->shown) {
2513 -+ d->shown = true;
2514 -+ emit ready(this);
2515 -+ }
2516 -+}
2517 -+
2518 -+void Job::scheduleChangedSignal()
2519 -+{
2520 -+ if (d->shown && !d->timerId) {
2521 -+ d->timerId = startTimer(0);
2522 -+ }
2523 -+}
2524 -+
2525 -+void Job::timerEvent(QTimerEvent *)
2526 -+{
2527 -+ killTimer(d->timerId);
2528 -+ d->timerId = 0;
2529 -+ emit changed(this);
2530 -+}
2531 -+
2532 -+
2533 -+#include "job.moc"
2534 -diff --git a/plasma/generic/applets/notifications/core/job.h b/plasma/generic/applets/notifications/core/job.h
2535 -new file mode 100644
2536 -index 0000000..3d2984d
2537 ---- /dev/null
2538 -+++ b/plasma/generic/applets/notifications/core/job.h
2539 -@@ -0,0 +1,188 @@
2540 -+/***************************************************************************
2541 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
2542 -+ * *
2543 -+ * This program is free software; you can redistribute it and/or modify *
2544 -+ * it under the terms of the GNU General Public License as published by *
2545 -+ * the Free Software Foundation; either version 2 of the License, or *
2546 -+ * (at your option) any later version. *
2547 -+ * *
2548 -+ * This program is distributed in the hope that it will be useful, *
2549 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2550 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2551 -+ * GNU General Public License for more details. *
2552 -+ * *
2553 -+ * You should have received a copy of the GNU General Public License *
2554 -+ * along with this program; if not, write to the *
2555 -+ * Free Software Foundation, Inc., *
2556 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
2557 -+ ***************************************************************************/
2558 -+
2559 -+#ifndef JOB_H
2560 -+#define JOB_H
2561 -+
2562 -+#include <QtCore/QHash>
2563 -+#include <QtCore/QObject>
2564 -+
2565 -+#include <KUrl>
2566 -+
2567 -+
2568 -+class Job : public QObject
2569 -+{
2570 -+ Q_OBJECT
2571 -+
2572 -+public:
2573 -+ enum State {
2574 -+ Running = 0,
2575 -+ Suspended = 1,
2576 -+ Stopped = 2
2577 -+ };
2578 -+
2579 -+ Job(QObject *parent = 0);
2580 -+ virtual ~Job();
2581 -+
2582 -+ /**
2583 -+ * Request and signal destruction of this object
2584 -+ */
2585 -+ void destroy();
2586 -+
2587 -+ /**
2588 -+ * @return the name of the application which started this job.
2589 -+ */
2590 -+ QString applicationName() const;
2591 -+
2592 -+ /**
2593 -+ * @return the name of the icon to be used for this job.
2594 -+ */
2595 -+ QString applicationIconName() const;
2596 -+
2597 -+ /**
2598 -+ * @return the descripion of the activity that is performed.
2599 -+ */
2600 -+ QString message() const;
2601 -+
2602 -+ /**
2603 -+ * @return the errormessage if an error has occurred.
2604 -+ */
2605 -+ QString error() const;
2606 -+
2607 -+ /**
2608 -+ * @return the (human readable) speed at which the jobs is progressing.
2609 -+ */
2610 -+ QString speed() const;
2611 -+
2612 -+ /**
2613 -+ * @return the (in bytes per second) speed at which the jobs is progressing.
2614 -+ */
2615 -+ qlonglong numericSpeed() const;
2616 -+
2617 -+ /**
2618 -+ * @return a nice description of the job that has been completed.
2619 -+ */
2620 -+ QString completedMessage() const;
2621 -+
2622 -+ /**
2623 -+ * @return the time (in seconds) in which this job is expected to complete.
2624 -+ */
2625 -+ ulong eta() const;
2626 -+
2627 -+ void setEta(ulong eta);
2628 -+
2629 -+ QMap<QString, qlonglong> totalAmounts() const;
2630 -+
2631 -+ QMap<QString, qlonglong> processedAmounts() const;
2632 -+
2633 -+ /**
2634 -+ * @return a list of pairs containing label names/values in the order they should be displayed.
2635 -+ */
2636 -+ QList<QPair<QString, QString> > labels() const;
2637 -+
2638 -+ /**
2639 -+ * @return the state this job is in.
2640 -+ */
2641 -+ State state() const;
2642 -+
2643 -+ bool isSuspendable() const;
2644 -+
2645 -+ bool isKillable() const;
2646 -+
2647 -+ /**
2648 -+ * @retun the percentage of the job that has been completed.
2649 -+ */
2650 -+ uint percentage() const;
2651 -+
2652 -+ /**
2653 -+ * total elapsed job time
2654 -+ */
2655 -+ uint elapsed() const;
2656 -+
2657 -+ /**
2658 -+ * Destination url
2659 -+ */
2660 -+ KUrl destination() const;
2661 -+
2662 -+public slots:
2663 -+ /**
2664 -+ * suspend this job.
2665 -+ */
2666 -+ virtual void suspend();
2667 -+
2668 -+ /**
2669 -+ * resume this job.
2670 -+ */
2671 -+ virtual void resume();
2672 -+
2673 -+ /**
2674 -+ * stop this job.
2675 -+ */
2676 -+ virtual void stop();
2677 -+
2678 -+signals:
2679 -+ /**
2680 -+ * Emitted when the job is ready to be shown
2681 -+ */
2682 -+ void ready(Job *job);
2683 -+
2684 -+ /**
2685 -+ * Emitted when the job changes state
2686 -+ */
2687 -+ void stateChanged(Job *job);
2688 -+
2689 -+ /**
2690 -+ * Emitted when the job details change
2691 -+ */
2692 -+ void changed(Job *job);
2693 -+
2694 -+ /**
2695 -+ * Emitted when the job is about to be destroyed
2696 -+ **/
2697 -+ void destroyed(Job *job);
2698 -+
2699 -+protected:
2700 -+ void setApplicationName(const QString &applicationName);
2701 -+ void setApplicationIconName(const QString &applicationIcon);
2702 -+ void setMessage(const QString &message);
2703 -+ void setError(const QString &error);
2704 -+ void setSpeed(const QString &speed);
2705 -+ void setNumericSpeed(const qlonglong speed);
2706 -+ void setTotalAmounts(QMap<QString, qlonglong> amount);
2707 -+ void setProcessedAmounts(QMap<QString, qlonglong> amount);
2708 -+ void setState(State state);
2709 -+ void setSuspendable(bool suspendable);
2710 -+ void setKillable(bool killable);
2711 -+ void setPercentage(uint percentage);
2712 -+ void setLabels(QList<QPair<QString, QString> > labels);
2713 -+ void timerEvent(QTimerEvent *);
2714 -+
2715 -+private slots:
2716 -+ void show();
2717 -+
2718 -+private:
2719 -+ void scheduleChangedSignal();
2720 -+
2721 -+ class Private;
2722 -+ Private* const d;
2723 -+
2724 -+ friend class Manager;
2725 -+};
2726 -+
2727 -+#endif
2728 -diff --git a/plasma/generic/applets/notifications/core/notification.cpp b/plasma/generic/applets/notifications/core/notification.cpp
2729 -new file mode 100644
2730 -index 0000000..26833b6
2731 ---- /dev/null
2732 -+++ b/plasma/generic/applets/notifications/core/notification.cpp
2733 -@@ -0,0 +1,272 @@
2734 -+/***************************************************************************
2735 -+ * notification.cpp *
2736 -+ * *
2737 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
2738 -+ * *
2739 -+ * This program is free software; you can redistribute it and/or modify *
2740 -+ * it under the terms of the GNU General Public License as published by *
2741 -+ * the Free Software Foundation; either version 2 of the License, or *
2742 -+ * (at your option) any later version. *
2743 -+ * *
2744 -+ * This program is distributed in the hope that it will be useful, *
2745 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
2746 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
2747 -+ * GNU General Public License for more details. *
2748 -+ * *
2749 -+ * You should have received a copy of the GNU General Public License *
2750 -+ * along with this program; if not, write to the *
2751 -+ * Free Software Foundation, Inc., *
2752 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
2753 -+ ***************************************************************************/
2754 -+
2755 -+#include "notification.h"
2756 -+
2757 -+#include <QImage>
2758 -+#include <QtCore/QTimer>
2759 -+
2760 -+#include <KDebug>
2761 -+
2762 -+
2763 -+class Notification::Private
2764 -+{
2765 -+public:
2766 -+ Private()
2767 -+ : timeout(0),
2768 -+ urgency(0),
2769 -+ hideTimer(0),
2770 -+ expired(false),
2771 -+ read(false)
2772 -+ {
2773 -+ }
2774 -+
2775 -+ QString identifier;
2776 -+ QString applicationName;
2777 -+ QIcon applicationIcon;
2778 -+ QString message;
2779 -+ QString summary;
2780 -+ int timeout;
2781 -+ int urgency;
2782 -+ QImage image;
2783 -+ QTimer *deleteTimer;
2784 -+ QTimer *hideTimer;
2785 -+ bool expired;
2786 -+ bool read;
2787 -+
2788 -+ QHash<QString, QString> actions;
2789 -+ QStringList actionOrder;
2790 -+};
2791 -+
2792 -+Notification::Notification(QObject *parent)
2793 -+ : QObject(parent),
2794 -+ d(new Private)
2795 -+{
2796 -+ d->deleteTimer = new QTimer(this);
2797 -+ d->deleteTimer->setSingleShot(true);
2798 -+ connect(d->deleteTimer, SIGNAL(timeout()), this, SLOT(destroy()));
2799 -+}
2800 -+
2801 -+
2802 -+Notification::~Notification()
2803 -+{
2804 -+ emit notificationDestroyed(this);
2805 -+ delete d;
2806 -+}
2807 -+
2808 -+void Notification::destroy()
2809 -+{
2810 -+ emit notificationDestroyed(this);
2811 -+ deleteLater();
2812 -+}
2813 -+
2814 -+QString Notification::applicationName() const
2815 -+{
2816 -+ return d->applicationName;
2817 -+}
2818 -+
2819 -+
2820 -+void Notification::setApplicationName(const QString &applicationName)
2821 -+{
2822 -+ d->applicationName = applicationName;
2823 -+}
2824 -+
2825 -+
2826 -+QIcon Notification::applicationIcon() const
2827 -+{
2828 -+ return d->applicationIcon;
2829 -+}
2830 -+
2831 -+
2832 -+void Notification::setApplicationIcon(const QIcon &applicationIcon)
2833 -+{
2834 -+ d->applicationIcon = applicationIcon;
2835 -+}
2836 -+
2837 -+
2838 -+QString Notification::message() const
2839 -+{
2840 -+ return d->message;
2841 -+}
2842 -+
2843 -+
2844 -+void Notification::setMessage(const QString &message)
2845 -+{
2846 -+ d->message = message;
2847 -+}
2848 -+
2849 -+
2850 -+QString Notification::summary() const
2851 -+{
2852 -+ return d->summary;
2853 -+}
2854 -+
2855 -+
2856 -+void Notification::setSummary(const QString &summary)
2857 -+{
2858 -+ d->summary = summary;
2859 -+}
2860 -+
2861 -+
2862 -+int Notification::timeout() const
2863 -+{
2864 -+ return d->timeout;
2865 -+}
2866 -+
2867 -+QImage Notification::image() const
2868 -+{
2869 -+ return d->image;
2870 -+}
2871 -+
2872 -+void Notification::setImage(QImage image)
2873 -+{
2874 -+ d->image = image;
2875 -+}
2876 -+
2877 -+void Notification::setTimeout(int timeout)
2878 -+{
2879 -+ //show them at most 30 seconds
2880 -+ if (!timeout) {
2881 -+ d->timeout = 30 * 1000;
2882 -+ } else {
2883 -+ d->timeout = timeout;
2884 -+ }
2885 -+
2886 -+ if (d->urgency >= 2) {
2887 -+ return;
2888 -+ }
2889 -+
2890 -+ if (!d->hideTimer) {
2891 -+ d->hideTimer = new QTimer(this);
2892 -+ d->hideTimer->setSingleShot(true);
2893 -+ connect(d->hideTimer, SIGNAL(timeout()), this, SLOT(hide()));
2894 -+ }
2895 -+ d->hideTimer->start(d->timeout);
2896 -+}
2897 -+
2898 -+void Notification::setUrgency(int urgency)
2899 -+{
2900 -+ if (urgency != d->urgency) {
2901 -+ d->urgency = urgency;
2902 -+ if (urgency >= 2) {
2903 -+ if (d->hideTimer) {
2904 -+ d->hideTimer->stop();
2905 -+ }
2906 -+ d->deleteTimer->stop();
2907 -+ } else {
2908 -+ setTimeout(d->timeout);
2909 -+ }
2910 -+ }
2911 -+}
2912 -+
2913 -+int Notification::urgency() const
2914 -+{
2915 -+ return d->urgency;
2916 -+}
2917 -+
2918 -+QHash<QString, QString> Notification::actions() const
2919 -+{
2920 -+ return d->actions;
2921 -+}
2922 -+
2923 -+
2924 -+void Notification::setActions(const QHash<QString, QString> &actions)
2925 -+{
2926 -+ d->actions = actions;
2927 -+ emit changed(this);
2928 -+}
2929 -+
2930 -+
2931 -+QStringList Notification::actionOrder() const
2932 -+{
2933 -+ return d->actionOrder;
2934 -+}
2935 -+
2936 -+
2937 -+void Notification::setActionOrder(const QStringList &actionOrder)
2938 -+{
2939 -+ d->actionOrder = actionOrder;
2940 -+}
2941 -+
2942 -+
2943 -+void Notification::triggerAction(const QString &actionId)
2944 -+{
2945 -+ Q_UNUSED(actionId);
2946 -+ kDebug() << "action triggered but no handler implemented";
2947 -+}
2948 -+
2949 -+void Notification::remove()
2950 -+{
2951 -+ kDebug() << "remove requested but no handler implemented";
2952 -+}
2953 -+
2954 -+void Notification::linkActivated(const QString &link)
2955 -+{
2956 -+ Q_UNUSED(link)
2957 -+ kDebug() << "link activation requested but no handler implemented";
2958 -+}
2959 -+
2960 -+void Notification::hide()
2961 -+{
2962 -+ d->expired = true;
2963 -+ emit expired(this);
2964 -+}
2965 -+
2966 -+void Notification::startDeletionCountdown()
2967 -+{
2968 -+ if (d->urgency >= 2) {
2969 -+ return;
2970 -+ }
2971 -+
2972 -+ //keep it available for 10 minutes
2973 -+ d->deleteTimer->start(10*60*1000);
2974 -+}
2975 -+
2976 -+bool Notification::isExpired() const
2977 -+{
2978 -+ return d->expired;
2979 -+}
2980 -+
2981 -+void Notification::setRead(const bool read)
2982 -+{
2983 -+ d->read = read;
2984 -+}
2985 -+
2986 -+bool Notification::isRead() const
2987 -+{
2988 -+ return d->read;
2989 -+}
2990 -+
2991 -+void Notification::setDeleteTimeout(const int time)
2992 -+{
2993 -+ if (d->deleteTimer->interval() != time) {
2994 -+ d->deleteTimer->start(time);
2995 -+ }
2996 -+}
2997 -+
2998 -+int Notification::deleteTimeOut() const
2999 -+{
3000 -+ return d->deleteTimer->interval();
3001 -+}
3002 -+
3003 -+
3004 -+
3005 -+#include "notification.moc"
3006 -diff --git a/plasma/generic/applets/notifications/core/notification.h b/plasma/generic/applets/notifications/core/notification.h
3007 -new file mode 100644
3008 -index 0000000..e04fdba
3009 ---- /dev/null
3010 -+++ b/plasma/generic/applets/notifications/core/notification.h
3011 -@@ -0,0 +1,100 @@
3012 -+/***************************************************************************
3013 -+ * notification.h *
3014 -+ * *
3015 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
3016 -+ * *
3017 -+ * This program is free software; you can redistribute it and/or modify *
3018 -+ * it under the terms of the GNU General Public License as published by *
3019 -+ * the Free Software Foundation; either version 2 of the License, or *
3020 -+ * (at your option) any later version. *
3021 -+ * *
3022 -+ * This program is distributed in the hope that it will be useful, *
3023 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
3024 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
3025 -+ * GNU General Public License for more details. *
3026 -+ * *
3027 -+ * You should have received a copy of the GNU General Public License *
3028 -+ * along with this program; if not, write to the *
3029 -+ * Free Software Foundation, Inc., *
3030 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
3031 -+ ***************************************************************************/
3032 -+
3033 -+#ifndef NOTIFICATION_H
3034 -+#define NOTIFICATION_H
3035 -+
3036 -+#include <QImage>
3037 -+#include <QtCore/QHash>
3038 -+#include <QtCore/QObject>
3039 -+
3040 -+#include <QtGui/QIcon>
3041 -+
3042 -+
3043 -+
3044 -+class Notification : public QObject
3045 -+{
3046 -+ Q_OBJECT
3047 -+
3048 -+public:
3049 -+ Notification(QObject *parent = 0);
3050 -+ virtual ~Notification();
3051 -+
3052 -+ QString applicationName() const;
3053 -+ QIcon applicationIcon() const;
3054 -+ QString message() const;
3055 -+ QString summary() const;
3056 -+ int timeout() const;
3057 -+ QImage image() const;
3058 -+
3059 -+ void setUrgency(int urgency);
3060 -+ int urgency() const;
3061 -+
3062 -+ QHash<QString, QString> actions() const;
3063 -+ QStringList actionOrder() const;
3064 -+
3065 -+ bool isExpired() const;
3066 -+
3067 -+ void setRead(const bool read);
3068 -+ bool isRead() const;
3069 -+
3070 -+ void setDeleteTimeout(const int time);
3071 -+ int deleteTimeOut() const;
3072 -+
3073 -+public slots:
3074 -+ virtual void triggerAction(const QString &actionId);
3075 -+ virtual void remove();
3076 -+ virtual void linkActivated(const QString &link);
3077 -+ void startDeletionCountdown();
3078 -+ void hide();
3079 -+ void destroy();
3080 -+
3081 -+signals:
3082 -+ void changed(Notification *notification = 0);
3083 -+
3084 -+ /**
3085 -+ * Emitted when the notification is about to be destroyed
3086 -+ **/
3087 -+ void notificationDestroyed(Notification *notification = 0);
3088 -+
3089 -+ /**
3090 -+ * emitted when the notification wants to hide itself
3091 -+ */
3092 -+ void expired(Notification *notification = 0);
3093 -+
3094 -+protected:
3095 -+ void setApplicationName(const QString &applicationName);
3096 -+ void setApplicationIcon(const QIcon &applicationIcon);
3097 -+ void setMessage(const QString &message);
3098 -+ void setSummary(const QString &summary);
3099 -+ void setImage(QImage image);
3100 -+ void setTimeout(int timeout);
3101 -+ void setActions(const QHash<QString, QString> &actions);
3102 -+ void setActionOrder(const QStringList &actionOrder);
3103 -+
3104 -+private:
3105 -+ class Private;
3106 -+ Private* const d;
3107 -+};
3108 -+
3109 -+
3110 -+
3111 -+#endif
3112 -diff --git a/plasma/generic/applets/notifications/core/notificationsmanager.cpp b/plasma/generic/applets/notifications/core/notificationsmanager.cpp
3113 -new file mode 100644
3114 -index 0000000..6892361
3115 ---- /dev/null
3116 -+++ b/plasma/generic/applets/notifications/core/notificationsmanager.cpp
3117 -@@ -0,0 +1,245 @@
3118 -+/***************************************************************************
3119 -+ * manager.cpp *
3120 -+ * *
3121 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
3122 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
3123 -+ * *
3124 -+ * This program is free software; you can redistribute it and/or modify *
3125 -+ * it under the terms of the GNU General Public License as published by *
3126 -+ * the Free Software Foundation; either version 2 of the License, or *
3127 -+ * (at your option) any later version. *
3128 -+ * *
3129 -+ * This program is distributed in the hope that it will be useful, *
3130 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
3131 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
3132 -+ * GNU General Public License for more details. *
3133 -+ * *
3134 -+ * You should have received a copy of the GNU General Public License *
3135 -+ * along with this program; if not, write to the *
3136 -+ * Free Software Foundation, Inc., *
3137 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
3138 -+ ***************************************************************************/
3139 -+
3140 -+#include "notificationsmanager.h"
3141 -+
3142 -+#include <QTimer>
3143 -+
3144 -+#include <KGlobal>
3145 -+
3146 -+#include <plasma/applet.h>
3147 -+
3148 -+#include "job.h"
3149 -+#include "notification.h"
3150 -+#include "protocol.h"
3151 -+
3152 -+#include "../protocols/notifications/dbusnotificationprotocol.h"
3153 -+#include "../protocols/jobs/dbusjobprotocol.h"
3154 -+
3155 -+
3156 -+static const int idleCheckInterval = 60 * 1000;
3157 -+
3158 -+class Manager::Private
3159 -+{
3160 -+public:
3161 -+ Private(Manager *manager)
3162 -+ : q(manager),
3163 -+ jobTotals(new Job(manager)),
3164 -+ jobProtocol(0),
3165 -+ notificationProtocol(0)
3166 -+ {
3167 -+ }
3168 -+
3169 -+ void setupProtocol(Protocol *protocol);
3170 -+ void checkIdle();
3171 -+
3172 -+ Manager *q;
3173 -+ QList<Task *> tasks;
3174 -+ QList<Notification*> notifications;
3175 -+ QList<Job *> jobs;
3176 -+ Job *jobTotals;
3177 -+ Notifications *notificationsApplet;
3178 -+ Protocol *jobProtocol;
3179 -+ Protocol *notificationProtocol;
3180 -+ QTimer *idleTimer;
3181 -+ static const int s_notificationLimit = 15;
3182 -+};
3183 -+
3184 -+
3185 -+Manager::Manager(Notifications *parentApplet)
3186 -+ : QObject(parentApplet),
3187 -+ d(new Private(this))
3188 -+{
3189 -+ d->notificationsApplet = parentApplet;
3190 -+ d->idleTimer = new QTimer(this);
3191 -+ d->idleTimer->setSingleShot(false);
3192 -+ connect(d->idleTimer, SIGNAL(timeout()), this, SLOT(checkIdle()));
3193 -+}
3194 -+
3195 -+Manager::~Manager()
3196 -+{
3197 -+ delete d;
3198 -+}
3199 -+
3200 -+void Manager::registerNotificationProtocol()
3201 -+{
3202 -+ if (!d->notificationProtocol) {
3203 -+ d->notificationProtocol = new DBusNotificationProtocol(this);
3204 -+ d->setupProtocol(d->notificationProtocol);
3205 -+ }
3206 -+}
3207 -+
3208 -+void Manager::unregisterNotificationProtocol()
3209 -+{
3210 -+ delete d->notificationProtocol;
3211 -+ d->notificationProtocol = 0;
3212 -+}
3213 -+
3214 -+void Manager::addNotification(Notification* notification)
3215 -+{
3216 -+ connect(notification, SIGNAL(notificationDestroyed(Notification*)),
3217 -+ this, SLOT(removeNotification(Notification*)));
3218 -+ connect(notification, SIGNAL(changed(Notification*)),
3219 -+ this, SIGNAL(notificationChanged(Notification*)));
3220 -+ connect(notification, SIGNAL(expired(Notification*)),
3221 -+ this, SIGNAL(notificationExpired(Notification*)));
3222 -+
3223 -+ d->notifications.append(notification);
3224 -+
3225 -+ if (!d->idleTimer->isActive()) {
3226 -+ d->idleTimer->start(idleCheckInterval);
3227 -+ }
3228 -+ connect(this, SIGNAL(idleTerminated()), notification, SLOT(startDeletionCountdown()));
3229 -+
3230 -+ emit notificationAdded(notification);
3231 -+
3232 -+ if (d->notifications.count() > d->s_notificationLimit) {
3233 -+ Notification *notification = d->notifications.first();
3234 -+ d->notifications.pop_front();
3235 -+ notification->deleteLater();
3236 -+ }
3237 -+}
3238 -+
3239 -+void Manager::removeNotification(Notification *notification)
3240 -+{
3241 -+ d->notifications.removeAll(notification);
3242 -+ disconnect(notification, 0, this, 0);
3243 -+ disconnect(this, 0, notification, 0);
3244 -+
3245 -+ if (d->notifications.isEmpty()) {
3246 -+ d->idleTimer->stop();
3247 -+ }
3248 -+
3249 -+ emit notificationRemoved(notification);
3250 -+}
3251 -+
3252 -+QList<Notification*> Manager::notifications() const
3253 -+{
3254 -+ return d->notifications;
3255 -+}
3256 -+
3257 -+void Manager::clearNotifications()
3258 -+{
3259 -+ qDeleteAll(d->notifications);
3260 -+ d->notifications.clear();
3261 -+}
3262 -+
3263 -+void Manager::registerJobProtocol()
3264 -+{
3265 -+ if (!d->jobProtocol) {
3266 -+ d->jobProtocol = new DBusJobProtocol(this);
3267 -+ d->setupProtocol(d->jobProtocol);
3268 -+ }
3269 -+}
3270 -+
3271 -+void Manager::unregisterJobProtocol()
3272 -+{
3273 -+ delete d->jobProtocol;
3274 -+ d->jobProtocol = 0;
3275 -+}
3276 -+
3277 -+void Manager::addJob(Job *job)
3278 -+{
3279 -+ connect(job, SIGNAL(destroyed(Job*)), this, SLOT(removeJob(Job*)));
3280 -+ connect(job, SIGNAL(changed(Job*)), this, SIGNAL(jobChanged(Job*)));
3281 -+ connect(job, SIGNAL(stateChanged(Job*)), this, SIGNAL(jobStateChanged(Job*)));
3282 -+ connect(job, SIGNAL(changed(Job*)), this, SLOT(updateTotals()));
3283 -+
3284 -+ d->jobs.append(job);
3285 -+ emit jobAdded(job);
3286 -+}
3287 -+
3288 -+void Manager::removeJob(Job *job)
3289 -+{
3290 -+ d->jobs.removeAll(job);
3291 -+ disconnect(job);
3292 -+ updateTotals();
3293 -+ emit jobRemoved(job);
3294 -+}
3295 -+
3296 -+void Manager::updateTotals()
3297 -+{
3298 -+ uint totalPercent = 0;
3299 -+ ulong totalEta = 0;
3300 -+ foreach (Job *job, d->jobs) {
3301 -+ totalPercent += job->percentage();
3302 -+ if (job->eta() > totalEta) {
3303 -+ totalEta = job->eta();
3304 -+ }
3305 -+ }
3306 -+
3307 -+ if (d->jobs.count() > 0) {
3308 -+ d->jobTotals->setPercentage(totalPercent / d->jobs.count());
3309 -+ d->jobTotals->setMessage(i18np("1 running job (%2 remaining)", "%1 running jobs (%2 remaining)",
3310 -+ d->jobs.count(),
3311 -+ KGlobal::locale()->prettyFormatDuration(totalEta)));
3312 -+ } else {
3313 -+ d->jobTotals->setPercentage(0);
3314 -+ d->jobTotals->setMessage(i18n("no running jobs"));
3315 -+ }
3316 -+ //TODO: set a sensible icon
3317 -+}
3318 -+
3319 -+Job *Manager::jobTotals() const
3320 -+{
3321 -+ return d->jobTotals;
3322 -+}
3323 -+
3324 -+QList<Job*> Manager::jobs() const
3325 -+{
3326 -+ return d->jobs;
3327 -+}
3328 -+
3329 -+void Manager::checkIdle()
3330 -+{
3331 -+ int totalIdle;
3332 -+#ifdef HAVE_LIBXSS // Idle detection.
3333 -+ XScreenSaverInfo* _mit_info;
3334 -+ _mit_info = XScreenSaverAllocInfo();
3335 -+ XScreenSaverQueryInfo( QX11Info::display(), QX11Info::appRootWindow(), _mit_info );
3336 -+ totalIdle = _mit_info->idle;
3337 -+ XFree( _mit_info );
3338 -+#else
3339 -+ totalIdle = 0;
3340 -+#endif // HAVE_LIBXSS
3341 -+
3342 -+ if (totalIdle < idleCheckInterval) {
3343 -+ d->idleTimer->stop();
3344 -+ emit idleTerminated();
3345 -+ }
3346 -+}
3347 -+
3348 -+void Manager::Private::setupProtocol(Protocol *protocol)
3349 -+{
3350 -+ connect(protocol, SIGNAL(jobCreated(Job*)), q, SLOT(addJob(Job*)));
3351 -+ connect(protocol, SIGNAL(notificationCreated(Notification*)),
3352 -+ q, SLOT(addNotification(Notification*)));
3353 -+ protocol->init();
3354 -+}
3355 -+
3356 -+Notifications *Manager::applet() const
3357 -+{
3358 -+ return d->notificationsApplet;
3359 -+}
3360 -+
3361 -+
3362 -+#include "notificationsmanager.moc"
3363 -diff --git a/plasma/generic/applets/notifications/core/notificationsmanager.h b/plasma/generic/applets/notifications/core/notificationsmanager.h
3364 -new file mode 100644
3365 -index 0000000..a6d6639
3366 ---- /dev/null
3367 -+++ b/plasma/generic/applets/notifications/core/notificationsmanager.h
3368 -@@ -0,0 +1,161 @@
3369 -+/***************************************************************************
3370 -+ * manager.h *
3371 -+ * *
3372 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
3373 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
3374 -+ * *
3375 -+ * This program is free software; you can redistribute it and/or modify *
3376 -+ * it under the terms of the GNU General Public License as published by *
3377 -+ * the Free Software Foundation; either version 2 of the License, or *
3378 -+ * (at your option) any later version. *
3379 -+ * *
3380 -+ * This program is distributed in the hope that it will be useful, *
3381 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
3382 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
3383 -+ * GNU General Public License for more details. *
3384 -+ * *
3385 -+ * You should have received a copy of the GNU General Public License *
3386 -+ * along with this program; if not, write to the *
3387 -+ * Free Software Foundation, Inc., *
3388 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
3389 -+ ***************************************************************************/
3390 -+
3391 -+#ifndef NOTIFICATIONSMANAGER_H
3392 -+#define NOTIFICATIONSMANAGER_H
3393 -+
3394 -+#include <QtCore/QObject>
3395 -+
3396 -+#include <KConfigGroup>
3397 -+
3398 -+#include <plasma/plasma.h>
3399 -+#include "../ui/notifications.h"
3400 -+
3401 -+
3402 -+namespace Plasma
3403 -+{
3404 -+class Applet;
3405 -+}
3406 -+
3407 -+class Notifications;
3408 -+class Notification;
3409 -+class Task;
3410 -+class Job;
3411 -+
3412 -+/**
3413 -+ * w
3414 -+ * @short Creator and amalgamator of the supported system tray specifications
3415 -+ **/
3416 -+class Manager : public QObject
3417 -+{
3418 -+ Q_OBJECT
3419 -+
3420 -+public:
3421 -+ Manager(Notifications *parentApplet);
3422 -+ ~Manager();
3423 -+
3424 -+ /**
3425 -+ * @return a list of all known Notification instances
3426 -+ **/
3427 -+ QList<Notification*> notifications() const;
3428 -+
3429 -+ /**
3430 -+ * clear all notifications
3431 -+ */
3432 -+ void clearNotifications();
3433 -+
3434 -+ /**
3435 -+ * @return a list of all known Job instances
3436 -+ **/
3437 -+ QList<Job*> jobs() const;
3438 -+
3439 -+ /**
3440 -+ * @return a Job instance that can be used to monitor total progress
3441 -+ **/
3442 -+ Job *jobTotals() const;
3443 -+
3444 -+ /**
3445 -+ * Integrates the Job progress info into the applet's notification system
3446 -+ **/
3447 -+ void registerJobProtocol();
3448 -+
3449 -+ /**
3450 -+ * Iintegrates the notifications into the applet's notification system
3451 -+ **/
3452 -+ void registerNotificationProtocol();
3453 -+
3454 -+ /**
3455 -+ * Removes the Job progress info from the applet's notification system
3456 -+ **/
3457 -+ void unregisterJobProtocol();
3458 -+
3459 -+ /**
3460 -+ * Removes the notifications from the applet's notification system
3461 -+ **/
3462 -+ void unregisterNotificationProtocol();
3463 -+
3464 -+ Notifications *applet() const;
3465 -+
3466 -+signals:
3467 -+ /**
3468 -+ * Emitted when a new notification has been added
3469 -+ **/
3470 -+ void notificationAdded(Notification *notification);
3471 -+
3472 -+ /**
3473 -+ * Emitted when something about a notification changes
3474 -+ **/
3475 -+ void notificationChanged(Notification *notification);
3476 -+
3477 -+ /**
3478 -+ * The notification is expired and wants to hide itself
3479 -+ */
3480 -+ void notificationExpired(Notification *notification);
3481 -+
3482 -+ /**
3483 -+ * Emitted when a notification has been removed
3484 -+ **/
3485 -+ void notificationRemoved(Notification *notification);
3486 -+
3487 -+ /**
3488 -+ * Emitted when a new job has been added
3489 -+ **/
3490 -+ void jobAdded(Job *job);
3491 -+
3492 -+ /**
3493 -+ * Emitted when the state of a job changes
3494 -+ **/
3495 -+ void jobStateChanged(Job *job);
3496 -+
3497 -+ /**
3498 -+ * Emitted when something about a job changes
3499 -+ **/
3500 -+ void jobChanged(Job *job);
3501 -+
3502 -+ /**
3503 -+ * Emitted when a job has been removed
3504 -+ **/
3505 -+ void jobRemoved(Job *job);
3506 -+
3507 -+ /**
3508 -+ * the pc is out of idle and is starting being used
3509 -+ */
3510 -+ void idleTerminated();
3511 -+
3512 -+private slots:
3513 -+ void addNotification(Notification *notification);
3514 -+ void removeNotification(Notification *notification);
3515 -+ void addJob(Job *job);
3516 -+ void removeJob(Job *job);
3517 -+ void updateTotals();
3518 -+ void checkIdle();
3519 -+
3520 -+private:
3521 -+ class Private;
3522 -+ Private* const d;
3523 -+
3524 -+ friend class Notifications;
3525 -+};
3526 -+
3527 -+
3528 -+
3529 -+#endif
3530 -diff --git a/plasma/generic/applets/notifications/core/protocol.cpp b/plasma/generic/applets/notifications/core/protocol.cpp
3531 -new file mode 100644
3532 -index 0000000..a3716a2
3533 ---- /dev/null
3534 -+++ b/plasma/generic/applets/notifications/core/protocol.cpp
3535 -@@ -0,0 +1,31 @@
3536 -+/***************************************************************************
3537 -+ * taskprotocol.cpp *
3538 -+ * *
3539 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
3540 -+ * *
3541 -+ * This program is free software; you can redistribute it and/or modify *
3542 -+ * it under the terms of the GNU General Public License as published by *
3543 -+ * the Free Software Foundation; either version 2 of the License, or *
3544 -+ * (at your option) any later version. *
3545 -+ * *
3546 -+ * This program is distributed in the hope that it will be useful, *
3547 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
3548 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
3549 -+ * GNU General Public License for more details. *
3550 -+ * *
3551 -+ * You should have received a copy of the GNU General Public License *
3552 -+ * along with this program; if not, write to the *
3553 -+ * Free Software Foundation, Inc., *
3554 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
3555 -+ ***************************************************************************/
3556 -+
3557 -+#include "protocol.h"
3558 -+
3559 -+
3560 -+Protocol::Protocol(QObject *parent)
3561 -+ : QObject(parent)
3562 -+{
3563 -+}
3564 -+
3565 -+
3566 -+#include "protocol.moc"
3567 -diff --git a/plasma/generic/applets/notifications/core/protocol.h b/plasma/generic/applets/notifications/core/protocol.h
3568 -new file mode 100644
3569 -index 0000000..ea47292
3570 ---- /dev/null
3571 -+++ b/plasma/generic/applets/notifications/core/protocol.h
3572 -@@ -0,0 +1,68 @@
3573 -+/***************************************************************************
3574 -+ * taskprotocol.h *
3575 -+ * *
3576 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
3577 -+ * *
3578 -+ * This program is free software; you can redistribute it and/or modify *
3579 -+ * it under the terms of the GNU General Public License as published by *
3580 -+ * the Free Software Foundation; either version 2 of the License, or *
3581 -+ * (at your option) any later version. *
3582 -+ * *
3583 -+ * This program is distributed in the hope that it will be useful, *
3584 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
3585 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
3586 -+ * GNU General Public License for more details. *
3587 -+ * *
3588 -+ * You should have received a copy of the GNU General Public License *
3589 -+ * along with this program; if not, write to the *
3590 -+ * Free Software Foundation, Inc., *
3591 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
3592 -+ ***************************************************************************/
3593 -+
3594 -+#ifndef PROTOCOL_H
3595 -+#define PROTOCOL_H
3596 -+
3597 -+#include <QtCore/QObject>
3598 -+
3599 -+
3600 -+class Job;
3601 -+class Notification;
3602 -+class Task;
3603 -+
3604 -+
3605 -+/**
3606 -+ * @short System tray protocol base class
3607 -+ *
3608 -+ * To support a new system tray protocol, this class and Task should be
3609 -+ * subclassed and the subclass of this class registered with the global
3610 -+ * Manager. The Protocol subclass should emit taskCreated() for each new
3611 -+ * task created.
3612 -+ **/
3613 -+class Protocol : public QObject
3614 -+{
3615 -+ Q_OBJECT
3616 -+public:
3617 -+ explicit Protocol(QObject *parent);
3618 -+
3619 -+ virtual void init() = 0;
3620 -+
3621 -+signals:
3622 -+ /**
3623 -+ * Signals that a new task has been created
3624 -+ **/
3625 -+ void taskCreated(Task *task);
3626 -+
3627 -+ /**
3628 -+ * Signals that a new notification has been created
3629 -+ **/
3630 -+ void jobCreated(Job *job);
3631 -+
3632 -+ /**
3633 -+ * Signals that a new notification has been created
3634 -+ **/
3635 -+ void notificationCreated(Notification *notification);
3636 -+};
3637 -+
3638 -+
3639 -+
3640 -+#endif
3641 -diff --git a/plasma/generic/applets/notifications/metadata.desktop b/plasma/generic/applets/notifications/metadata.desktop
3642 -deleted file mode 100644
3643 -index 3a2be65..0000000
3644 ---- a/plasma/generic/applets/notifications/metadata.desktop
3645 -+++ /dev/null
3646 -@@ -1,166 +0,0 @@
3647 --[Desktop Entry]
3648 --Encoding=UTF-8
3649 --Name=Notifications
3650 --Name[ar]=تنبيهات
3651 --Name[ast]=Notificaciones
3652 --Name[be]=Абвяшчэнні
3653 --Name[be@latin]=Infarmavańnie
3654 --Name[bg]=Уведомяване
3655 --Name[bn]=বিজ্ঞপ্তি
3656 --Name[bn_IN]=সূচনাবার্তা
3657 --Name[br]=Kemenn
3658 --Name[bs]=obavještenja
3659 --Name[ca]=Notificacions
3660 --Name[ca@valencia]=Notificacions
3661 --Name[cs]=Oznamování
3662 --Name[csb]=Dôwanié wiédzë
3663 --Name[da]=Bekendtgørelser
3664 --Name[de]=Benachrichtigungen
3665 --Name[el]=Ειδοποιήσεις
3666 --Name[en_GB]=Notifications
3667 --Name[eo]=Atentigoj
3668 --Name[es]=Notificaciones
3669 --Name[et]=Märguanded
3670 --Name[eu]=Jakinarazpenak
3671 --Name[fa]=اخطارها
3672 --Name[fi]=Ilmoitukset
3673 --Name[fr]=Notifications
3674 --Name[fy]=Notifikaasjes
3675 --Name[ga]=Fógairt
3676 --Name[gl]=Notificacións
3677 --Name[gu]=નોંધણીઓ
3678 --Name[he]=הודעות
3679 --Name[hi]=सूचनाएँ
3680 --Name[hne]=सूचना मन ल
3681 --Name[hr]=Obavijesti
3682 --Name[hu]=Rendszerüzenetek
3683 --Name[ia]=Notificationes
3684 --Name[id]=Notifikasi
3685 --Name[is]=Kerfistilkynningar
3686 --Name[it]=Notifiche
3687 --Name[ja]=通知
3688 --Name[kk]=Құлақтандыру
3689 --Name[km]=សេចក្តី​ជូន​ដំណឹង​
3690 --Name[kn]=ಸೂಚನೆಗಳು
3691 --Name[ko]=알림
3692 --Name[ku]=Agahdarî
3693 --Name[lt]=Pranešimai
3694 --Name[lv]=Paziņojumi
3695 --Name[mai]=सूचनासभ
3696 --Name[mk]=Известувања
3697 --Name[ml]=അറിയിപ്പുകള്‍
3698 --Name[mr]=सूचना
3699 --Name[ms]=Pemberitahuan
3700 --Name[nb]=Varslinger
3701 --Name[nds]=Bescheden
3702 --Name[ne]=सूचना
3703 --Name[nl]=Meldingen
3704 --Name[nn]=Varslingar
3705 --Name[oc]=Notificacions
3706 --Name[or]=ବିଜ୍ଞପ୍ତି
3707 --Name[pa]=ਨੋਟੀਫਿਕੇਸ਼ਨ
3708 --Name[pl]=Powiadomienia
3709 --Name[pt]=Notificações
3710 --Name[pt_BR]=Notificações
3711 --Name[ro]=Notificări
3712 --Name[ru]=Системные уведомления
3713 --Name[se]=Dieđáhusat
3714 --Name[si]=දැනුම් දීම්
3715 --Name[sk]=Upozornenia
3716 --Name[sl]=Obvestila
3717 --Name[sr]=обавештења
3718 --Name[sr@ijekavian]=обавјештења
3719 --Name[sr@ijekavianlatin]=obavještenja
3720 --Name[sr@latin]=obaveštenja
3721 --Name[sv]=Underrättelser
3722 --Name[ta]=Notifications
3723 --Name[te]=నోటీసులు
3724 --Name[tg]=Огоҳиномаҳо
3725 --Name[th]=การแจ้งให้ทราบต่าง ๆ
3726 --Name[tr]=Bildirimler
3727 --Name[ug]=ئۇقتۇرۇشلار
3728 --Name[uk]=Сповіщення
3729 --Name[uz]=Xabarnomalar
3730 --Name[uz@cyrillic]=Хабарномалар
3731 --Name[wa]=Notifiaedjes
3732 --Name[x-test]=xxNotificationsxx
3733 --Name[zh_CN]=通知
3734 --Name[zh_TW]=通知
3735 --Comment=Display notifications and jobs
3736 --Comment[ar]=أظهر التنبيهات والمهام
3737 --Comment[ast]=Amosar notificaciones y xeres
3738 --Comment[bg]=Показване на уведомления и задачи
3739 --Comment[bs]=Prikazuje obavještenja i poslove
3740 --Comment[ca]=Mostra les notificacions i els treballs
3741 --Comment[ca@valencia]=Mostra les notificacions i els treballs
3742 --Comment[cs]=Oznámení a úlohy
3743 --Comment[da]=Vis bekendtgørelser og job
3744 --Comment[de]=Benachrichtigungen und Aktionen anzeigen
3745 --Comment[el]=Εμφανίζει ειδοποιήσεις και εργασίες
3746 --Comment[en_GB]=Display notifications and jobs
3747 --Comment[es]=Mostrar notificaciones y tareas
3748 --Comment[et]=Märguannete ja tööde näitamine
3749 --Comment[eu]=Bistaratu jakinarazpenak eta lanak
3750 --Comment[fi]=Näyttää ilmoituksia ja töitä
3751 --Comment[fr]=Affiche les notifications et les tâches
3752 --Comment[ga]=Taispeáin fógraí agus jabanna
3753 --Comment[gl]=Mostra notificacións e tarefas
3754 --Comment[he]=משמש להצגת הודעות ועבודות
3755 --Comment[hr]=Prikazuje obavijesti i poslove
3756 --Comment[hu]=Értesítések és feladatok megjelenítése
3757 --Comment[ia]=Monstra notificationes e labores
3758 --Comment[id]=Tampilan notifikasi dan tugas
3759 --Comment[is]=Birting tilkynninga og verka
3760 --Comment[it]=Mostra notifiche e processi
3761 --Comment[ja]=ディスプレイ通知とジョブ
3762 --Comment[kk]=Құлақтандыру мен тапсырмаларды көрсету
3763 --Comment[km]=បង្ហាញ​ការ​ជូនដំណឹង និង​ការងារ
3764 --Comment[kn]=ಸೂಚನೆಗಳು ಹಾಗು ಕಾರ್ಯಗಳನ್ನು ಪ್ರದರ್ಶಿಸು
3765 --Comment[ko]=알림과 작업 표시
3766 --Comment[lt]=Rodyti pranešimus ir darbus
3767 --Comment[lv]=Parāda paziņojumus un darbus
3768 --Comment[mr]=सूचना व कार्यै दर्शवा
3769 --Comment[nb]=Vis varslinger og jobber
3770 --Comment[nds]=Bescheden un Opgaven wiesen
3771 --Comment[nl]=Meldingen en taken tonen
3772 --Comment[pa]=ਨੋਟੀਫਿਕੇਸ਼ਨ ਤੇ ਜਾਬ ਵੇਖੋ
3773 --Comment[pl]=Wyświetlanie powiadomień i zadań
3774 --Comment[pt]=Mostrar as notificações e tarefas
3775 --Comment[pt_BR]=Exibe notificações e tarefas
3776 --Comment[ro]=Afișează notificări și sarcini
3777 --Comment[ru]=Уведомления и задания
3778 --Comment[si]=කාර්ය සහ දැනුම්දීමෙ පෙන්වන්න
3779 --Comment[sk]=Zobrazenie upozornení a úloh
3780 --Comment[sl]=Prikazuje obvestila in opravila
3781 --Comment[sr]=Приказује обавештења и послове
3782 --Comment[sr@ijekavian]=Приказује обавјештења и послове
3783 --Comment[sr@ijekavianlatin]=Prikazuje obavještenja i poslove
3784 --Comment[sr@latin]=Prikazuje obaveštenja i poslove
3785 --Comment[sv]=Visa underrättelser och jobb
3786 --Comment[tg]=Иттилооти огоҳиҳо ва амалҳо
3787 --Comment[th]=แสดงการแจ้งให้ทราบและงานต่าง ๆ
3788 --Comment[tr]=Bildirimleri ve görevleri göster
3789 --Comment[ug]=ئۇقتۇرۇش ۋە ۋەزىپىلەرنى كۆرسىتىدۇ
3790 --Comment[uk]=Показ сповіщень і завдань
3791 --Comment[vi]=Hiển thị thông báo và công việc
3792 --Comment[wa]=Håyner notifiaedjes eyet bouyes
3793 --Comment[x-test]=xxDisplay notifications and jobsxx
3794 --Comment[zh_CN]=显示通知和任务
3795 --Comment[zh_TW]=顯示通知與工作
3796 --
3797 --Type=Service
3798 --Icon=preferences-desktop-notification
3799 --X-KDE-ParentApp=
3800 --X-KDE-PluginInfo-Author=Davide Bettio
3801 --X-KDE-PluginInfo-Category=Tasks
3802 --X-KDE-PluginInfo-Email=davide.bettio@×××××××.net
3803 --X-KDE-PluginInfo-License=GPL
3804 --X-KDE-PluginInfo-Name=org.kde.notifications
3805 --X-KDE-PluginInfo-Version=0.1
3806 --X-KDE-PluginInfo-Website=http://plasma.kde.org/
3807 --X-KDE-ServiceTypes=Plasma/PopupApplet,Plasma/Applet
3808 --X-Plasma-API=declarativeappletscript
3809 --X-Plasma-DefaultSize=100,100
3810 --X-Plasma-MainScript=ui/main.qml
3811 --X-Plasma-RequiredExtensions=LaunchApp
3812 --X-Plasma-NotificationArea=true
3813 -diff --git a/plasma/generic/applets/notifications/plasma-applet-notifications.desktop b/plasma/generic/applets/notifications/plasma-applet-notifications.desktop
3814 -new file mode 100644
3815 -index 0000000..78a76f8
3816 ---- /dev/null
3817 -+++ b/plasma/generic/applets/notifications/plasma-applet-notifications.desktop
3818 -@@ -0,0 +1,164 @@
3819 -+[Desktop Entry]
3820 -+Name=Notifications
3821 -+Name[ar]=تنبيهات
3822 -+Name[ast]=Notificaciones
3823 -+Name[be]=Абвяшчэнні
3824 -+Name[be@latin]=Infarmavańnie
3825 -+Name[bg]=Уведомяване
3826 -+Name[bn]=বিজ্ঞপ্তি
3827 -+Name[bn_IN]=সূচনাবার্তা
3828 -+Name[br]=Kemenn
3829 -+Name[bs]=obavještenja
3830 -+Name[ca]=Notificacions
3831 -+Name[ca@valencia]=Notificacions
3832 -+Name[cs]=Oznamování
3833 -+Name[csb]=Dôwanié wiédzë
3834 -+Name[da]=Bekendtgørelser
3835 -+Name[de]=Benachrichtigungen
3836 -+Name[el]=Ειδοποιήσεις
3837 -+Name[en_GB]=Notifications
3838 -+Name[eo]=Atentigoj
3839 -+Name[es]=Notificaciones
3840 -+Name[et]=Märguanded
3841 -+Name[eu]=Jakinarazpenak
3842 -+Name[fa]=اخطارها
3843 -+Name[fi]=Ilmoitukset
3844 -+Name[fr]=Notifications
3845 -+Name[fy]=Notifikaasjes
3846 -+Name[ga]=Fógairt
3847 -+Name[gl]=Notificacións
3848 -+Name[gu]=નોંધણીઓ
3849 -+Name[he]=הודעות
3850 -+Name[hi]=सूचनाएँ
3851 -+Name[hne]=सूचना मन ल
3852 -+Name[hr]=Obavijesti
3853 -+Name[hu]=Rendszerüzenetek
3854 -+Name[ia]=Notificationes
3855 -+Name[id]=Notifikasi
3856 -+Name[is]=Kerfistilkynningar
3857 -+Name[it]=Notifiche
3858 -+Name[ja]=通知
3859 -+Name[kk]=Құлақтандыру
3860 -+Name[km]=សេចក្តី​ជូន​ដំណឹង​
3861 -+Name[kn]=ಸೂಚನೆಗಳು
3862 -+Name[ko]=알림
3863 -+Name[ku]=Agahdarî
3864 -+Name[lt]=Pranešimai
3865 -+Name[lv]=Paziņojumi
3866 -+Name[mai]=सूचनासभ
3867 -+Name[mk]=Известувања
3868 -+Name[ml]=അറിയിപ്പുകള്‍
3869 -+Name[mr]=सूचना
3870 -+Name[ms]=Pemberitahuan
3871 -+Name[nb]=Varslinger
3872 -+Name[nds]=Bescheden
3873 -+Name[ne]=सूचना
3874 -+Name[nl]=Meldingen
3875 -+Name[nn]=Varslingar
3876 -+Name[oc]=Notificacions
3877 -+Name[or]=ବିଜ୍ଞପ୍ତି
3878 -+Name[pa]=ਨੋਟੀਫਿਕੇਸ਼ਨ
3879 -+Name[pl]=Powiadomienia
3880 -+Name[pt]=Notificações
3881 -+Name[pt_BR]=Notificações
3882 -+Name[ro]=Notificări
3883 -+Name[ru]=Системные уведомления
3884 -+Name[se]=Dieđáhusat
3885 -+Name[si]=දැනුම් දීම්
3886 -+Name[sk]=Upozornenia
3887 -+Name[sl]=Obvestila
3888 -+Name[sr]=обавештења
3889 -+Name[sr@ijekavian]=обавјештења
3890 -+Name[sr@ijekavianlatin]=obavještenja
3891 -+Name[sr@latin]=obaveštenja
3892 -+Name[sv]=Underrättelser
3893 -+Name[ta]=Notifications
3894 -+Name[te]=నోటీసులు
3895 -+Name[tg]=Огоҳиномаҳо
3896 -+Name[th]=การแจ้งให้ทราบต่าง ๆ
3897 -+Name[tr]=Bildirimler
3898 -+Name[ug]=ئۇقتۇرۇشلار
3899 -+Name[uk]=Сповіщення
3900 -+Name[uz]=Xabarnomalar
3901 -+Name[uz@cyrillic]=Хабарномалар
3902 -+Name[wa]=Notifiaedjes
3903 -+Name[x-test]=xxNotificationsxx
3904 -+Name[zh_CN]=通知
3905 -+Name[zh_TW]=通知
3906 -+Comment=Display notifications and jobs
3907 -+Comment[ar]=أظهر التنبيهات والمهام
3908 -+Comment[ast]=Amosar notificaciones y xeres
3909 -+Comment[bg]=Показване на уведомления и задачи
3910 -+Comment[bs]=Prikazuje obavještenja i poslove
3911 -+Comment[ca]=Mostra les notificacions i els treballs
3912 -+Comment[ca@valencia]=Mostra les notificacions i els treballs
3913 -+Comment[cs]=Oznámení a úlohy
3914 -+Comment[da]=Vis bekendtgørelser og job
3915 -+Comment[de]=Benachrichtigungen und Aktionen anzeigen
3916 -+Comment[el]=Εμφανίζει ειδοποιήσεις και εργασίες
3917 -+Comment[en_GB]=Display notifications and jobs
3918 -+Comment[es]=Mostrar notificaciones y tareas
3919 -+Comment[et]=Märguannete ja tööde näitamine
3920 -+Comment[eu]=Bistaratu jakinarazpenak eta lanak
3921 -+Comment[fi]=Näyttää ilmoituksia ja töitä
3922 -+Comment[fr]=Affiche les notifications et les tâches
3923 -+Comment[ga]=Taispeáin fógraí agus jabanna
3924 -+Comment[gl]=Mostra notificacións e tarefas
3925 -+Comment[he]=משמש להצגת הודעות ועבודות
3926 -+Comment[hr]=Prikazuje obavijesti i poslove
3927 -+Comment[hu]=Értesítések és feladatok megjelenítése
3928 -+Comment[ia]=Monstra notificationes e labores
3929 -+Comment[id]=Tampilan notifikasi dan tugas
3930 -+Comment[is]=Birting tilkynninga og verka
3931 -+Comment[it]=Mostra notifiche e processi
3932 -+Comment[ja]=ディスプレイ通知とジョブ
3933 -+Comment[kk]=Құлақтандыру мен тапсырмаларды көрсету
3934 -+Comment[km]=បង្ហាញ​ការ​ជូនដំណឹង និង​ការងារ
3935 -+Comment[kn]=ಸೂಚನೆಗಳು ಹಾಗು ಕಾರ್ಯಗಳನ್ನು ಪ್ರದರ್ಶಿಸು
3936 -+Comment[ko]=알림과 작업 표시
3937 -+Comment[lt]=Rodyti pranešimus ir darbus
3938 -+Comment[lv]=Parāda paziņojumus un darbus
3939 -+Comment[nb]=Vis varslinger og jobber
3940 -+Comment[nds]=Bescheden un Opgaven wiesen
3941 -+Comment[nl]=Meldingen en taken tonen
3942 -+Comment[pa]=ਨੋਟੀਫਿਕੇਸ਼ਨ ਤੇ ਜਾਬ ਵੇਖੋ
3943 -+Comment[pl]=Wyświetlanie powiadomień i zadań
3944 -+Comment[pt]=Mostrar as notificações e tarefas
3945 -+Comment[pt_BR]=Exibe notificações e tarefas
3946 -+Comment[ro]=Afișează notificări și sarcini
3947 -+Comment[ru]=Уведомления и задания
3948 -+Comment[si]=කාර්ය සහ දැනුම්දීමෙ පෙන්වන්න
3949 -+Comment[sk]=Zobrazenie upozornení a úloh
3950 -+Comment[sl]=Prikazuje obvestila in opravila
3951 -+Comment[sr]=Приказује обавештења и послове
3952 -+Comment[sr@ijekavian]=Приказује обавјештења и послове
3953 -+Comment[sr@ijekavianlatin]=Prikazuje obavještenja i poslove
3954 -+Comment[sr@latin]=Prikazuje obaveštenja i poslove
3955 -+Comment[sv]=Visa underrättelser och jobb
3956 -+Comment[tg]=Иттилооти огоҳиҳо ва амалҳо
3957 -+Comment[th]=แสดงการแจ้งให้ทราบและงานต่าง ๆ
3958 -+Comment[tr]=Bildirimleri ve görevleri göster
3959 -+Comment[ug]=ئۇقتۇرۇش ۋە ۋەزىپىلەرنى كۆرسىتىدۇ
3960 -+Comment[uk]=Показ сповіщень і завдань
3961 -+Comment[vi]=Hiển thị thông báo và công việc
3962 -+Comment[wa]=Håyner notifiaedjes eyet bouyes
3963 -+Comment[x-test]=xxDisplay notifications and jobsxx
3964 -+Comment[zh_CN]=显示通知和任务
3965 -+Comment[zh_TW]=顯示通知與工作
3966 -+
3967 -+Icon=dialog-information
3968 -+Type=Service
3969 -+X-KDE-ServiceTypes=Plasma/Applet
3970 -+
3971 -+X-KDE-Library=plasma_applet_notifications
3972 -+X-KDE-PluginInfo-Author=Marco Martin
3973 -+X-KDE-PluginInfo-Email=notmart@×××××.com
3974 -+X-KDE-PluginInfo-Name=notifications
3975 -+X-KDE-PluginInfo-Version=1.0
3976 -+X-KDE-PluginInfo-Website=http://plasma.kde.org/
3977 -+X-KDE-PluginInfo-Category=System Information
3978 -+X-KDE-PluginInfo-Depends=
3979 -+X-KDE-PluginInfo-License=GPL v2+
3980 -+X-KDE-PluginInfo-EnabledByDefault=true
3981 -+
3982 -+X-Plasma-NotificationArea=true
3983 -diff --git a/plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/NotificationDelegate.qml b/plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/NotificationDelegate.qml
3984 -deleted file mode 100644
3985 -index bdb74c2..0000000
3986 ---- a/plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/NotificationDelegate.qml
3987 -+++ /dev/null
3988 -@@ -1,195 +0,0 @@
3989 --/*
3990 -- * Copyright 2011 Marco Martin <notmart@×××××.com>
3991 -- *
3992 -- * This program is free software; you can redistribute it and/or modify
3993 -- * it under the terms of the GNU Library General Public License as
3994 -- * published by the Free Software Foundation; either version 2, or
3995 -- * (at your option) any later version.
3996 -- *
3997 -- * This program is distributed in the hope that it will be useful,
3998 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3999 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4000 -- * GNU Library General Public License for more details
4001 -- *
4002 -- * You should have received a copy of the GNU Library General Public
4003 -- * License along with this program; if not, write to the
4004 -- * Free Software Foundation, Inc.,
4005 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
4006 -- */
4007 --
4008 --import QtQuick 1.0
4009 --import org.kde.plasma.core 0.1 as PlasmaCore
4010 --import org.kde.plasma.components 0.1 as PlasmaComponents
4011 --import org.kde.qtextracomponents 0.1
4012 --
4013 --PlasmaComponents.ListItem {
4014 -- id: notificationItem
4015 -- opacity: 1-Math.abs(x)/width
4016 -- width: popupFlickable.width
4017 -- property int toolIconSize: theme.smallMediumIconSize
4018 -- property int layoutSpacing: 4
4019 --
4020 -- visible: appTabBar.currentTab == allAppsTab || appTabBar.currentTab.text == appName
4021 --
4022 -- Component.onCompleted: {
4023 -- allApplicationsModel.addApplication(appIcon, appName)
4024 -- mainScrollArea.height = mainScrollArea.implicitHeight
4025 -- }
4026 -- Component.onDestruction: {
4027 -- allApplicationsModel.removeApplication(model.appName)
4028 -- mainScrollArea.height = mainScrollArea.implicitHeight
4029 -- }
4030 -- Timer {
4031 -- interval: 10*60*1000
4032 -- repeat: false
4033 -- running: !idleTimeSource.idle
4034 -- onTriggered: {
4035 -- notificationsModel.remove(index)
4036 -- }
4037 -- }
4038 --
4039 --
4040 -- MouseArea {
4041 -- width: parent.width
4042 -- height: childrenRect.height
4043 -- drag {
4044 -- target: notificationItem
4045 -- axis: Drag.XAxis
4046 -- //kind of an hack over Column being too smart
4047 -- minimumX: -parent.width + 1
4048 -- maximumX: parent.width - 1
4049 -- }
4050 -- onReleased: {
4051 -- if (notificationItem.x < -notificationItem.width/2) {
4052 -- removeAnimation.exitFromRight = false
4053 -- removeAnimation.running = true
4054 -- } else if (notificationItem.x > notificationItem.width/2 ) {
4055 -- removeAnimation.exitFromRight = true
4056 -- removeAnimation.running = true
4057 -- } else {
4058 -- resetAnimation.running = true
4059 -- }
4060 -- }
4061 -- SequentialAnimation {
4062 -- id: removeAnimation
4063 -- property bool exitFromRight: true
4064 -- NumberAnimation {
4065 -- target: notificationItem
4066 -- properties: "x"
4067 -- to: removeAnimation.exitFromRight ? notificationItem.width-1 : 1-notificationItem.width
4068 -- duration: 250
4069 -- easing.type: Easing.InOutQuad
4070 -- }
4071 -- NumberAnimation {
4072 -- target: notificationItem
4073 -- properties: "height"
4074 -- to: 0
4075 -- duration: 250
4076 -- easing.type: Easing.InOutQuad
4077 -- }
4078 -- ScriptAction {
4079 -- script: notificationsModel.remove(index)
4080 -- }
4081 -- }
4082 -- SequentialAnimation {
4083 -- id: resetAnimation
4084 -- NumberAnimation {
4085 -- target: notificationItem
4086 -- properties: "x"
4087 -- to: 0
4088 -- duration: 250
4089 -- easing.type: Easing.InOutQuad
4090 -- }
4091 -- }
4092 -- Column {
4093 -- spacing: notificationItem.layoutSpacing
4094 -- width: parent.width
4095 -- Item {
4096 -- width: parent.width
4097 -- height: summaryLabel.height
4098 --
4099 -- PlasmaComponents.Label {
4100 -- id: summaryLabel
4101 -- text: summary
4102 -- height: paintedHeight
4103 -- anchors {
4104 -- left: parent.left
4105 -- right: parent.right
4106 -- leftMargin: closeButton.width
4107 -- rightMargin: closeButton.width
4108 -- }
4109 -- horizontalAlignment: Text.AlignHCenter
4110 -- elide: Text.ElideRight
4111 -- }
4112 --
4113 -- PlasmaComponents.ToolButton {
4114 -- id: closeButton
4115 -- iconSource: "window-close"
4116 -- width: notificationItem.toolIconSize
4117 -- height: width
4118 -- onClicked: removeAnimation.running = true
4119 -- anchors {
4120 -- top: parent.top
4121 -- right: parent.right
4122 -- }
4123 -- }
4124 -- }
4125 --
4126 -- Item {
4127 -- height: childrenRect.height
4128 -- width: parent.width
4129 -- QIconItem {
4130 -- id: appIconItem
4131 -- icon: QIcon(appIcon)
4132 -- width: theme.largeIconSize
4133 -- height: theme.largeIconSize
4134 -- visible: !imageItem.visible
4135 -- anchors {
4136 -- left: parent.left
4137 -- verticalCenter: parent.verticalCenter
4138 -- }
4139 -- }
4140 -- QImageItem {
4141 -- id: imageItem
4142 -- anchors.fill: appIconItem
4143 -- image: model.image
4144 -- smooth: true
4145 -- visible: nativeWidth > 0
4146 -- }
4147 -- PlasmaComponents.Label {
4148 -- text: body
4149 -- color: theme.textColor
4150 -- anchors {
4151 -- left: appIconItem.right
4152 -- right: actionsColumn.left
4153 -- verticalCenter: parent.verticalCenter
4154 -- leftMargin: 6
4155 -- rightMargin: 6
4156 -- }
4157 -- wrapMode: Text.Wrap
4158 -- }
4159 -- Column {
4160 -- id: actionsColumn
4161 -- spacing: notificationItem.layoutSpacing
4162 -- anchors {
4163 -- right: parent.right
4164 -- rightMargin: 6
4165 -- verticalCenter: parent.verticalCenter
4166 -- }
4167 -- Repeater {
4168 -- model: actions
4169 -- PlasmaComponents.Button {
4170 -- text: model.text
4171 -- width: theme.defaultFont.mSize.width * 8
4172 -- height: theme.defaultFont.mSize.width * 3
4173 -- onClicked: {
4174 -- executeAction(source, model.id)
4175 -- actionsColumn.visible = false
4176 -- }
4177 -- }
4178 -- }
4179 -- }
4180 -- }
4181 -- }
4182 -- }
4183 --}
4184 -diff --git a/plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/qmldir b/plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/qmldir
4185 -deleted file mode 100644
4186 -index 88fc37a..0000000
4187 ---- a/plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/qmldir
4188 -+++ /dev/null
4189 -@@ -1 +0,0 @@
4190 --NotificationDelegate 0.1 NotificationDelegate.qml
4191 -diff --git a/plasma/generic/applets/notifications/platformcontents/touch/ui/uiproperties.js b/plasma/generic/applets/notifications/platformcontents/touch/ui/uiproperties.js
4192 -deleted file mode 100644
4193 -index f2f3d6b..0000000
4194 ---- a/plasma/generic/applets/notifications/platformcontents/touch/ui/uiproperties.js
4195 -+++ /dev/null
4196 -@@ -1,23 +0,0 @@
4197 --/*
4198 -- * Copyright 2012 Marco Martin <notmart@×××××.com>
4199 -- *
4200 -- * This program is free software; you can redistribute it and/or modify
4201 -- * it under the terms of the GNU Library General Public License as
4202 -- * published by the Free Software Foundation; either version 2, or
4203 -- * (at your option) any later version.
4204 -- *
4205 -- * This program is distributed in the hope that it will be useful,
4206 -- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4207 -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4208 -- * GNU Library General Public License for more details
4209 -- *
4210 -- * You should have received a copy of the GNU Library General Public
4211 -- * License along with this program; if not, write to the
4212 -- * Free Software Foundation, Inc.,
4213 -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
4214 -- */
4215 --
4216 --
4217 --var toolIconSize = theme.mediumIconSize
4218 --var layoutSpacing = 6
4219 --var touchInput = true
4220 -diff --git a/plasma/generic/applets/notifications/protocols/jobs/dbusjob.cpp b/plasma/generic/applets/notifications/protocols/jobs/dbusjob.cpp
4221 -new file mode 100644
4222 -index 0000000..7c89275
4223 ---- /dev/null
4224 -+++ b/plasma/generic/applets/notifications/protocols/jobs/dbusjob.cpp
4225 -@@ -0,0 +1,54 @@
4226 -+/***************************************************************************
4227 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
4228 -+ * *
4229 -+ * This program is free software; you can redistribute it and/or modify *
4230 -+ * it under the terms of the GNU General Public License as published by *
4231 -+ * the Free Software Foundation; either version 2 of the License, or *
4232 -+ * (at your option) any later version. *
4233 -+ * *
4234 -+ * This program is distributed in the hope that it will be useful, *
4235 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4236 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4237 -+ * GNU General Public License for more details. *
4238 -+ * *
4239 -+ * You should have received a copy of the GNU General Public License *
4240 -+ * along with this program; if not, write to the *
4241 -+ * Free Software Foundation, Inc., *
4242 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4243 -+ ***************************************************************************/
4244 -+
4245 -+#include "dbusjob.h"
4246 -+
4247 -+#include <KDebug>
4248 -+
4249 -+
4250 -+
4251 -+DBusJob::DBusJob(const QString &source, QObject *parent)
4252 -+ : Job(parent),
4253 -+ m_source(source)
4254 -+{
4255 -+}
4256 -+
4257 -+DBusJob::~DBusJob()
4258 -+{
4259 -+ emit jobDeleted(m_source);
4260 -+}
4261 -+
4262 -+void DBusJob::suspend()
4263 -+{
4264 -+ emit suspend(m_source);
4265 -+ kDebug() << "suspend";
4266 -+}
4267 -+
4268 -+void DBusJob::resume()
4269 -+{
4270 -+ emit resume(m_source);
4271 -+ kDebug() << "resume";
4272 -+}
4273 -+
4274 -+void DBusJob::stop()
4275 -+{
4276 -+ emit stop(m_source);
4277 -+ kDebug() << "cancel";
4278 -+}
4279 -+
4280 -diff --git a/plasma/generic/applets/notifications/protocols/jobs/dbusjob.h b/plasma/generic/applets/notifications/protocols/jobs/dbusjob.h
4281 -new file mode 100644
4282 -index 0000000..2e973d6
4283 ---- /dev/null
4284 -+++ b/plasma/generic/applets/notifications/protocols/jobs/dbusjob.h
4285 -@@ -0,0 +1,54 @@
4286 -+/***************************************************************************
4287 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
4288 -+ * *
4289 -+ * This program is free software; you can redistribute it and/or modify *
4290 -+ * it under the terms of the GNU General Public License as published by *
4291 -+ * the Free Software Foundation; either version 2 of the License, or *
4292 -+ * (at your option) any later version. *
4293 -+ * *
4294 -+ * This program is distributed in the hope that it will be useful, *
4295 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4296 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4297 -+ * GNU General Public License for more details. *
4298 -+ * *
4299 -+ * You should have received a copy of the GNU General Public License *
4300 -+ * along with this program; if not, write to the *
4301 -+ * Free Software Foundation, Inc., *
4302 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4303 -+ ***************************************************************************/
4304 -+
4305 -+#ifndef DBUSJOB_H
4306 -+#define DBUSJOB_H
4307 -+
4308 -+#include "../../core/job.h"
4309 -+
4310 -+
4311 -+
4312 -+class DBusJob : public Job
4313 -+{
4314 -+ Q_OBJECT
4315 -+
4316 -+ friend class DBusJobProtocol;
4317 -+
4318 -+public:
4319 -+ DBusJob(const QString &source, QObject *parent = 0);
4320 -+ ~DBusJob();
4321 -+
4322 -+public slots:
4323 -+ void suspend();
4324 -+ void resume();
4325 -+ void stop();
4326 -+
4327 -+signals:
4328 -+ void jobDeleted(const QString &source);
4329 -+ void suspend(const QString &source);
4330 -+ void resume(const QString &source);
4331 -+ void stop(const QString &source);
4332 -+
4333 -+private:
4334 -+ QString m_source;
4335 -+};
4336 -+
4337 -+
4338 -+
4339 -+#endif
4340 -diff --git a/plasma/generic/applets/notifications/protocols/jobs/dbusjobprotocol.cpp b/plasma/generic/applets/notifications/protocols/jobs/dbusjobprotocol.cpp
4341 -new file mode 100644
4342 -index 0000000..dff6dc9
4343 ---- /dev/null
4344 -+++ b/plasma/generic/applets/notifications/protocols/jobs/dbusjobprotocol.cpp
4345 -@@ -0,0 +1,180 @@
4346 -+/***************************************************************************
4347 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
4348 -+ * *
4349 -+ * This program is free software; you can redistribute it and/or modify *
4350 -+ * it under the terms of the GNU General Public License as published by *
4351 -+ * the Free Software Foundation; either version 2 of the License, or *
4352 -+ * (at your option) any later version. *
4353 -+ * *
4354 -+ * This program is distributed in the hope that it will be useful, *
4355 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4356 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4357 -+ * GNU General Public License for more details. *
4358 -+ * *
4359 -+ * You should have received a copy of the GNU General Public License *
4360 -+ * along with this program; if not, write to the *
4361 -+ * Free Software Foundation, Inc., *
4362 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4363 -+ ***************************************************************************/
4364 -+
4365 -+#include "dbusjob.h"
4366 -+#include "dbusjobprotocol.h"
4367 -+
4368 -+
4369 -+#include <KConfigGroup>
4370 -+
4371 -+#include <Plasma/DataEngineManager>
4372 -+#include <Plasma/Service>
4373 -+#include <Plasma/ServiceJob>
4374 -+
4375 -+static const char engineName[] = "applicationjobs";
4376 -+
4377 -+DBusJobProtocol::DBusJobProtocol(Manager *parent)
4378 -+ : Protocol(parent),
4379 -+ m_manager(parent),
4380 -+ m_engine(0)
4381 -+{
4382 -+}
4383 -+
4384 -+
4385 -+DBusJobProtocol::~DBusJobProtocol()
4386 -+{
4387 -+ if (m_engine) {
4388 -+ Plasma::DataEngineManager::self()->unloadEngine(engineName);
4389 -+ }
4390 -+
4391 -+ foreach (DBusJob *job, m_jobs) {
4392 -+ disconnect(job);
4393 -+ job->destroy();
4394 -+ }
4395 -+
4396 -+ m_jobs.clear();
4397 -+}
4398 -+
4399 -+
4400 -+void DBusJobProtocol::init()
4401 -+{
4402 -+ m_engine = Plasma::DataEngineManager::self()->loadEngine(engineName);
4403 -+
4404 -+ if (!m_engine->isValid()) {
4405 -+ Plasma::DataEngineManager::self()->unloadEngine(engineName);
4406 -+ m_engine = 0;
4407 -+ return;
4408 -+ }
4409 -+
4410 -+ connect(m_engine, SIGNAL(sourceAdded(QString)),
4411 -+ this, SLOT(prepareJob(QString)));
4412 -+ connect(m_engine, SIGNAL(sourceRemoved(QString)),
4413 -+ this, SLOT(removeJob(QString)));
4414 -+}
4415 -+
4416 -+void DBusJobProtocol::prepareJob(const QString &source)
4417 -+{
4418 -+ m_engine->connectSource(source, this);
4419 -+}
4420 -+
4421 -+void DBusJobProtocol::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
4422 -+{
4423 -+ DBusJob *job = m_jobs.value(source, 0);
4424 -+
4425 -+ if (!job) {
4426 -+ job = new DBusJob(source, this);
4427 -+ m_jobs.insert(source, job);
4428 -+ connect(job, SIGNAL(jobDeleted(QString)),
4429 -+ this, SLOT(removeJob(QString)));
4430 -+ connect(job, SIGNAL(suspend(QString)),
4431 -+ this, SLOT(suspend(QString)));
4432 -+ connect(job, SIGNAL(resume(QString)),
4433 -+ this, SLOT(resume(QString)));
4434 -+ connect(job, SIGNAL(stop(QString)),
4435 -+ this, SLOT(stop(QString)));
4436 -+ connect(job, SIGNAL(ready(Job*)),
4437 -+ this, SIGNAL(jobCreated(Job*)));
4438 -+ }
4439 -+
4440 -+ job->setApplicationName(data.value("appName").toString());
4441 -+ job->setApplicationIconName(data.value("appIconName").toString());
4442 -+ job->setPercentage(data["percentage"].toUInt());
4443 -+ job->setError(data["error"].toString());
4444 -+ job->setMessage(data["infoMessage"].toString());
4445 -+ job->setSuspendable(data["suspendable"].toBool());
4446 -+ job->setKillable(data["killable"].toBool());
4447 -+ job->setSpeed(data["speed"].toString());
4448 -+ job->setNumericSpeed(data["numericSpeed"].toLongLong());
4449 -+ job->setEta(data["eta"].toULongLong());
4450 -+
4451 -+ if (data["state"].toString() == "running") {
4452 -+ job->setState(Job::Running);
4453 -+ } else if (data["state"].toString() == "suspended") {
4454 -+ job->setState(Job::Suspended);
4455 -+ } else {
4456 -+ job->setState(Job::Stopped);
4457 -+ }
4458 -+
4459 -+ int i = 0;
4460 -+ QList<QPair<QString, QString> > labels;
4461 -+ while (data.contains(QString("label%1").arg(i))) {
4462 -+ QPair<QString, QString> label;
4463 -+ label.first = data[QString("labelName%1").arg(i)].toString();
4464 -+ label.second = data[QString("label%1").arg(i)].toString();
4465 -+ labels << label;
4466 -+ i++;
4467 -+ }
4468 -+ job->setLabels(labels);
4469 -+
4470 -+ i = 0;
4471 -+ QMap<QString, qlonglong> totalAmounts;
4472 -+ while (data.contains(QString("totalUnit%1").arg(i))) {
4473 -+ QString unit = data[QString("totalUnit%1").arg(i)].toString();
4474 -+ qlonglong amount = data[QString("totalAmount%1").arg(i)].toLongLong();
4475 -+ totalAmounts[unit] = amount;
4476 -+ i++;
4477 -+ }
4478 -+ job->setTotalAmounts(totalAmounts);
4479 -+
4480 -+ i = 0;
4481 -+ QMap<QString, qlonglong> processedAmounts;
4482 -+ while (data.contains(QString("processedUnit%1").arg(i))) {
4483 -+ QString unit = data[QString("processedUnit%1").arg(i)].toString();
4484 -+ qlonglong amount = data[QString("processedAmount%1").arg(i)].toLongLong();
4485 -+ processedAmounts[unit] = amount;
4486 -+ i++;
4487 -+ }
4488 -+
4489 -+ job->setProcessedAmounts(processedAmounts);
4490 -+}
4491 -+
4492 -+void DBusJobProtocol::removeJob(const QString &source)
4493 -+{
4494 -+ if (m_jobs.contains(source)) {
4495 -+ DBusJob *job = m_jobs.take(source);
4496 -+ job->setState(Job::Stopped);
4497 -+ job->destroy();
4498 -+ }
4499 -+}
4500 -+
4501 -+void DBusJobProtocol::suspend(const QString &source)
4502 -+{
4503 -+ Plasma::Service *service = m_engine->serviceForSource(source);
4504 -+ KConfigGroup op = service->operationDescription("suspend");
4505 -+ KJob *job = service->startOperationCall(op);
4506 -+ connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater()));
4507 -+}
4508 -+
4509 -+void DBusJobProtocol::resume(const QString &source)
4510 -+{
4511 -+ Plasma::Service *service = m_engine->serviceForSource(source);
4512 -+ KConfigGroup op = service->operationDescription("resume");
4513 -+ KJob *job = service->startOperationCall(op);
4514 -+ connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater()));
4515 -+}
4516 -+
4517 -+void DBusJobProtocol::stop(const QString &source)
4518 -+{
4519 -+ Plasma::Service *service = m_engine->serviceForSource(source);
4520 -+ KConfigGroup op = service->operationDescription("stop");
4521 -+ KJob *job = service->startOperationCall(op);
4522 -+ connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater()));
4523 -+}
4524 -+
4525 -+#include "dbusjobprotocol.moc"
4526 -diff --git a/plasma/generic/applets/notifications/protocols/jobs/dbusjobprotocol.h b/plasma/generic/applets/notifications/protocols/jobs/dbusjobprotocol.h
4527 -new file mode 100644
4528 -index 0000000..230356c
4529 ---- /dev/null
4530 -+++ b/plasma/generic/applets/notifications/protocols/jobs/dbusjobprotocol.h
4531 -@@ -0,0 +1,57 @@
4532 -+/***************************************************************************
4533 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
4534 -+ * *
4535 -+ * This program is free software; you can redistribute it and/or modify *
4536 -+ * it under the terms of the GNU General Public License as published by *
4537 -+ * the Free Software Foundation; either version 2 of the License, or *
4538 -+ * (at your option) any later version. *
4539 -+ * *
4540 -+ * This program is distributed in the hope that it will be useful, *
4541 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4542 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4543 -+ * GNU General Public License for more details. *
4544 -+ * *
4545 -+ * You should have received a copy of the GNU General Public License *
4546 -+ * along with this program; if not, write to the *
4547 -+ * Free Software Foundation, Inc., *
4548 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4549 -+ ***************************************************************************/
4550 -+
4551 -+#ifndef DBUSJOBPROTOCOL_H
4552 -+#define DBUSJOBPROTOCOL_H
4553 -+
4554 -+#include "../../core/protocol.h"
4555 -+#include "../../core/notificationsmanager.h"
4556 -+
4557 -+#include <plasma/dataengine.h>
4558 -+
4559 -+
4560 -+class DBusJob;
4561 -+
4562 -+class DBusJobProtocol : public Protocol
4563 -+{
4564 -+ Q_OBJECT
4565 -+
4566 -+public:
4567 -+ DBusJobProtocol(Manager *parent);
4568 -+ ~DBusJobProtocol();
4569 -+ void init();
4570 -+
4571 -+private slots:
4572 -+ void prepareJob(const QString &source);
4573 -+ void dataUpdated(const QString &source, const Plasma::DataEngine::Data &data);
4574 -+ void removeJob(const QString &source);
4575 -+ //void relayAction(const QString &source, const QString &actionName);
4576 -+ void suspend(const QString &source);
4577 -+ void resume(const QString &source);
4578 -+ void stop(const QString &source);
4579 -+
4580 -+private:
4581 -+ Manager *m_manager;
4582 -+ Plasma::DataEngine *m_engine;
4583 -+ QHash<QString, DBusJob*> m_jobs;
4584 -+};
4585 -+
4586 -+
4587 -+
4588 -+#endif
4589 -diff --git a/plasma/generic/applets/notifications/protocols/notifications/dbusnotification.cpp b/plasma/generic/applets/notifications/protocols/notifications/dbusnotification.cpp
4590 -new file mode 100644
4591 -index 0000000..2c28ff2
4592 ---- /dev/null
4593 -+++ b/plasma/generic/applets/notifications/protocols/notifications/dbusnotification.cpp
4594 -@@ -0,0 +1,48 @@
4595 -+/***************************************************************************
4596 -+ * dbusnotification.cpp *
4597 -+ * *
4598 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
4599 -+ * *
4600 -+ * This program is free software; you can redistribute it and/or modify *
4601 -+ * it under the terms of the GNU General Public License as published by *
4602 -+ * the Free Software Foundation; either version 2 of the License, or *
4603 -+ * (at your option) any later version. *
4604 -+ * *
4605 -+ * This program is distributed in the hope that it will be useful, *
4606 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4607 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4608 -+ * GNU General Public License for more details. *
4609 -+ * *
4610 -+ * You should have received a copy of the GNU General Public License *
4611 -+ * along with this program; if not, write to the *
4612 -+ * Free Software Foundation, Inc., *
4613 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4614 -+ ***************************************************************************/
4615 -+
4616 -+#include "dbusnotification.h"
4617 -+
4618 -+#include <KDebug>
4619 -+
4620 -+
4621 -+DBusNotification::DBusNotification(const QString &source, QObject *parent)
4622 -+ : Notification(parent),
4623 -+ m_source(source)
4624 -+{
4625 -+}
4626 -+
4627 -+DBusNotification::~DBusNotification()
4628 -+{
4629 -+ emit notificationDeleted(m_source);
4630 -+}
4631 -+
4632 -+void DBusNotification::remove()
4633 -+{
4634 -+ emit unregisterNotification(m_source);
4635 -+ deleteLater();
4636 -+}
4637 -+
4638 -+void DBusNotification::triggerAction(const QString &actionId)
4639 -+{
4640 -+ emit actionTriggered(m_source, actionId);
4641 -+}
4642 -+
4643 -diff --git a/plasma/generic/applets/notifications/protocols/notifications/dbusnotification.h b/plasma/generic/applets/notifications/protocols/notifications/dbusnotification.h
4644 -new file mode 100644
4645 -index 0000000..213cc71
4646 ---- /dev/null
4647 -+++ b/plasma/generic/applets/notifications/protocols/notifications/dbusnotification.h
4648 -@@ -0,0 +1,54 @@
4649 -+/***************************************************************************
4650 -+ * dbusnotification.h *
4651 -+ * *
4652 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
4653 -+ * *
4654 -+ * This program is free software; you can redistribute it and/or modify *
4655 -+ * it under the terms of the GNU General Public License as published by *
4656 -+ * the Free Software Foundation; either version 2 of the License, or *
4657 -+ * (at your option) any later version. *
4658 -+ * *
4659 -+ * This program is distributed in the hope that it will be useful, *
4660 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4661 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4662 -+ * GNU General Public License for more details. *
4663 -+ * *
4664 -+ * You should have received a copy of the GNU General Public License *
4665 -+ * along with this program; if not, write to the *
4666 -+ * Free Software Foundation, Inc., *
4667 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4668 -+ ***************************************************************************/
4669 -+
4670 -+#ifndef DBUSNOTIFICATION_H
4671 -+#define DBUSNOTIFICATION_H
4672 -+
4673 -+#include "../../core/notification.h"
4674 -+
4675 -+
4676 -+
4677 -+class DBusNotification : public Notification
4678 -+{
4679 -+ Q_OBJECT
4680 -+
4681 -+ friend class DBusNotificationProtocol;
4682 -+
4683 -+public:
4684 -+ DBusNotification(const QString &source, QObject *parent = 0);
4685 -+ ~DBusNotification();
4686 -+
4687 -+public slots:
4688 -+ void remove();
4689 -+ void triggerAction(const QString &actionId);
4690 -+
4691 -+signals:
4692 -+ void notificationDeleted(const QString &source);
4693 -+ void actionTriggered(const QString &source, const QString &actionId);
4694 -+ void unregisterNotification(const QString &source);
4695 -+
4696 -+private:
4697 -+ QString m_source;
4698 -+};
4699 -+
4700 -+
4701 -+
4702 -+#endif
4703 -diff --git a/plasma/generic/applets/notifications/protocols/notifications/dbusnotificationprotocol.cpp b/plasma/generic/applets/notifications/protocols/notifications/dbusnotificationprotocol.cpp
4704 -new file mode 100644
4705 -index 0000000..fd94048
4706 ---- /dev/null
4707 -+++ b/plasma/generic/applets/notifications/protocols/notifications/dbusnotificationprotocol.cpp
4708 -@@ -0,0 +1,192 @@
4709 -+/***************************************************************************
4710 -+ * fdoprotocol.cpp *
4711 -+ * *
4712 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
4713 -+ * *
4714 -+ * This program is free software; you can redistribute it and/or modify *
4715 -+ * it under the terms of the GNU General Public License as published by *
4716 -+ * the Free Software Foundation; either version 2 of the License, or *
4717 -+ * (at your option) any later version. *
4718 -+ * *
4719 -+ * This program is distributed in the hope that it will be useful, *
4720 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4721 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4722 -+ * GNU General Public License for more details. *
4723 -+ * *
4724 -+ * You should have received a copy of the GNU General Public License *
4725 -+ * along with this program; if not, write to the *
4726 -+ * Free Software Foundation, Inc., *
4727 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4728 -+ ***************************************************************************/
4729 -+
4730 -+#include "dbusnotification.h"
4731 -+#include "dbusnotificationprotocol.h"
4732 -+
4733 -+#include <KConfigGroup>
4734 -+#include <KDebug>
4735 -+#include <KIcon>
4736 -+
4737 -+#include <Plasma/DataEngineManager>
4738 -+#include <Plasma/Service>
4739 -+#include <Plasma/ServiceJob>
4740 -+
4741 -+
4742 -+static const char engineName[] = "notifications";
4743 -+
4744 -+DBusNotificationProtocol::DBusNotificationProtocol(Manager *parent)
4745 -+ : Protocol(parent),
4746 -+ m_manager(parent),
4747 -+ m_engine(0)
4748 -+{
4749 -+}
4750 -+
4751 -+
4752 -+DBusNotificationProtocol::~DBusNotificationProtocol()
4753 -+{
4754 -+ if (m_engine) {
4755 -+ Plasma::DataEngineManager::self()->unloadEngine(engineName);
4756 -+ }
4757 -+}
4758 -+
4759 -+
4760 -+void DBusNotificationProtocol::init()
4761 -+{
4762 -+ m_engine = Plasma::DataEngineManager::self()->loadEngine(engineName);
4763 -+
4764 -+ if (!m_engine->isValid()) {
4765 -+ m_engine = 0;
4766 -+ Plasma::DataEngineManager::self()->unloadEngine(engineName);
4767 -+ return;
4768 -+ }
4769 -+
4770 -+ connect(m_engine, SIGNAL(sourceAdded(QString)),
4771 -+ this, SLOT(prepareNotification(QString)));
4772 -+ connect(m_engine, SIGNAL(sourceRemoved(QString)),
4773 -+ this, SLOT(hideNotification(QString)));
4774 -+}
4775 -+
4776 -+
4777 -+void DBusNotificationProtocol::prepareNotification(const QString &source)
4778 -+{
4779 -+ if (m_engine) {
4780 -+ m_engine->connectSource(source, this);
4781 -+ }
4782 -+}
4783 -+
4784 -+
4785 -+void DBusNotificationProtocol::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
4786 -+{
4787 -+ bool isNew = !m_notifications.contains(source);
4788 -+
4789 -+ if (isNew) {
4790 -+ DBusNotification * notification = new DBusNotification(source, this);
4791 -+ connect(notification, SIGNAL(unregisterNotification(QString)),
4792 -+ this, SLOT(unregisterNotification(QString)));
4793 -+ connect(notification, SIGNAL(notificationDeleted(QString)),
4794 -+ this, SLOT(notificationDeleted(QString)));
4795 -+ connect(notification, SIGNAL(actionTriggered(QString,QString)),
4796 -+ this, SLOT(relayAction(QString,QString)));
4797 -+ m_notifications[source] = notification;
4798 -+ }
4799 -+
4800 -+ DBusNotification* notification = m_notifications[source];
4801 -+ notification->setApplicationName(data.value("appName").toString());
4802 -+ notification->setApplicationIcon(KIcon(data.value("appIcon").toString()));
4803 -+ notification->setSummary(data.value("summary").toString());
4804 -+ notification->setMessage(data.value("body").toString());
4805 -+ notification->setTimeout(data.value("expireTimeout").toInt());
4806 -+ notification->setUrgency(data.value("urgency").toInt());
4807 -+
4808 -+ if (data.contains("image")) {
4809 -+ QImage image = qvariant_cast<QImage>(data.value("image"));
4810 -+ notification->setImage(image);
4811 -+ }
4812 -+
4813 -+ QStringList codedActions = data.value("actions").toStringList();
4814 -+ if (codedActions.count() % 2 != 0) {
4815 -+ kDebug() << "Invalid actions" << codedActions << "from" << notification->applicationName();
4816 -+ codedActions.clear();
4817 -+ }
4818 -+
4819 -+ QHash<QString, QString> actions;
4820 -+ QStringList actionOrder;
4821 -+
4822 -+ while (!codedActions.isEmpty()) {
4823 -+ QString actionId = codedActions.takeFirst();
4824 -+ QString actionName = codedActions.takeFirst();
4825 -+ actions.insert(actionId, actionName);
4826 -+ actionOrder.append(actionId);
4827 -+ }
4828 -+
4829 -+ notification->setActions(actions);
4830 -+ notification->setActionOrder(actionOrder);
4831 -+
4832 -+ if (isNew) {
4833 -+ emit notificationCreated(notification);
4834 -+ } else {
4835 -+ emit notification->changed(notification);
4836 -+ }
4837 -+}
4838 -+
4839 -+
4840 -+void DBusNotificationProtocol::relayAction(const QString &source, const QString &actionId)
4841 -+{
4842 -+ if (!m_engine) {
4843 -+ return;
4844 -+ }
4845 -+
4846 -+ Plasma::Service *service = m_engine->serviceForSource(source);
4847 -+ KConfigGroup op = service->operationDescription("invokeAction");
4848 -+
4849 -+ if (op.isValid()) {
4850 -+ op.writeEntry("actionId", actionId);
4851 -+ KJob *job = service->startOperationCall(op);
4852 -+ connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater()));
4853 -+ } else {
4854 -+ delete service;
4855 -+ kDebug() << "invalid operation";
4856 -+ }
4857 -+}
4858 -+
4859 -+void DBusNotificationProtocol::unregisterNotification(const QString &source)
4860 -+{
4861 -+ if (!m_engine) {
4862 -+ return;
4863 -+ }
4864 -+
4865 -+ Plasma::Service *service = m_engine->serviceForSource(source);
4866 -+ KConfigGroup op = service->operationDescription("userClosed");
4867 -+ KJob *job = service->startOperationCall(op);
4868 -+ connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater()));
4869 -+}
4870 -+
4871 -+void DBusNotificationProtocol::hideNotification(const QString &source)
4872 -+{
4873 -+ if (m_notifications.contains(source)) {
4874 -+ m_notifications.value(source)->hide();
4875 -+ }
4876 -+}
4877 -+
4878 -+void DBusNotificationProtocol::removeNotification(const QString &source)
4879 -+{
4880 -+ if (m_notifications.contains(source)) {
4881 -+ m_notifications.take(source)->destroy();
4882 -+ }
4883 -+}
4884 -+
4885 -+void DBusNotificationProtocol::notificationDeleted(const QString &source)
4886 -+{
4887 -+ if (!m_engine) {
4888 -+ return;
4889 -+ }
4890 -+
4891 -+ Plasma::Service *service = m_engine->serviceForSource(source);
4892 -+ KConfigGroup op = service->operationDescription("userClosed");
4893 -+ KJob *job = service->startOperationCall(op);
4894 -+ connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater()));
4895 -+
4896 -+ m_notifications.remove(source);
4897 -+}
4898 -+
4899 -+
4900 -+#include "dbusnotificationprotocol.moc"
4901 -diff --git a/plasma/generic/applets/notifications/protocols/notifications/dbusnotificationprotocol.h b/plasma/generic/applets/notifications/protocols/notifications/dbusnotificationprotocol.h
4902 -new file mode 100644
4903 -index 0000000..e52dfd9
4904 ---- /dev/null
4905 -+++ b/plasma/generic/applets/notifications/protocols/notifications/dbusnotificationprotocol.h
4906 -@@ -0,0 +1,62 @@
4907 -+/***************************************************************************
4908 -+ * dbusnotificationprotocol.h *
4909 -+ * *
4910 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
4911 -+ * Copyright (C) 2008 Dmitry Suzdalev <dimsuz@×××××.com> *
4912 -+ * *
4913 -+ * This program is free software; you can redistribute it and/or modify *
4914 -+ * it under the terms of the GNU General Public License as published by *
4915 -+ * the Free Software Foundation; either version 2 of the License, or *
4916 -+ * (at your option) any later version. *
4917 -+ * *
4918 -+ * This program is distributed in the hope that it will be useful, *
4919 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4920 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4921 -+ * GNU General Public License for more details. *
4922 -+ * *
4923 -+ * You should have received a copy of the GNU General Public License *
4924 -+ * along with this program; if not, write to the *
4925 -+ * Free Software Foundation, Inc., *
4926 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4927 -+ ***************************************************************************/
4928 -+
4929 -+#ifndef DBUSNOTIFICATIONPROTOCOL_H
4930 -+#define DBUSNOTIFICATIONPROTOCOL_H
4931 -+
4932 -+#include "../../core/protocol.h"
4933 -+#include "../../core/notificationsmanager.h"
4934 -+
4935 -+#include <QHash>
4936 -+
4937 -+#include <Plasma/DataEngine>
4938 -+
4939 -+
4940 -+class DBusNotification;
4941 -+
4942 -+class DBusNotificationProtocol : public Protocol
4943 -+{
4944 -+ Q_OBJECT
4945 -+
4946 -+public:
4947 -+ DBusNotificationProtocol(Manager *parent);
4948 -+ ~DBusNotificationProtocol();
4949 -+ void init();
4950 -+
4951 -+private slots:
4952 -+ void prepareNotification(const QString &source);
4953 -+ void dataUpdated(const QString &source, const Plasma::DataEngine::Data &data);
4954 -+ void removeNotification(const QString &source);
4955 -+ void notificationDeleted(const QString &source);
4956 -+ void relayAction(const QString &source, const QString &actionId);
4957 -+ void unregisterNotification(const QString&);
4958 -+ void hideNotification(const QString &source);
4959 -+
4960 -+private:
4961 -+ Manager *m_manager;
4962 -+ Plasma::DataEngine *m_engine;
4963 -+ QHash<QString, DBusNotification*> m_notifications;
4964 -+};
4965 -+
4966 -+
4967 -+
4968 -+#endif
4969 -diff --git a/plasma/generic/applets/notifications/ui/busywidget.cpp b/plasma/generic/applets/notifications/ui/busywidget.cpp
4970 -new file mode 100644
4971 -index 0000000..6bce0d7
4972 ---- /dev/null
4973 -+++ b/plasma/generic/applets/notifications/ui/busywidget.cpp
4974 -@@ -0,0 +1,352 @@
4975 -+/***************************************************************************
4976 -+ * Copyright (C) 2008, 2009 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
4977 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
4978 -+ * *
4979 -+ * This program is free software; you can redistribute it and/or modify *
4980 -+ * it under the terms of the GNU General Public License as published by *
4981 -+ * the Free Software Foundation; either version 2 of the License, or *
4982 -+ * (at your option) any later version. *
4983 -+ * *
4984 -+ * This program is distributed in the hope that it will be useful, *
4985 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
4986 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
4987 -+ * GNU General Public License for more details. *
4988 -+ * *
4989 -+ * You should have received a copy of the GNU General Public License *
4990 -+ * along with this program; if not, write to the *
4991 -+ * Free Software Foundation, Inc., *
4992 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
4993 -+ ***************************************************************************/
4994 -+
4995 -+#include "busywidget.h"
4996 -+#include <fixx11h.h>
4997 -+
4998 -+#include <QtGui/QPainter>
4999 -+#include <QtGui/QTextOption>
5000 -+#include <QtGui/QStyleOptionGraphicsItem>
5001 -+#include <QtGui/QWidget> // QWIDGETSIZE_MAX
5002 -+#include <QSequentialAnimationGroup>
5003 -+
5004 -+#include <plasma/extender.h>
5005 -+#include <plasma/extenderitem.h>
5006 -+#include <plasma/extendergroup.h>
5007 -+#include <plasma/popupapplet.h>
5008 -+#include <plasma/tooltipmanager.h>
5009 -+#include <plasma/theme.h>
5010 -+#include <Plasma/Animation>
5011 -+#include <Plasma/Animator>
5012 -+
5013 -+#include <KIcon>
5014 -+#include <KGlobalSettings>
5015 -+
5016 -+#include "../core/notificationsmanager.h"
5017 -+#include "../core/job.h"
5018 -+#include "../core/notification.h"
5019 -+#include "../core/completedjobnotification.h"
5020 -+
5021 -+
5022 -+
5023 -+BusyWidget::BusyWidget(Plasma::PopupApplet *parent, const Manager *manager)
5024 -+ : Plasma::BusyWidget(parent),
5025 -+ m_icon("dialog-information"),
5026 -+ m_state(Empty),
5027 -+ m_svg(new Plasma::Svg(this)),
5028 -+ m_systray(parent),
5029 -+ m_manager(manager),
5030 -+ m_total(0),
5031 -+ m_suppressToolTips(false)
5032 -+{
5033 -+ setAcceptsHoverEvents(true);
5034 -+ m_svg->setImagePath("icons/notification");
5035 -+ m_svg->setContainsMultipleImages(true);
5036 -+ setRunning(false);
5037 -+
5038 -+ m_fadeInAnimation = Plasma::Animator::create(Plasma::Animator::PixmapTransitionAnimation);
5039 -+ m_fadeInAnimation->setTargetWidget(this);
5040 -+ m_fadeInAnimation->setProperty("duration", 1000);
5041 -+ m_fadeInAnimation->setProperty("targetPixmap", m_svg->pixmap("notification-active"));
5042 -+
5043 -+ m_fadeOutAnimation = Plasma::Animator::create(Plasma::Animator::PixmapTransitionAnimation);
5044 -+ m_fadeOutAnimation->setTargetWidget(this);
5045 -+ m_fadeOutAnimation->setProperty("duration", 1000);
5046 -+ m_fadeOutAnimation->setProperty("startPixmap", m_svg->pixmap("notification-active"));
5047 -+
5048 -+
5049 -+ m_fadeGroup = new QSequentialAnimationGroup(this);
5050 -+ m_fadeGroup->addAnimation(m_fadeInAnimation);
5051 -+ m_fadeGroup->addAnimation(m_fadeOutAnimation);
5052 -+
5053 -+ connect(manager, SIGNAL(notificationAdded(Notification*)),
5054 -+ this, SLOT(updateTask()));
5055 -+ connect(manager, SIGNAL(notificationRemoved(Notification*)),
5056 -+ this, SLOT(updateTask()));
5057 -+ connect(manager, SIGNAL(notificationChanged(Notification*)),
5058 -+ this, SLOT(updateTask()));
5059 -+ connect(manager, SIGNAL(notificationExpired(Notification*)),
5060 -+ this, SLOT(updateTask()));
5061 -+ connect(manager, SIGNAL(jobAdded(Job*)),
5062 -+ this, SLOT(updateTask()));
5063 -+ connect(manager, SIGNAL(jobRemoved(Job*)),
5064 -+ this, SLOT(updateTask()));
5065 -+ connect(manager, SIGNAL(jobStateChanged(Job*)),
5066 -+ this, SLOT(updateTask()));
5067 -+
5068 -+ Plasma::Extender *extender = qobject_cast<Plasma::Extender *>(m_systray->graphicsWidget());
5069 -+ if (extender) {
5070 -+ connect(extender, SIGNAL(itemDetached(Plasma::ExtenderItem*)),
5071 -+ this, SLOT(updateTask()));
5072 -+ }
5073 -+
5074 -+ Plasma::ToolTipManager::self()->registerWidget(this);
5075 -+ updateTask();
5076 -+}
5077 -+
5078 -+void BusyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
5079 -+{
5080 -+ QRectF iconRect(0, 0, qMin(size().width(), size().height()), qMin(size().width(), size().height()));
5081 -+ iconRect.moveCenter(boundingRect().center());
5082 -+
5083 -+ if (m_state == Running) {
5084 -+ const int arcStart = 90*16;
5085 -+ const int arcEnd = -(360*(qreal)m_manager->jobTotals()->percentage()/100)*16;
5086 -+
5087 -+ Plasma::BusyWidget::paint(painter, option, widget);
5088 -+
5089 -+ //kDebug() << arcStart << arcEnd;
5090 -+
5091 -+ QPixmap activePixmap(iconRect.size().toSize());
5092 -+ activePixmap.fill(Qt::transparent);
5093 -+ QPixmap inActivePixmap(iconRect.size().toSize());
5094 -+ inActivePixmap.fill(Qt::transparent);
5095 -+ QRect pieRect(QPoint(0, 0), activePixmap.size()*2);
5096 -+ pieRect.moveCenter(activePixmap.rect().center());
5097 -+
5098 -+ QPainter p(&activePixmap);
5099 -+ p.setPen(Qt::NoPen);
5100 -+ p.setBrush(Qt::black);
5101 -+ p.setCompositionMode(QPainter::CompositionMode_Source);
5102 -+ p.drawPie(pieRect, arcStart, arcEnd);
5103 -+ p.setCompositionMode(QPainter::CompositionMode_SourceIn);
5104 -+ m_svg->paint(&p, QRectF(QPointF(0, 0), iconRect.size()), "notification-progress-active");
5105 -+ p.end();
5106 -+
5107 -+ p.begin(&inActivePixmap);
5108 -+ p.setPen(Qt::NoPen);
5109 -+ p.setBrush(Qt::black);
5110 -+ p.setCompositionMode(QPainter::CompositionMode_Source);
5111 -+ p.drawPie(pieRect, arcStart, (360*16)+arcEnd);
5112 -+ p.setCompositionMode(QPainter::CompositionMode_SourceIn);
5113 -+ m_svg->paint(&p, QRectF(QPointF(0, 0), iconRect.size()), "notification-progress-inactive");
5114 -+ p.end();
5115 -+
5116 -+ painter->drawPixmap(iconRect.topLeft().toPoint(), activePixmap);
5117 -+ painter->drawPixmap(iconRect.topLeft().toPoint(), inActivePixmap);
5118 -+
5119 -+ Plasma::BusyWidget::paint(painter, option, widget);
5120 -+
5121 -+ } else if (m_state == Empty && m_manager->notifications().count() > 0) {
5122 -+ m_svg->paint(painter, iconRect, "notification-inactive");
5123 -+ } else if (m_state == Empty && m_manager->notifications().count() == 0) {
5124 -+ m_svg->paint(painter, iconRect, "notification-disabled");
5125 -+ } else {
5126 -+ // m_state == Info
5127 -+ m_svg->paint(painter, iconRect, "notification-empty");
5128 -+ QFont font(KGlobalSettings::smallestReadableFont());
5129 -+ painter->setFont(font);
5130 -+ QRectF r = rect();
5131 -+
5132 -+ painter->setPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
5133 -+
5134 -+ const QFontMetrics fm(font);
5135 -+ const QSize textSize = fm.boundingRect(label()).size();
5136 -+ const bool textFits = textSize.width() <= r.width() && textSize.height() <= r.height();
5137 -+ if (m_svg && m_svg->hasElement(expanderElement())) {
5138 -+ QSizeF arrowSize(m_svg->elementSize(expanderElement()));
5139 -+ QRectF arrowRect(r.center() - QPointF(arrowSize.width() / 2, arrowSize.height() + fm.xHeight() / 2), arrowSize);
5140 -+ m_svg->paint(painter, arrowRect, expanderElement());
5141 -+
5142 -+ r.setTop(arrowRect.bottom());
5143 -+
5144 -+ if (textFits) {
5145 -+ painter->drawText(r, Qt::AlignHCenter|Qt::AlignTop, label());
5146 -+ }
5147 -+ } else if (textFits) {
5148 -+ painter->drawText(r, Qt::AlignCenter, label());
5149 -+ }
5150 -+ }
5151 -+
5152 -+ if (m_fadeInAnimation->state() == QAbstractAnimation::Running) {
5153 -+ QPixmap pix = m_fadeInAnimation->property("currentPixmap").value<QPixmap>();
5154 -+ painter->drawPixmap(iconRect, pix, pix.rect());
5155 -+ } else if (m_fadeOutAnimation->state() == QAbstractAnimation::Running) {
5156 -+ QPixmap pix = m_fadeOutAnimation->property("currentPixmap").value<QPixmap>();
5157 -+ painter->drawPixmap(iconRect, pix, pix.rect());
5158 -+ }
5159 -+}
5160 -+
5161 -+void BusyWidget::resizeEvent(QGraphicsSceneResizeEvent *)
5162 -+{
5163 -+ //regenerate pixmaps
5164 -+ m_svg->resize(contentsRect().size());
5165 -+ m_fadeInAnimation->setProperty("targetPixmap", m_svg->pixmap("notification-active"));
5166 -+ m_fadeOutAnimation->setProperty("startPixmap", m_svg->pixmap("notification-active"));
5167 -+ m_svg->resize();
5168 -+}
5169 -+
5170 -+void BusyWidget::setState(State state)
5171 -+{
5172 -+ if (m_state == state) {
5173 -+ return;
5174 -+ }
5175 -+
5176 -+ m_state = state;
5177 -+ setRunning(m_state == Running);
5178 -+ update();
5179 -+}
5180 -+
5181 -+QString BusyWidget::expanderElement() const
5182 -+{
5183 -+ switch (m_systray->location()) {
5184 -+ case Plasma::TopEdge:
5185 -+ return "expander-top";
5186 -+ case Plasma::RightEdge:
5187 -+ return "expander-right";
5188 -+ case Plasma::LeftEdge:
5189 -+ return "expander-left";
5190 -+ case Plasma::BottomEdge:
5191 -+ default:
5192 -+ return "expander-bottom";
5193 -+ }
5194 -+}
5195 -+
5196 -+void BusyWidget::getJobCounts(int &runningJobs, int &pausedJobs, int &completedJobs, int &jobSpeed)
5197 -+{
5198 -+ runningJobs = pausedJobs = completedJobs = jobSpeed = 0;
5199 -+ foreach (const Job *job, m_manager->jobs()) {
5200 -+ switch (job->state()) {
5201 -+ case Job::Running:
5202 -+ jobSpeed += job->numericSpeed();
5203 -+ ++runningJobs;
5204 -+ break;
5205 -+ case Job::Suspended:
5206 -+ ++pausedJobs;
5207 -+ break;
5208 -+ default:
5209 -+ break;
5210 -+ }
5211 -+ }
5212 -+
5213 -+}
5214 -+
5215 -+void BusyWidget::updateTask()
5216 -+{
5217 -+ int runningJobs, pausedJobs, completedJobs, jobSpeed;
5218 -+ getJobCounts(runningJobs, pausedJobs, completedJobs, jobSpeed);
5219 -+
5220 -+ int total = m_manager->jobs().count();
5221 -+ int activeNotifications = 0;
5222 -+ bool hasOldNotifications = false;
5223 -+
5224 -+ foreach (Notification *notification, m_manager->notifications()) {
5225 -+ if (qobject_cast<CompletedJobNotification *>(notification)) {
5226 -+ ++completedJobs;
5227 -+ } else if (notification->isExpired()) {
5228 -+ hasOldNotifications = true;
5229 -+ } else {
5230 -+ ++activeNotifications;
5231 -+ }
5232 -+ }
5233 -+
5234 -+ total += completedJobs + activeNotifications;
5235 -+
5236 -+ if (total + m_manager->notifications().count() < 0) {
5237 -+ m_systray->hidePopup();
5238 -+ }
5239 -+
5240 -+ if (total > m_total) {
5241 -+ m_fadeGroup->start();
5242 -+ }
5243 -+
5244 -+ m_total = total;
5245 -+
5246 -+ if (activeNotifications > 0) {
5247 -+ m_systray->setStatus(Plasma::NeedsAttentionStatus);
5248 -+ } else if (m_total > 0 || hasOldNotifications) {
5249 -+ m_systray->setStatus(Plasma::ActiveStatus);
5250 -+ } else {
5251 -+ m_systray->setStatus(Plasma::PassiveStatus);
5252 -+ }
5253 -+
5254 -+ if (!total) {
5255 -+ setState(BusyWidget::Empty);
5256 -+ setLabel(QString());
5257 -+ } else if (runningJobs) {
5258 -+ setState(BusyWidget::Running);
5259 -+ setLabel(QString("%1").arg(QString::number(total)));
5260 -+ } else {
5261 -+ setState(BusyWidget::Info);
5262 -+ setLabel(QString::number(total));
5263 -+ }
5264 -+
5265 -+ if (Plasma::ToolTipManager::self()->isVisible(this)) {
5266 -+ toolTipAboutToShow();
5267 -+ }
5268 -+}
5269 -+
5270 -+void BusyWidget::suppressToolTips(bool suppress)
5271 -+{
5272 -+ m_suppressToolTips = suppress;
5273 -+}
5274 -+
5275 -+void BusyWidget::toolTipAboutToShow()
5276 -+{
5277 -+ if (m_suppressToolTips) {
5278 -+ Plasma::ToolTipManager::self()->setContent(this, Plasma::ToolTipContent());
5279 -+ return;
5280 -+ }
5281 -+
5282 -+ int runningJobs, pausedJobs, completedJobs, jobSpeed;
5283 -+ getJobCounts(runningJobs, pausedJobs, completedJobs, jobSpeed);
5284 -+
5285 -+ //make a nice plasma tooltip
5286 -+ QString tooltipContent;
5287 -+ if (runningJobs > 0) {
5288 -+ tooltipContent += i18ncp("Number of jobs and the speed at which they are downloading",
5289 -+ "%1 running job (%2/s)", "%1 running jobs (%2/s)", runningJobs,
5290 -+ KGlobal::locale()->formatByteSize(jobSpeed));
5291 -+ if (pausedJobs > 0 || completedJobs > 0 || !m_manager->notifications().isEmpty()) {
5292 -+ tooltipContent += "<br>";
5293 -+ }
5294 -+ }
5295 -+
5296 -+ if (pausedJobs > 0) {
5297 -+ tooltipContent += i18np("%1 suspended job", "%1 suspended jobs", pausedJobs);
5298 -+ if (completedJobs > 0 || !m_manager->notifications().isEmpty()) {
5299 -+ tooltipContent += "<br>";
5300 -+ }
5301 -+ }
5302 -+
5303 -+ if (completedJobs > 0) {
5304 -+ tooltipContent += i18np("%1 completed job", "%1 completed jobs", completedJobs);
5305 -+ if (!m_manager->notifications().isEmpty()) {
5306 -+ tooltipContent += "<br>";
5307 -+ }
5308 -+ }
5309 -+
5310 -+ if (!m_manager->notifications().isEmpty()) {
5311 -+ tooltipContent += i18np("%1 notification", "%1 notifications",
5312 -+ m_manager->notifications().count());
5313 -+ }
5314 -+
5315 -+ if (tooltipContent.isEmpty()) {
5316 -+ tooltipContent = i18n("No active jobs or notifications");
5317 -+ }
5318 -+
5319 -+ Plasma::ToolTipContent data(i18n("Notifications and jobs"),
5320 -+ tooltipContent,
5321 -+ KIcon("help-about"));
5322 -+ Plasma::ToolTipManager::self()->setContent(this, data);
5323 -+}
5324 -+
5325 -+
5326 -+#include "busywidget.moc"
5327 -diff --git a/plasma/generic/applets/notifications/ui/busywidget.h b/plasma/generic/applets/notifications/ui/busywidget.h
5328 -new file mode 100644
5329 -index 0000000..ae5f994
5330 ---- /dev/null
5331 -+++ b/plasma/generic/applets/notifications/ui/busywidget.h
5332 -@@ -0,0 +1,80 @@
5333 -+/***************************************************************************
5334 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
5335 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
5336 -+ * *
5337 -+ * This program is free software; you can redistribute it and/or modify *
5338 -+ * it under the terms of the GNU General Public License as published by *
5339 -+ * the Free Software Foundation; either version 2 of the License, or *
5340 -+ * (at your option) any later version. *
5341 -+ * *
5342 -+ * This program is distributed in the hope that it will be useful, *
5343 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
5344 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
5345 -+ * GNU General Public License for more details. *
5346 -+ * *
5347 -+ * You should have received a copy of the GNU General Public License *
5348 -+ * along with this program; if not, write to the *
5349 -+ * Free Software Foundation, Inc., *
5350 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
5351 -+ ***************************************************************************/
5352 -+
5353 -+#ifndef NOTIFICATIONBUSYWIDGET_H
5354 -+#define NOTIFICATIONBUSYWIDGET_H
5355 -+
5356 -+#include <KIcon>
5357 -+
5358 -+#include <Plasma/BusyWidget>
5359 -+
5360 -+class QStyleOptionGraphicsItem;
5361 -+class QSequentialAnimationGroup;
5362 -+
5363 -+namespace Plasma
5364 -+{
5365 -+ class Animation;
5366 -+ class Extender;
5367 -+ class PopupApplet;
5368 -+ class Svg;
5369 -+}
5370 -+
5371 -+
5372 -+class Manager;
5373 -+
5374 -+class BusyWidget : public Plasma::BusyWidget
5375 -+{
5376 -+ Q_OBJECT
5377 -+
5378 -+public:
5379 -+ enum State { Empty, Info, Running };
5380 -+
5381 -+ BusyWidget(Plasma::PopupApplet *parent, const Manager *manager);
5382 -+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
5383 -+ void setState(State state);
5384 -+ void suppressToolTips(bool suppress);
5385 -+
5386 -+public slots:
5387 -+ void toolTipAboutToShow();
5388 -+
5389 -+protected:
5390 -+ void resizeEvent(QGraphicsSceneResizeEvent *event);
5391 -+
5392 -+protected slots:
5393 -+ void updateTask();
5394 -+
5395 -+private:
5396 -+ QString expanderElement() const;
5397 -+ void getJobCounts(int &runningJobs, int &pausedJobs, int &completedJobs, int &jobSpeed);
5398 -+
5399 -+ KIcon m_icon;
5400 -+ State m_state;
5401 -+ Plasma::Svg *m_svg;
5402 -+ Plasma::PopupApplet *m_systray;
5403 -+ const Manager *m_manager;
5404 -+ Plasma::Animation *m_fadeInAnimation;
5405 -+ Plasma::Animation *m_fadeOutAnimation;
5406 -+ QSequentialAnimationGroup *m_fadeGroup;
5407 -+ int m_total;
5408 -+ bool m_suppressToolTips;
5409 -+};
5410 -+
5411 -+
5412 -+#endif
5413 -diff --git a/plasma/generic/applets/notifications/ui/jobtotalswidget.cpp b/plasma/generic/applets/notifications/ui/jobtotalswidget.cpp
5414 -new file mode 100644
5415 -index 0000000..6552ed3
5416 ---- /dev/null
5417 -+++ b/plasma/generic/applets/notifications/ui/jobtotalswidget.cpp
5418 -@@ -0,0 +1,94 @@
5419 -+/***************************************************************************
5420 -+ * Copyright 2009 by Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
5421 -+ * *
5422 -+ * This program is free software; you can redistribute it and/or modify *
5423 -+ * it under the terms of the GNU General Public License as published by *
5424 -+ * the Free Software Foundation; either version 2 of the License, or *
5425 -+ * (at your option) any later version. *
5426 -+ * *
5427 -+ * This program is distributed in the hope that it will be useful, *
5428 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
5429 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
5430 -+ * GNU General Public License for more details. *
5431 -+ * *
5432 -+ * You should have received a copy of the GNU General Public License *
5433 -+ * along with this program; if not, write to the *
5434 -+ * Free Software Foundation, Inc., *
5435 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
5436 -+ ***************************************************************************/
5437 -+
5438 -+#include "jobtotalswidget.h"
5439 -+#include "../core/job.h"
5440 -+
5441 -+#include <Plasma/ExtenderItem>
5442 -+#include <Plasma/Meter>
5443 -+
5444 -+static const int UPDATE_TIMER_INTERVAL = 200;
5445 -+
5446 -+
5447 -+JobTotalsWidget::JobTotalsWidget(Job *job, QGraphicsWidget *parent)
5448 -+ : Meter(parent),
5449 -+ m_job(job),
5450 -+ m_updateTimerId(0)
5451 -+{
5452 -+ m_extenderGroup = qobject_cast<Plasma::ExtenderGroup *>(parent),
5453 -+
5454 -+ setSvg("widgets/bar_meter_horizontal");
5455 -+ setMeterType(Plasma::Meter::BarMeterHorizontal);
5456 -+
5457 -+ setMinimumWidth(350);
5458 -+ setMinimumHeight(16);
5459 -+ setMaximumHeight(16);
5460 -+ setMaximum(100);
5461 -+ setValue(0);
5462 -+
5463 -+ if (m_job) {
5464 -+ connect(m_job, SIGNAL(changed(Job*)),
5465 -+ this, SLOT(scheduleJobUpdate()));
5466 -+
5467 -+ updateJob();
5468 -+ }
5469 -+}
5470 -+
5471 -+JobTotalsWidget::~JobTotalsWidget()
5472 -+{
5473 -+}
5474 -+
5475 -+void JobTotalsWidget::scheduleJobUpdate()
5476 -+{
5477 -+ if (!m_updateTimerId) {
5478 -+ m_updateTimerId = startTimer(UPDATE_TIMER_INTERVAL);
5479 -+ }
5480 -+}
5481 -+
5482 -+void JobTotalsWidget::timerEvent(QTimerEvent *event)
5483 -+{
5484 -+ if (event->timerId() == m_updateTimerId) {
5485 -+ killTimer(m_updateTimerId);
5486 -+ m_updateTimerId = 0;
5487 -+ updateJob();
5488 -+ } else {
5489 -+ Meter::timerEvent(event);
5490 -+ }
5491 -+}
5492 -+
5493 -+void JobTotalsWidget::updateJob()
5494 -+{
5495 -+ setValue(m_job->percentage());
5496 -+
5497 -+ if (m_extenderGroup) {
5498 -+ if (m_extenderGroup->items().count() > 1 || m_extenderGroup->isGroupCollapsed()) {
5499 -+ m_extenderGroup->setTitle(m_job->message());
5500 -+ } else {
5501 -+ m_extenderGroup->setTitle(i18nc("Generic title for the job transfer popup", "Jobs"));
5502 -+ }
5503 -+ m_extenderGroup->setIcon(m_job->applicationIconName());
5504 -+ } else {
5505 -+ setLabelAlignment(0, Qt::AlignLeft|Qt::AlignVCenter);
5506 -+ setLabel(0, m_job->message());
5507 -+ }
5508 -+}
5509 -+
5510 -+
5511 -+#include "jobtotalswidget.moc"
5512 -+
5513 -diff --git a/plasma/generic/applets/notifications/ui/jobtotalswidget.h b/plasma/generic/applets/notifications/ui/jobtotalswidget.h
5514 -new file mode 100644
5515 -index 0000000..4f07c86
5516 ---- /dev/null
5517 -+++ b/plasma/generic/applets/notifications/ui/jobtotalswidget.h
5518 -@@ -0,0 +1,65 @@
5519 -+/***************************************************************************
5520 -+ * Copyright 2009 by Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl *
5521 -+ * *
5522 -+ * This program is free software; you can redistribute it and/or modify *
5523 -+ * it under the terms of the GNU General Public License as published by *
5524 -+ * the Free Software Foundation; either version 2 of the License, or *
5525 -+ * (at your option) any later version. *
5526 -+ * *
5527 -+ * This program is distributed in the hope that it will be useful, *
5528 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
5529 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
5530 -+ * GNU General Public License for more details. *
5531 -+ * *
5532 -+ * You should have received a copy of the GNU General Public License *
5533 -+ * along with this program; if not, write to the *
5534 -+ * Free Software Foundation, Inc., *
5535 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
5536 -+ ***************************************************************************/
5537 -+
5538 -+#ifndef JOBTOTALSWIDGET_H
5539 -+#define JOBTOTALSWIDGET_H
5540 -+
5541 -+#include "../core/job.h"
5542 -+
5543 -+
5544 -+#include <QGraphicsWidget>
5545 -+
5546 -+#include <plasma/widgets/meter.h>
5547 -+#include <Plasma/Service>
5548 -+#include <Plasma/ExtenderGroup>
5549 -+#include <plasma/dataengine.h>
5550 -+
5551 -+namespace Plasma
5552 -+{
5553 -+ class ExtenderItem;
5554 -+ class Meter;
5555 -+} // namespace Plasma
5556 -+
5557 -+
5558 -+class Job;
5559 -+
5560 -+class JobTotalsWidget : public Plasma::Meter
5561 -+{
5562 -+ Q_OBJECT
5563 -+
5564 -+ public:
5565 -+ explicit JobTotalsWidget(Job *job, QGraphicsWidget *parent);
5566 -+ ~JobTotalsWidget();
5567 -+
5568 -+ protected:
5569 -+ void timerEvent(QTimerEvent *event);
5570 -+
5571 -+ private Q_SLOTS:
5572 -+ void scheduleJobUpdate();
5573 -+
5574 -+ private:
5575 -+ void updateJob();
5576 -+
5577 -+ Plasma::ExtenderGroup *m_extenderGroup;
5578 -+ Job *m_job;
5579 -+ int m_updateTimerId;
5580 -+};
5581 -+
5582 -+
5583 -+#endif
5584 -diff --git a/plasma/generic/applets/notifications/ui/jobwidget.cpp b/plasma/generic/applets/notifications/ui/jobwidget.cpp
5585 -new file mode 100644
5586 -index 0000000..06096fd
5587 ---- /dev/null
5588 -+++ b/plasma/generic/applets/notifications/ui/jobwidget.cpp
5589 -@@ -0,0 +1,435 @@
5590 -+/***************************************************************************
5591 -+ * Copyright 2008 by Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
5592 -+ * *
5593 -+ * This program is free software; you can redistribute it and/or modify *
5594 -+ * it under the terms of the GNU General Public License as published by *
5595 -+ * the Free Software Foundation; either version 2 of the License, or *
5596 -+ * (at your option) any later version. *
5597 -+ * *
5598 -+ * This program is distributed in the hope that it will be useful, *
5599 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
5600 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
5601 -+ * GNU General Public License for more details. *
5602 -+ * *
5603 -+ * You should have received a copy of the GNU General Public License *
5604 -+ * along with this program; if not, write to the *
5605 -+ * Free Software Foundation, Inc., *
5606 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
5607 -+ ***************************************************************************/
5608 -+
5609 -+#include "jobwidget.h"
5610 -+#include "../core/job.h"
5611 -+
5612 -+
5613 -+#include <QFont>
5614 -+#include <QAction>
5615 -+#include <QGraphicsGridLayout>
5616 -+#include <QLabel>
5617 -+
5618 -+#include <KIconLoader>
5619 -+
5620 -+#include <Plasma/DataEngine>
5621 -+#include <Plasma/Extender>
5622 -+#include <Plasma/ExtenderItem>
5623 -+#include <Plasma/Label>
5624 -+#include <Plasma/Meter>
5625 -+#include <Plasma/PopupApplet>
5626 -+#include <Plasma/PushButton>
5627 -+#include <Plasma/Service>
5628 -+#include <Plasma/SignalPlotter>
5629 -+#include <Plasma/IconWidget>
5630 -+#include <Plasma/Theme>
5631 -+#include <Plasma/ToolTipManager>
5632 -+
5633 -+static const int UPDATE_INTERVAL = 200;
5634 -+
5635 -+JobWidget::JobWidget(Job *job, Plasma::ExtenderItem *parent)
5636 -+ : QGraphicsWidget(parent),
5637 -+ m_extenderItem(parent),
5638 -+ m_job(job),
5639 -+ m_updateTimerId(0),
5640 -+ m_extenderItemDestroyed(false)
5641 -+{
5642 -+ Q_ASSERT(m_extenderItem);
5643 -+
5644 -+ m_meter = new Plasma::Meter(this);
5645 -+ m_meter->setSvg("widgets/bar_meter_horizontal");
5646 -+ m_meter->setMeterType(Plasma::Meter::BarMeterHorizontal);
5647 -+ m_meter->setMaximumHeight(16);
5648 -+ m_meter->setMaximum(100);
5649 -+ m_meter->setValue(0);
5650 -+
5651 -+ m_plotter = new Plasma::SignalPlotter(this);
5652 -+ m_plotter->setUseAutoRange(true);
5653 -+ m_plotter->setShowVerticalLines(false);
5654 -+ m_plotter->setUnit(i18n("KiB/s"));
5655 -+ m_plotter->addPlot(Plasma::Theme::defaultTheme()->color(Plasma::Theme::HighlightColor));
5656 -+
5657 -+ m_fromNameLabel = new Plasma::Label(this);
5658 -+ m_fromLabel = new Plasma::Label(this);
5659 -+ m_toNameLabel = new Plasma::Label(this);
5660 -+ m_toLabel = new Plasma::Label(this);
5661 -+ m_totalBytesLabel = new Plasma::Label(this);
5662 -+ m_dirCountLabel = new Plasma::Label(this);
5663 -+ m_fileCountLabel = new Plasma::Label(this);
5664 -+ m_eta = new Plasma::Label(this);
5665 -+ m_details = new Plasma::IconWidget(this);
5666 -+ m_details->setSvg("widgets/action-overlays", "add-normal");
5667 -+ m_details->setMaximumSize(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium);
5668 -+ m_details->setMinimumSize(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium);
5669 -+
5670 -+ m_totalBytesLabel->setVisible(false);
5671 -+ m_dirCountLabel->setVisible(false);
5672 -+ m_fileCountLabel->setVisible(false);
5673 -+ m_plotter->setVisible(false);
5674 -+
5675 -+ m_fromNameLabel->setAlignment(Qt::AlignRight);
5676 -+ m_fromLabel->setAlignment(Qt::AlignLeft);
5677 -+ m_toNameLabel->setAlignment(Qt::AlignRight);
5678 -+ m_toLabel->setAlignment(Qt::AlignLeft);
5679 -+ m_totalBytesLabel->setAlignment(Qt::AlignRight);
5680 -+ m_dirCountLabel->setAlignment(Qt::AlignRight);
5681 -+ m_fileCountLabel->setAlignment(Qt::AlignRight);
5682 -+ m_eta->setAlignment(Qt::AlignRight);
5683 -+
5684 -+ m_fromLabel->nativeWidget()->setWordWrap(false);
5685 -+ m_toLabel->nativeWidget()->setWordWrap(false);
5686 -+ m_dirCountLabel->nativeWidget()->setWordWrap(false);
5687 -+ m_fileCountLabel->nativeWidget()->setWordWrap(false);
5688 -+ m_totalBytesLabel->nativeWidget()->setWordWrap(false);
5689 -+ m_eta->nativeWidget()->setWordWrap(false);
5690 -+
5691 -+ m_layout = new QGraphicsGridLayout(this);
5692 -+ m_layout->addItem(m_fromNameLabel, 0, 0);
5693 -+ m_layout->addItem(m_fromLabel, 0, 1);
5694 -+ m_layout->addItem(m_toNameLabel, 1, 0);
5695 -+ m_layout->addItem(m_toLabel, 1, 1);
5696 -+ m_layout->addItem(m_eta, 2, 1);
5697 -+ m_layout->addItem(m_details, 3, 0, Qt::AlignVCenter|Qt::AlignRight);
5698 -+ m_layout->addItem(m_meter, 3, 1, Qt::AlignCenter);
5699 -+
5700 -+ setMinimumWidth(350);
5701 -+
5702 -+ if (m_job.data()) {
5703 -+ m_details->setToolTip(i18n("More"));
5704 -+ m_details->setSvg("widgets/action-overlays", "add-normal");
5705 -+
5706 -+ connect(m_job.data(), SIGNAL(stateChanged(Job*)), this, SLOT(updateJobState()));
5707 -+ connect(m_job.data(), SIGNAL(destroyed(Job*)), this, SLOT(destroyExtenderItem()));
5708 -+ connect(m_details, SIGNAL(clicked()), this, SLOT(detailsClicked()));
5709 -+
5710 -+ //the suspend action
5711 -+ QAction *suspendAction = new QAction(m_extenderItem);
5712 -+ suspendAction->setIcon(KIcon("media-playback-pause"));
5713 -+ suspendAction->setEnabled(true);
5714 -+ suspendAction->setVisible(false);
5715 -+ suspendAction->setToolTip(i18n("Pause job"));
5716 -+ m_extenderItem->addAction("suspend", suspendAction);
5717 -+ connect(suspendAction, SIGNAL(triggered()), m_job.data(), SLOT(suspend()));
5718 -+
5719 -+ //the resume action
5720 -+ QAction *resumeAction = new QAction(m_extenderItem);
5721 -+ resumeAction->setIcon(KIcon("media-playback-start"));
5722 -+ resumeAction->setEnabled(true);
5723 -+ resumeAction->setVisible(false);
5724 -+ resumeAction->setToolTip(i18n("Resume job"));
5725 -+ m_extenderItem->addAction("resume", resumeAction);
5726 -+ connect(resumeAction, SIGNAL(triggered()), m_job.data(), SLOT(resume()));
5727 -+
5728 -+ //the friendly stop action
5729 -+ QAction *stopAction = new QAction(m_extenderItem);
5730 -+ stopAction->setIcon(KIcon("media-playback-stop"));
5731 -+ stopAction->setEnabled(true);
5732 -+ stopAction->setVisible(true);
5733 -+ stopAction->setToolTip(i18n("Cancel job"));
5734 -+ m_extenderItem->addAction("stop", stopAction);
5735 -+ connect(stopAction, SIGNAL(triggered()), m_job.data(), SLOT(stop()));
5736 -+
5737 -+ updateJob();
5738 -+ updateJobState(); // make sure to set the title
5739 -+ } else {
5740 -+ m_extenderItem->showCloseButton();
5741 -+
5742 -+ labelName0 = m_extenderItem->config().readEntry("labelName0", "");
5743 -+ label0= m_extenderItem->config().readEntry("label0", "");
5744 -+ labelName1 = m_extenderItem->config().readEntry("labelName1", "");
5745 -+ label1 = m_extenderItem->config().readEntry("label1", "");
5746 -+
5747 -+ updateLabels();
5748 -+ }
5749 -+}
5750 -+
5751 -+JobWidget::~JobWidget()
5752 -+{
5753 -+}
5754 -+
5755 -+void JobWidget::destroyExtenderItem()
5756 -+{
5757 -+ m_extenderItem->destroy();
5758 -+ m_extenderItemDestroyed = true;
5759 -+}
5760 -+
5761 -+void JobWidget::scheduleUpdateJob()
5762 -+{
5763 -+ if (m_extenderItemDestroyed) {
5764 -+ return;
5765 -+ }
5766 -+
5767 -+ if (!m_updateTimerId) {
5768 -+ m_updateTimerId = startTimer(UPDATE_INTERVAL);
5769 -+ }
5770 -+}
5771 -+
5772 -+void JobWidget::updateJobState()
5773 -+{
5774 -+ if (m_extenderItemDestroyed && m_job.data()) {
5775 -+ return;
5776 -+ }
5777 -+
5778 -+ //show the current status in the title.
5779 -+ if (!m_job.data()->error().isEmpty()) {
5780 -+ m_extenderItem->setTitle(m_job.data()->error());
5781 -+ } else if (m_job.data()->state() == Job::Running) {
5782 -+ m_extenderItem->setTitle(m_job.data()->message());
5783 -+ if (m_job.data()->eta()) {
5784 -+ m_eta->setText(i18n("%1 (%2 remaining)", m_job.data()->speed(),
5785 -+ KGlobal::locale()->prettyFormatDuration(m_job.data()->eta())));
5786 -+ } else {
5787 -+ m_eta->setText(QString());
5788 -+ }
5789 -+ } else if (m_job.data()->state() == Job::Suspended) {
5790 -+ m_extenderItem->setTitle(
5791 -+ i18nc("%1 is the name of the job, can be things like Copying, deleting, moving",
5792 -+ "%1 [Paused]", m_job.data()->message()));
5793 -+ m_eta->setText(i18n("Paused"));
5794 -+ } else {
5795 -+ m_extenderItem->setTitle(
5796 -+ i18nc("%1 is the name of the job, can be things like Copying, deleting, moving",
5797 -+ "%1 [Finished]", m_job.data()->message()));
5798 -+ m_extenderItem->showCloseButton();
5799 -+ }
5800 -+}
5801 -+
5802 -+void JobWidget::updateJob()
5803 -+{
5804 -+ if (m_extenderItemDestroyed || !m_job.data()) {
5805 -+ return;
5806 -+ }
5807 -+
5808 -+ m_meter->setValue(m_job.data()->percentage());
5809 -+
5810 -+ //Update the ETA and job speed (only if running)
5811 -+ if (m_job.data()->state() == Job::Running) {
5812 -+ if (m_job.data()->eta()) {
5813 -+ m_eta->setText(i18n("%1 (%2 remaining)", m_job.data()->speed(),
5814 -+ KGlobal::locale()->prettyFormatDuration(m_job.data()->eta())));
5815 -+ } else {
5816 -+ m_eta->setText(QString());
5817 -+ }
5818 -+ }
5819 -+
5820 -+ if (m_job.data()->labels().count() > 0) {
5821 -+ labelName0 = m_job.data()->labels().value(0).first;
5822 -+ label0 = m_job.data()->labels().value(0).second;
5823 -+ }
5824 -+ if (m_job.data()->labels().count() > 1) {
5825 -+ labelName1 = m_job.data()->labels().value(1).first;
5826 -+ label1 = m_job.data()->labels().value(1).second;
5827 -+ }
5828 -+
5829 -+ //TODO: can we write this at some later point?
5830 -+ KConfigGroup cg = m_extenderItem->config();
5831 -+ cg.writeEntry("labelName0", labelName0);
5832 -+ cg.writeEntry("label0", label0);
5833 -+ cg.writeEntry("labelName1", labelName1);
5834 -+ cg.writeEntry("label1", label1);
5835 -+
5836 -+ updateLabels();
5837 -+
5838 -+ //set the correct actions to visible.
5839 -+ if (m_extenderItem->action("suspend")) {
5840 -+ m_extenderItem->action("suspend")->setVisible(m_job.data()->isSuspendable() &&
5841 -+ m_job.data()->state() == Job::Running);
5842 -+ }
5843 -+
5844 -+ if (m_extenderItem->action("resume")) {
5845 -+ m_extenderItem->action("resume")->setVisible(m_job.data()->isSuspendable() &&
5846 -+ m_job.data()->state() == Job::Suspended);
5847 -+ }
5848 -+
5849 -+ if (m_extenderItem->action("stop")) {
5850 -+ m_extenderItem->action("stop")->setVisible(m_job.data()->isKillable() &&
5851 -+ m_job.data()->state() != Job::Stopped);
5852 -+ }
5853 -+
5854 -+ QMap<QString, qlonglong> processed = m_job.data()->processedAmounts();
5855 -+ QMap<QString, qlonglong> totals = m_job.data()->totalAmounts();
5856 -+
5857 -+ qlonglong dirs = totals.value("dirs");
5858 -+ if (dirs > 1) {
5859 -+ m_dirCountLabel->setText(i18np("%2 / 1 folder", "%2 / %1 folders", dirs, processed["dirs"]));
5860 -+ m_dirCountLabel->setMaximumHeight(INT_MAX);
5861 -+ } else {
5862 -+ m_dirCountLabel->setMaximumHeight(0);
5863 -+ }
5864 -+
5865 -+ qlonglong files = totals.value("files");
5866 -+ if (files > 1) {
5867 -+ m_fileCountLabel->setText(i18np("%2 / 1 file", "%2 / %1 files", files, processed["files"]));
5868 -+ m_fileCountLabel->setMaximumHeight(INT_MAX);
5869 -+ } else {
5870 -+ m_fileCountLabel->setMaximumHeight(0);
5871 -+ }
5872 -+
5873 -+ QList<double> sample;
5874 -+ sample << m_job.data()->numericSpeed()/1000;
5875 -+ m_plotter->addSample(sample);
5876 -+
5877 -+ qlonglong total = totals["bytes"];
5878 -+ if (total > 0) {
5879 -+ QString processedString = KGlobal::locale()->formatByteSize(processed["bytes"]);
5880 -+ QString totalsString = KGlobal::locale()->formatByteSize(total);
5881 -+ m_totalBytesLabel->setText(QString("%1 / %2").arg(processedString, totalsString));
5882 -+ } else {
5883 -+ m_details->hide();
5884 -+ m_totalBytesLabel->hide();
5885 -+ }
5886 -+
5887 -+ if (m_totalBytesLabel->text().isEmpty() &&
5888 -+ m_dirCountLabel->text().isEmpty() &&
5889 -+ m_fileCountLabel->text().isEmpty()) {
5890 -+ m_details->hide();
5891 -+ } else {
5892 -+ m_details->show();
5893 -+ }
5894 -+
5895 -+ m_extenderItem->setIcon(m_job.data()->applicationIconName());
5896 -+}
5897 -+
5898 -+void JobWidget::showEvent(QShowEvent *)
5899 -+{
5900 -+ if (!m_job.data()) {
5901 -+ return;
5902 -+ }
5903 -+
5904 -+ Plasma::PopupApplet *applet = qobject_cast<Plasma::PopupApplet *>(m_extenderItem->extender()->applet());
5905 -+ if (applet && applet->isPopupShowing()) {
5906 -+ updateJob();
5907 -+ disconnect(m_job.data(), SIGNAL(changed(Job*)), this, SLOT(scheduleUpdateJob()));
5908 -+ connect(m_job.data(), SIGNAL(changed(Job*)), this, SLOT(scheduleUpdateJob()));
5909 -+ return;
5910 -+ }
5911 -+}
5912 -+
5913 -+void JobWidget::hideEvent(QHideEvent *)
5914 -+{
5915 -+ if (!m_job.data()) {
5916 -+ return;
5917 -+ }
5918 -+
5919 -+ disconnect(m_job.data(), SIGNAL(changed(Job*)), this, SLOT(scheduleUpdateJob()));
5920 -+}
5921 -+
5922 -+void JobWidget::poppedUp(bool shown)
5923 -+{
5924 -+ if (!m_job.data()) {
5925 -+ return;
5926 -+ }
5927 -+
5928 -+ disconnect(m_job.data(), SIGNAL(changed(Job*)), this, SLOT(scheduleUpdateJob()));
5929 -+
5930 -+ if (shown && isVisible()) {
5931 -+ updateJob();
5932 -+ connect(m_job.data(), SIGNAL(changed(Job*)), this, SLOT(scheduleUpdateJob()));
5933 -+ return;
5934 -+ }
5935 -+}
5936 -+
5937 -+Job *JobWidget::job() const
5938 -+{
5939 -+ return m_job.data();
5940 -+}
5941 -+
5942 -+void JobWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
5943 -+{
5944 -+ Q_UNUSED(event)
5945 -+ updateLabels();
5946 -+}
5947 -+
5948 -+void JobWidget::timerEvent(QTimerEvent *event)
5949 -+{
5950 -+ if (event->timerId() == m_updateTimerId) {
5951 -+ killTimer(m_updateTimerId);
5952 -+ m_updateTimerId = 0;
5953 -+ updateJob();
5954 -+ }
5955 -+}
5956 -+
5957 -+void JobWidget::updateLabels()
5958 -+{
5959 -+ QFontMetricsF fm = m_fromLabel->nativeWidget()->fontMetrics();
5960 -+ if (!labelName0.isEmpty()) {
5961 -+ m_fromNameLabel->setText(QString("%1: ").arg(labelName0));
5962 -+ }
5963 -+ if (label0.startsWith(QLatin1String("file://"))) {
5964 -+ label0 = KUrl(label0).toLocalFile();
5965 -+ }
5966 -+
5967 -+ const QString shortLabel0(fm.elidedText(label0, Qt::ElideMiddle, m_fromLabel->size().width()));
5968 -+ m_fromLabel->setText(shortLabel0);
5969 -+
5970 -+
5971 -+ Plasma::ToolTipContent data;
5972 -+
5973 -+ if (label0.length() > shortLabel0.length()) {
5974 -+ data.setSubText(label0);
5975 -+ Plasma::ToolTipManager::self()->setContent(m_fromLabel, data);
5976 -+ }
5977 -+
5978 -+ if (!labelName1.isEmpty()) {
5979 -+ m_toNameLabel->setText(QString("%1: ").arg(labelName1));
5980 -+ }
5981 -+ if (label1.startsWith(QLatin1String("file://"))) {
5982 -+ label1 = KUrl(label1).toLocalFile();
5983 -+ }
5984 -+
5985 -+ const QString shortLabel1(fm.elidedText(label1, Qt::ElideMiddle, m_toLabel->size().width()));
5986 -+ m_toLabel->setText(shortLabel1);
5987 -+
5988 -+ if (label1.length() > shortLabel1.length()) {
5989 -+ data.setSubText(label1);
5990 -+ Plasma::ToolTipManager::self()->setContent(m_toLabel, data);
5991 -+ }
5992 -+}
5993 -+
5994 -+void JobWidget::detailsClicked()
5995 -+{
5996 -+ if (!m_totalBytesLabel->isVisible()) {
5997 -+ m_details->setToolTip(i18n("Less"));
5998 -+ m_details->setSvg("widgets/action-overlays", "remove-normal");
5999 -+ m_totalBytesLabel->setVisible(true);
6000 -+ m_dirCountLabel->setVisible(true);
6001 -+ m_fileCountLabel->setVisible(true);
6002 -+ m_plotter->setVisible(true);
6003 -+ m_layout->addItem(m_totalBytesLabel, 4, 1);
6004 -+ m_layout->addItem(m_fileCountLabel, 5, 1);
6005 -+ m_layout->addItem(m_dirCountLabel, 6, 1);
6006 -+ m_layout->addItem(m_plotter, 7, 1);
6007 -+ m_extenderItem->setCollapsed(m_extenderItem->isCollapsed());
6008 -+ } else {
6009 -+ m_details->setToolTip(i18n("More"));
6010 -+ m_details->setSvg("widgets/action-overlays", "add-normal");
6011 -+ m_totalBytesLabel->setVisible(false);
6012 -+ m_dirCountLabel->setVisible(false);
6013 -+ m_fileCountLabel->setVisible(false);
6014 -+ m_plotter->setVisible(false);
6015 -+ for (int i = 0; i < 4; i++) {
6016 -+ m_layout->removeAt(m_layout->count() - 1);
6017 -+ }
6018 -+ m_layout->updateGeometry();
6019 -+ m_extenderItem->setCollapsed(m_extenderItem->isCollapsed());
6020 -+ }
6021 -+}
6022 -+
6023 -+#include "jobwidget.moc"
6024 -+
6025 -diff --git a/plasma/generic/applets/notifications/ui/jobwidget.h b/plasma/generic/applets/notifications/ui/jobwidget.h
6026 -new file mode 100644
6027 -index 0000000..b949bac
6028 ---- /dev/null
6029 -+++ b/plasma/generic/applets/notifications/ui/jobwidget.h
6030 -@@ -0,0 +1,102 @@
6031 -+/***************************************************************************
6032 -+ * Copyright 2008 by Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl *
6033 -+ * *
6034 -+ * This program is free software; you can redistribute it and/or modify *
6035 -+ * it under the terms of the GNU General Public License as published by *
6036 -+ * the Free Software Foundation; either version 2 of the License, or *
6037 -+ * (at your option) any later version. *
6038 -+ * *
6039 -+ * This program is distributed in the hope that it will be useful, *
6040 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
6041 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
6042 -+ * GNU General Public License for more details. *
6043 -+ * *
6044 -+ * You should have received a copy of the GNU General Public License *
6045 -+ * along with this program; if not, write to the *
6046 -+ * Free Software Foundation, Inc., *
6047 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
6048 -+ ***************************************************************************/
6049 -+
6050 -+#ifndef JOBWIDGET_H
6051 -+#define JOBWIDGET_H
6052 -+
6053 -+#include "../core/job.h"
6054 -+
6055 -+
6056 -+#include <QGraphicsWidget>
6057 -+#include <QGraphicsGridLayout>
6058 -+
6059 -+#include <Plasma/Service>
6060 -+#include <Plasma/ExtenderItem>
6061 -+#include <plasma/dataengine.h>
6062 -+#include <Plasma/PushButton>
6063 -+
6064 -+namespace Plasma
6065 -+{
6066 -+ class ExtenderItem;
6067 -+ class PushButton;
6068 -+ class Label;
6069 -+ class Meter;
6070 -+ class IconWidget;
6071 -+ class SignalPlotter;
6072 -+} // namespace Plasma
6073 -+
6074 -+class Job;
6075 -+
6076 -+
6077 -+class JobWidget : public QGraphicsWidget
6078 -+{
6079 -+ Q_OBJECT
6080 -+
6081 -+ public:
6082 -+ explicit JobWidget(Job *job, Plasma::ExtenderItem *parent);
6083 -+ ~JobWidget();
6084 -+
6085 -+ void poppedUp(bool shown);
6086 -+
6087 -+ Job *job() const;
6088 -+
6089 -+ protected:
6090 -+ void resizeEvent(QGraphicsSceneResizeEvent *event);
6091 -+ void timerEvent(QTimerEvent *event);
6092 -+ void showEvent(QShowEvent *event);
6093 -+ void hideEvent(QHideEvent *event);
6094 -+
6095 -+ private Q_SLOTS:
6096 -+ void detailsClicked();
6097 -+ void destroyExtenderItem();
6098 -+ void scheduleUpdateJob();
6099 -+ void updateJobState();
6100 -+
6101 -+ private:
6102 -+ void updateLabels();
6103 -+ void updateJob();
6104 -+
6105 -+ Plasma::ExtenderItem *m_extenderItem;
6106 -+ QWeakPointer<Job>m_job;
6107 -+
6108 -+ Plasma::Meter *m_meter;
6109 -+ Plasma::Label *m_fromNameLabel;
6110 -+ Plasma::Label *m_fromLabel;
6111 -+ Plasma::Label *m_toNameLabel;
6112 -+ Plasma::Label *m_toLabel;
6113 -+ Plasma::Label *m_totalBytesLabel;
6114 -+ Plasma::Label *m_dirCountLabel;
6115 -+ Plasma::Label *m_fileCountLabel;
6116 -+ Plasma::Label *m_eta;
6117 -+ Plasma::IconWidget *m_details;
6118 -+ Plasma::SignalPlotter *m_plotter;
6119 -+
6120 -+ QGraphicsGridLayout *m_layout;
6121 -+
6122 -+ QString labelName0;
6123 -+ QString labelName1;
6124 -+ QString label0;
6125 -+ QString label1;
6126 -+
6127 -+ int m_updateTimerId;
6128 -+
6129 -+ bool m_extenderItemDestroyed;
6130 -+};
6131 -+
6132 -+#endif
6133 -diff --git a/plasma/generic/applets/notifications/ui/notificationgroup.cpp b/plasma/generic/applets/notifications/ui/notificationgroup.cpp
6134 -new file mode 100644
6135 -index 0000000..f27e2c3
6136 ---- /dev/null
6137 -+++ b/plasma/generic/applets/notifications/ui/notificationgroup.cpp
6138 -@@ -0,0 +1,239 @@
6139 -+/***************************************************************************
6140 -+ * notificationgroup.cpp *
6141 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
6142 -+ * *
6143 -+ * This program is free software; you can redistribute it and/or modify *
6144 -+ * it under the terms of the GNU General Public License as published by *
6145 -+ * the Free Software Foundation; either version 2 of the License, or *
6146 -+ * (at your option) any later version. *
6147 -+ * *
6148 -+ * This program is distributed in the hope that it will be useful, *
6149 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
6150 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
6151 -+ * GNU General Public License for more details. *
6152 -+ * *
6153 -+ * You should have received a copy of the GNU General Public License *
6154 -+ * along with this program; if not, write to the *
6155 -+ * Free Software Foundation, Inc., *
6156 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
6157 -+ ***************************************************************************/
6158 -+
6159 -+#include "notificationgroup.h"
6160 -+#include "../core/notification.h"
6161 -+#include "notificationwidget.h"
6162 -+
6163 -+#include <QGraphicsLinearLayout>
6164 -+#include <QWidget>
6165 -+
6166 -+#include <KDebug>
6167 -+#include <KIcon>
6168 -+#include <KLocale>
6169 -+
6170 -+#include <Plasma/TabBar>
6171 -+#include <Plasma/ExtenderItem>
6172 -+
6173 -+
6174 -+NotificationGroup::NotificationGroup(Plasma::Extender *parent, uint groupId)
6175 -+ : Plasma::ExtenderGroup(parent, groupId)
6176 -+{
6177 -+ setTransient(true);
6178 -+ config().writeEntry("type", "notification");
6179 -+ setName("notifications");
6180 -+ setTitle(i18n("Notifications"));
6181 -+ setIcon("dialog-information");
6182 -+ showCloseButton();
6183 -+
6184 -+
6185 -+ m_notificationBar = new Plasma::TabBar(this);
6186 -+ m_notificationBar->nativeWidget()->setMaximumWidth(400);
6187 -+ m_notificationBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
6188 -+ m_notificationBar->addTab(KIcon("dialog-information"), i18nc("Show all notifications", "All"));
6189 -+ connect(m_notificationBar, SIGNAL(currentChanged(int)), this, SLOT(tabSwitched(int)));
6190 -+
6191 -+
6192 -+ QGraphicsWidget *widget = new QGraphicsWidget(this);
6193 -+ QGraphicsLinearLayout *tabsLayout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
6194 -+ widget->setContentsMargins(0, 4, 0, 0);
6195 -+ tabsLayout->setContentsMargins(0, 0, 0, 0);
6196 -+ tabsLayout->addStretch();
6197 -+ tabsLayout->addItem(m_notificationBar);
6198 -+ tabsLayout->addStretch();
6199 -+
6200 -+ setWidget(widget);
6201 -+ setCollapsed(true);
6202 -+ setAutoCollapse(false);
6203 -+}
6204 -+
6205 -+NotificationGroup::~NotificationGroup()
6206 -+{
6207 -+ m_extenderItemsForNotification.clear();
6208 -+ m_notificationForExtenderItems.clear();
6209 -+ qDeleteAll(m_notifications);
6210 -+}
6211 -+
6212 -+
6213 -+void NotificationGroup::addNotification(Notification *notification)
6214 -+{
6215 -+ connect(notification, SIGNAL(notificationDestroyed(Notification*)), this, SLOT(removeNotification(Notification*)));
6216 -+
6217 -+ NotificationWidget *notificationWidget = new NotificationWidget(notification, this);
6218 -+ notificationWidget->setTitleBarVisible(false);
6219 -+ Plasma::ExtenderItem *extenderItem = new ExtenderItem(extender());
6220 -+ extenderItem->setGroup(this, QPointF(0,0));
6221 -+ extenderItem->setTransient(true);
6222 -+ extenderItem->config().writeEntry("type", "notification");
6223 -+ extenderItem->setWidget(notificationWidget);
6224 -+ extenderItem->setIcon(QIcon());
6225 -+ extenderItem->showCloseButton();
6226 -+ connect(extenderItem, SIGNAL(destroyed(Plasma::ExtenderItem*)), this, SLOT(extenderItemDestroyed(Plasma::ExtenderItem*)));
6227 -+ connect(notificationWidget, SIGNAL(destroyed()), extenderItem, SLOT(deleteLater()));
6228 -+
6229 -+ if (!notification->summary().isEmpty()) {
6230 -+ extenderItem->setTitle(notification->summary());
6231 -+ } else {
6232 -+ extenderItem->setTitle(i18n("Notification from %1", notification->applicationName()));
6233 -+ }
6234 -+
6235 -+ m_extenderItemsForNotification[notification] = extenderItem;
6236 -+ m_notificationForExtenderItems[extenderItem] = notification;
6237 -+ m_notifications.append(notification);
6238 -+ m_notificationsForApp[notification->applicationName()].insert(notification);
6239 -+ m_appForNotification[notification] = notification->applicationName();
6240 -+
6241 -+ if (!m_currentFilter.isNull() && m_currentFilter != notification->applicationName()) {
6242 -+ extenderItem->setMaximumHeight(0);
6243 -+ extenderItem->setVisible(false);
6244 -+ }
6245 -+
6246 -+ //adjust tabbar
6247 -+ bool found = false;
6248 -+ for (int i = 0; i < m_notificationBar->count(); ++i) {
6249 -+ if (m_notificationBar->tabText(i) == notification->applicationName()) {
6250 -+ found = true;
6251 -+ break;
6252 -+ }
6253 -+ }
6254 -+
6255 -+ if (!found) {
6256 -+ m_notificationBar->addTab(notification->applicationIcon(), notification->applicationName());
6257 -+ if (m_notificationBar->count() > 2) {
6258 -+ setCollapsed(false);
6259 -+ setAutoCollapse(true);
6260 -+ }
6261 -+ }
6262 -+
6263 -+ if (items().count() == 1) {
6264 -+ //ensure the notifications group is the last item
6265 -+ Plasma::ExtenderGroup *jobGroup = extender()->group("jobGroup");
6266 -+ if (jobGroup && jobGroup->isVisible()) {
6267 -+ if (extender()->appearance() == Plasma::Extender::TopDownStacked) {
6268 -+ setExtender(extender(), QPointF(0,0));
6269 -+ } else {
6270 -+ setExtender(extender(), jobGroup->geometry().bottomLeft());
6271 -+ }
6272 -+ }
6273 -+ }
6274 -+
6275 -+ notificationWidget->layout()->activate();
6276 -+}
6277 -+
6278 -+void NotificationGroup::extenderItemDestroyed(Plasma::ExtenderItem *object)
6279 -+{
6280 -+ if (m_extenderItemsForNotification.isEmpty()) {
6281 -+ // either we aren't tracking this notification or else we're being deleted
6282 -+ return;
6283 -+ }
6284 -+
6285 -+ Notification *n = m_notificationForExtenderItems.value(object);
6286 -+
6287 -+ if (n) {
6288 -+ m_notificationForExtenderItems.remove(object);
6289 -+ removeNotification(n);
6290 -+ n->deleteLater();
6291 -+ }
6292 -+}
6293 -+
6294 -+void NotificationGroup::removeNotification(Notification *notification)
6295 -+{
6296 -+ if (m_extenderItemsForNotification.isEmpty()) {
6297 -+ // either we aren't tracking this notification or else we're being deleted
6298 -+ return;
6299 -+ }
6300 -+
6301 -+ Plasma::ExtenderItem *item = m_extenderItemsForNotification.value(notification);
6302 -+ if (item) {
6303 -+ m_notificationForExtenderItems.remove(item);
6304 -+ }
6305 -+
6306 -+ m_extenderItemsForNotification.remove(notification);
6307 -+ m_notifications.removeAll(notification);
6308 -+ QString applicationName = m_appForNotification.value(notification);
6309 -+
6310 -+ if (applicationName.isEmpty()) {
6311 -+ return;
6312 -+ }
6313 -+
6314 -+ m_appForNotification.remove(notification);
6315 -+
6316 -+ if (m_notificationsForApp.contains(applicationName)) {
6317 -+ m_notificationsForApp[applicationName].remove(notification);
6318 -+ if (m_notificationsForApp[applicationName].isEmpty()) {
6319 -+ m_notificationsForApp.remove(applicationName);
6320 -+ }
6321 -+ }
6322 -+
6323 -+ //clear tabbar
6324 -+ for (int i = 1; i < m_notificationBar->count(); ++i) {
6325 -+ if (!m_notificationsForApp.contains(m_notificationBar->tabText(i))) {
6326 -+ if (i == m_notificationBar->currentIndex()) {
6327 -+ m_notificationBar->setCurrentIndex(0);
6328 -+ }
6329 -+ m_notificationBar->removeTab(i);
6330 -+ //2 tabs means just "all" and a single application, no need to display it
6331 -+ if (m_notificationBar->count() <= 2) {
6332 -+ setCollapsed(true);
6333 -+ setAutoCollapse(false);
6334 -+ }
6335 -+ }
6336 -+ }
6337 -+
6338 -+ if (m_notifications.count() == 0) {
6339 -+ emit scrollerEmpty();
6340 -+ return;
6341 -+ }
6342 -+}
6343 -+
6344 -+
6345 -+void NotificationGroup::filterNotificationsByOwner(const QString &owner)
6346 -+{
6347 -+ foreach (Notification *notification, m_notifications) {
6348 -+ Plasma::ExtenderItem *item = m_extenderItemsForNotification.value(notification);
6349 -+
6350 -+ if (!item || item->group() != this) {
6351 -+ continue;
6352 -+ }
6353 -+
6354 -+ if (owner.isNull() || notification->applicationName() == owner) {
6355 -+ item->setMaximumHeight(QWIDGETSIZE_MAX);
6356 -+ item->setVisible(true);
6357 -+ } else {
6358 -+ item->setMaximumHeight(0);
6359 -+ item->setVisible(false);
6360 -+ }
6361 -+ }
6362 -+
6363 -+ m_currentFilter = owner;
6364 -+}
6365 -+
6366 -+void NotificationGroup::tabSwitched(int index)
6367 -+{
6368 -+ if (index > 0) {
6369 -+ filterNotificationsByOwner(m_notificationBar->tabText(index));
6370 -+ } else {
6371 -+ filterNotificationsByOwner(QString());
6372 -+ }
6373 -+}
6374 -+
6375 -+
6376 -+#include "notificationgroup.moc"
6377 -+
6378 -diff --git a/plasma/generic/applets/notifications/ui/notificationgroup.h b/plasma/generic/applets/notifications/ui/notificationgroup.h
6379 -new file mode 100644
6380 -index 0000000..ffa2112
6381 ---- /dev/null
6382 -+++ b/plasma/generic/applets/notifications/ui/notificationgroup.h
6383 -@@ -0,0 +1,85 @@
6384 -+/***************************************************************************
6385 -+ * notificationgroup.h *
6386 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
6387 -+ * *
6388 -+ * This program is free software; you can redistribute it and/or modify *
6389 -+ * it under the terms of the GNU General Public License as published by *
6390 -+ * the Free Software Foundation; either version 2 of the License, or *
6391 -+ * (at your option) any later version. *
6392 -+ * *
6393 -+ * This program is distributed in the hope that it will be useful, *
6394 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
6395 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
6396 -+ * GNU General Public License for more details. *
6397 -+ * *
6398 -+ * You should have received a copy of the GNU General Public License *
6399 -+ * along with this program; if not, write to the *
6400 -+ * Free Software Foundation, Inc., *
6401 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
6402 -+ ***************************************************************************/
6403 -+
6404 -+#ifndef NOTIFICATIONGROUP_H
6405 -+#define NOTIFICATIONGROUP_H
6406 -+
6407 -+
6408 -+#include <Plasma/Extender>
6409 -+#include <Plasma/ExtenderGroup>
6410 -+
6411 -+
6412 -+#include <Plasma/Plasma>
6413 -+
6414 -+class QGraphicsLinearLayout;
6415 -+
6416 -+namespace Plasma
6417 -+{
6418 -+ class ExtenderItem;
6419 -+ class TabBar;
6420 -+ class Extender;
6421 -+}
6422 -+
6423 -+class NotificationWidget;
6424 -+class Notification;
6425 -+
6426 -+class NotificationGroup : public Plasma::ExtenderGroup
6427 -+{
6428 -+ Q_OBJECT
6429 -+
6430 -+public:
6431 -+ NotificationGroup(Plasma::Extender *parent, uint groupId = 0);
6432 -+ ~NotificationGroup();
6433 -+
6434 -+ void addNotification(Notification *notification);
6435 -+
6436 -+ void filterNotificationsByOwner(const QString &owner);
6437 -+
6438 -+
6439 -+public Q_SLOTS:
6440 -+ void removeNotification(Notification *notification);
6441 -+
6442 -+protected Q_SLOTS:
6443 -+ void tabSwitched(int index);
6444 -+ void extenderItemDestroyed(Plasma::ExtenderItem *object);
6445 -+
6446 -+Q_SIGNALS:
6447 -+ void scrollerEmpty();
6448 -+
6449 -+private:
6450 -+ Plasma::TabBar *m_notificationBar;
6451 -+
6452 -+ //housekeeping data structures
6453 -+ QList<Notification *>m_notifications;
6454 -+
6455 -+ //Those two are kept on both ways since we are not sure the thing
6456 -+ //contained in the hash is still valid so we couldn't obtain the
6457 -+ //info to remove the proper key, unless both ways are stored
6458 -+ QHash<QString, QSet<Notification *> > m_notificationsForApp;
6459 -+ QHash<Notification *, QString> m_appForNotification;
6460 -+
6461 -+ QHash<Notification *, Plasma::ExtenderItem *>m_extenderItemsForNotification;
6462 -+ QHash<Plasma::ExtenderItem *, Notification *>m_notificationForExtenderItems;
6463 -+
6464 -+ QString m_currentFilter;
6465 -+};
6466 -+
6467 -+
6468 -+#endif
6469 -diff --git a/plasma/generic/applets/notifications/ui/notifications.cpp b/plasma/generic/applets/notifications/ui/notifications.cpp
6470 -new file mode 100644
6471 -index 0000000..eea1d72
6472 ---- /dev/null
6473 -+++ b/plasma/generic/applets/notifications/ui/notifications.cpp
6474 -@@ -0,0 +1,434 @@
6475 -+/***************************************************************************
6476 -+ * applet.cpp *
6477 -+ * *
6478 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
6479 -+ * Copyright (C) 2008 Sebastian Sauer *
6480 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
6481 -+ * *
6482 -+ * This program is free software; you can redistribute it and/or modify *
6483 -+ * it under the terms of the GNU General Public License as published by *
6484 -+ * the Free Software Foundation; either version 2 of the License, or *
6485 -+ * (at your option) any later version. *
6486 -+ * *
6487 -+ * This program is distributed in the hope that it will be useful, *
6488 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
6489 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
6490 -+ * GNU General Public License for more details. *
6491 -+ * *
6492 -+ * You should have received a copy of the GNU General Public License *
6493 -+ * along with this program; if not, write to the *
6494 -+ * Free Software Foundation, Inc., *
6495 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
6496 -+ ***************************************************************************/
6497 -+
6498 -+#include "notifications.h"
6499 -+
6500 -+#include <QtGui/QApplication>
6501 -+#include <QtGui/QGraphicsLayout>
6502 -+#include <QtGui/QGraphicsLinearLayout>
6503 -+#include <QtGui/QVBoxLayout>
6504 -+#include <QtGui/QIcon>
6505 -+#include <QtGui/QLabel>
6506 -+#include <QtGui/QListWidget>
6507 -+#include <QtGui/QTreeWidget>
6508 -+#include <QtGui/QCheckBox>
6509 -+#include <QtGui/QPainter>
6510 -+#include <QtGui/QX11Info>
6511 -+#include <QtCore/QProcess>
6512 -+
6513 -+
6514 -+#include <KConfigDialog>
6515 -+#include <KComboBox>
6516 -+#include <KWindowSystem>
6517 -+#include <KIconLoader>
6518 -+
6519 -+#include <Solid/Device>
6520 -+
6521 -+#include <plasma/extender.h>
6522 -+#include <plasma/extenderitem.h>
6523 -+#include <plasma/extendergroup.h>
6524 -+#include <plasma/framesvg.h>
6525 -+#include <plasma/widgets/label.h>
6526 -+#include <plasma/theme.h>
6527 -+#include <plasma/dataenginemanager.h>
6528 -+#include <plasma/dataengine.h>
6529 -+#include <Plasma/TabBar>
6530 -+#include <Plasma/Animator>
6531 -+#include <Plasma/Animation>
6532 -+#include <Plasma/Containment>
6533 -+#include <Plasma/Corona>
6534 -+#include <Plasma/Dialog>
6535 -+#include <Plasma/WindowEffects>
6536 -+
6537 -+#include "config-notifications.h"
6538 -+#ifdef HAVE_LIBXSS // Idle detection.
6539 -+#include <X11/Xlib.h>
6540 -+#include <X11/Xutil.h>
6541 -+#include <X11/extensions/scrnsaver.h>
6542 -+#include <fixx11h.h>
6543 -+#endif // HAVE_LIBXSS
6544 -+
6545 -+#include "../core/notificationsmanager.h"
6546 -+#include "../core/notification.h"
6547 -+#include "../core/completedjobnotification.h"
6548 -+#include "busywidget.h"
6549 -+#include "jobwidget.h"
6550 -+#include "jobtotalswidget.h"
6551 -+#include "notificationgroup.h"
6552 -+#include "notificationstack.h"
6553 -+#include "stackdialog.h"
6554 -+
6555 -+
6556 -+K_EXPORT_PLASMA_APPLET(notifications, Notifications)
6557 -+
6558 -+
6559 -+Notifications::Notifications(QObject *parent, const QVariantList &arguments)
6560 -+ : Plasma::PopupApplet(parent, arguments),
6561 -+ m_jobSummaryWidget(0),
6562 -+ m_autoHidePopup(true),
6563 -+ m_notificationStack(0),
6564 -+ m_notificationStackDialog(0),
6565 -+ m_standaloneJobSummaryWidget(0),
6566 -+ m_standaloneJobSummaryDialog(0),
6567 -+ m_busyWidget(0)
6568 -+{
6569 -+ m_manager = new Manager(this);
6570 -+
6571 -+ setPopupIcon(QIcon());
6572 -+ setPassivePopup(true);
6573 -+ setAspectRatioMode(Plasma::IgnoreAspectRatio);
6574 -+ setBackgroundHints(NoBackground);
6575 -+ setHasConfigurationInterface(true);
6576 -+ setMinimumSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
6577 -+}
6578 -+
6579 -+Notifications::~Notifications()
6580 -+{
6581 -+ // stop listening to the manager
6582 -+ disconnect(m_manager, 0, this, 0);
6583 -+ if (m_notificationStackDialog) {
6584 -+ disconnect(m_notificationStackDialog, 0, this, 0);
6585 -+ }
6586 -+
6587 -+ foreach (Notification *notification, m_manager->notifications()) {
6588 -+ // we don't want a destroyed managed after the destruction of manager
6589 -+ disconnect(notification, 0, this, 0);
6590 -+ }
6591 -+
6592 -+ //has to be deleted before the manager because it will access it
6593 -+ delete m_busyWidget;
6594 -+ delete m_notificationStackDialog;
6595 -+ delete m_standaloneJobSummaryDialog;
6596 -+}
6597 -+
6598 -+void Notifications::init()
6599 -+{
6600 -+ extender()->setEmptyExtenderMessage(i18n("No notifications and no jobs"));
6601 -+
6602 -+ m_busyWidget = new BusyWidget(this, m_manager);
6603 -+ connect(m_busyWidget, SIGNAL(clicked()), this, SLOT(togglePopup()));
6604 -+ QGraphicsLinearLayout *lay = new QGraphicsLinearLayout(this);
6605 -+ setContentsMargins(0, 0, 0, 0);
6606 -+ lay->setContentsMargins(0, 0, 0, 0);
6607 -+ lay->addItem(m_busyWidget);
6608 -+
6609 -+ configChanged();
6610 -+ setStatus(Plasma::PassiveStatus);
6611 -+}
6612 -+
6613 -+void Notifications::configChanged()
6614 -+{
6615 -+ KConfigGroup cg = config();
6616 -+
6617 -+ m_autoHidePopup = cg.readEntry("AutoHidePopup", true);
6618 -+ if (m_notificationStackDialog) {
6619 -+ m_notificationStackDialog->setAutoHide(m_autoHidePopup);
6620 -+ }
6621 -+
6622 -+ if (cg.readEntry("ShowJobs", true)) {
6623 -+ createJobGroups();
6624 -+
6625 -+ m_manager->registerJobProtocol();
6626 -+ connect(m_manager, SIGNAL(jobAdded(Job*)),
6627 -+ this, SLOT(addJob(Job*)), Qt::UniqueConnection);
6628 -+ connect(m_manager, SIGNAL(jobRemoved(Job*)),
6629 -+ this, SLOT(finishJob(Job*)), Qt::UniqueConnection);
6630 -+ } else {
6631 -+ delete extender()->group("jobGroup");
6632 -+ m_manager->unregisterJobProtocol();
6633 -+ disconnect(m_manager, SIGNAL(jobAdded(Job*)),
6634 -+ this, SLOT(addJob(Job*)));
6635 -+ disconnect(m_manager, SIGNAL(jobRemoved(Job*)),
6636 -+ this, SLOT(finishJob(Job*)));
6637 -+ }
6638 -+
6639 -+ if (cg.readEntry("ShowNotifications", true)) {
6640 -+ m_manager->registerNotificationProtocol();
6641 -+ connect(m_manager, SIGNAL(notificationAdded(Notification*)),
6642 -+ this, SLOT(addNotification(Notification*)), Qt::UniqueConnection);
6643 -+ } else {
6644 -+ m_manager->unregisterNotificationProtocol();
6645 -+ disconnect(m_manager, SIGNAL(notificationAdded(Notification*)),
6646 -+ this, SLOT(addNotification(Notification*)));
6647 -+ }
6648 -+}
6649 -+
6650 -+void Notifications::syncNotificationBarNeeded()
6651 -+{
6652 -+ if (!m_manager) {
6653 -+ return;
6654 -+ }
6655 -+
6656 -+ if (m_manager->notifications().isEmpty()) {
6657 -+ if (extender()->item("notifications")) {
6658 -+ //don't let him in the config file
6659 -+ extender()->item("notifications")->destroy();
6660 -+ }
6661 -+ } else if (!extender()->item("notifications")) {
6662 -+ m_notificationGroup = new NotificationGroup(extender());
6663 -+ }
6664 -+}
6665 -+
6666 -+Manager *Notifications::manager() const
6667 -+{
6668 -+ return m_manager;
6669 -+}
6670 -+
6671 -+void Notifications::createConfigurationInterface(KConfigDialog *parent)
6672 -+{
6673 -+ if (!m_notificationInterface) {
6674 -+ KConfigGroup cg = config();
6675 -+ m_notificationInterface = new QWidget();
6676 -+
6677 -+ m_notificationUi.setupUi(m_notificationInterface.data());
6678 -+
6679 -+ m_notificationUi.showJobs->setChecked(cg.readEntry("ShowJobs", true));
6680 -+ m_notificationUi.showNotifications->setChecked(cg.readEntry("ShowNotifications", true));
6681 -+
6682 -+ m_notificationUi.autoHide->setChecked(config().readEntry("AutoHidePopup", true));
6683 -+
6684 -+ connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
6685 -+ connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
6686 -+
6687 -+ parent->addPage(m_notificationInterface.data(), i18n("Information"),
6688 -+ "preferences-desktop-notification",
6689 -+ i18n("Choose which information to show"));
6690 -+
6691 -+ connect(m_notificationUi.showNotifications, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified()));
6692 -+ connect(m_notificationUi.showJobs, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified()));
6693 -+ connect(m_notificationUi.autoHide, SIGNAL(stateChanged(int)), parent, SLOT(settingsModified()));
6694 -+ }
6695 -+}
6696 -+
6697 -+void Notifications::configAccepted()
6698 -+{
6699 -+ //TODO put in a single page
6700 -+ //cg.writeEntry("AutoHidePopup", m_autoHideUi.autoHide->isChecked());
6701 -+
6702 -+ KConfigGroup cg = config();
6703 -+ cg.writeEntry("ShowJobs", m_notificationUi.showJobs->isChecked());
6704 -+ cg.writeEntry("ShowNotifications", m_notificationUi.showNotifications->isChecked());
6705 -+ cg.writeEntry("AutoHidePopup", m_notificationUi.autoHide->isChecked());
6706 -+
6707 -+ emit configNeedsSaving();
6708 -+}
6709 -+
6710 -+void Notifications::addNotification(Notification *notification)
6711 -+{
6712 -+ syncNotificationBarNeeded();
6713 -+
6714 -+ //At this point we are sure the pointer is valid
6715 -+ m_notificationGroup.data()->addNotification(notification);
6716 -+
6717 -+
6718 -+ if (isPopupShowing()) {
6719 -+ return;
6720 -+ }
6721 -+
6722 -+ if (!m_notificationStack) {
6723 -+ m_notificationStack = new NotificationStack(this);
6724 -+ if (containment() && containment()->corona()) {
6725 -+ containment()->corona()->addOffscreenWidget(m_notificationStack);
6726 -+ }
6727 -+ m_notificationStackDialog = new StackDialog;
6728 -+ m_notificationStackDialog->setNotificationStack(m_notificationStack);
6729 -+ m_notificationStackDialog->setApplet(this);
6730 -+ connect(m_notificationStack, SIGNAL(stackEmpty()), m_notificationStackDialog, SLOT(hide()));
6731 -+ connect(m_notificationStack, SIGNAL(showRequested()), m_notificationStackDialog, SLOT(perhapsShow()));
6732 -+ m_notificationStackDialog->setAutoHide(m_autoHidePopup);
6733 -+
6734 -+ if (m_standaloneJobSummaryDialog) {
6735 -+ m_notificationStackDialog->setWindowToTile(m_standaloneJobSummaryDialog);
6736 -+ }
6737 -+ }
6738 -+
6739 -+
6740 -+ m_notificationStack->addNotification(notification);
6741 -+ m_notificationStackDialog->syncToGraphicsWidget();
6742 -+
6743 -+ if (containment() && containment()->corona()) {
6744 -+ if (!m_notificationStackDialog->isVisible()) {
6745 -+ m_notificationStack->setCurrentNotification(notification);
6746 -+ }
6747 -+
6748 -+ KWindowSystem::setOnAllDesktops(m_notificationStackDialog->winId(), true);
6749 -+ m_notificationStackDialog->perhapsShow();
6750 -+ }
6751 -+
6752 -+ Plasma::Animation *pulse = Plasma::Animator::create(Plasma::Animator::PulseAnimation, m_busyWidget);
6753 -+ pulse->setTargetWidget(m_busyWidget);
6754 -+ pulse->start(QAbstractAnimation::DeleteWhenStopped);
6755 -+}
6756 -+
6757 -+void Notifications::addJob(Job *job)
6758 -+{
6759 -+ Plasma::ExtenderGroup *group = extender()->group("jobGroup");
6760 -+
6761 -+ Plasma::ExtenderItem *extenderItem = new Plasma::ExtenderItem(extender());
6762 -+ extenderItem->setTransient(true);
6763 -+ extenderItem->config().writeEntry("type", "job");
6764 -+ extenderItem->setWidget(new JobWidget(job, extenderItem));
6765 -+
6766 -+ extenderItem->setGroup(group);
6767 -+
6768 -+ if (group) {
6769 -+ group->setCollapsed(group->items().count() < 2);
6770 -+ }
6771 -+
6772 -+ if (isPopupShowing()) {
6773 -+ return;
6774 -+ }
6775 -+
6776 -+ //show the tiny standalone overview
6777 -+ if (!m_standaloneJobSummaryWidget) {
6778 -+ m_standaloneJobSummaryDialog = new Plasma::Dialog();
6779 -+ KWindowSystem::setType(m_standaloneJobSummaryDialog->winId(), NET::Dock);
6780 -+ if (m_notificationStackDialog) {
6781 -+ m_notificationStackDialog->setWindowToTile(m_standaloneJobSummaryDialog);
6782 -+ }
6783 -+
6784 -+ m_standaloneJobSummaryWidget = new JobTotalsWidget(m_manager->jobTotals(), this);
6785 -+ if (containment() && containment()->corona()) {
6786 -+ containment()->corona()->addOffscreenWidget(m_standaloneJobSummaryWidget);
6787 -+ }
6788 -+ m_standaloneJobSummaryDialog->setGraphicsWidget(m_standaloneJobSummaryWidget);
6789 -+ //FIXME:sizing hack and layout issues..
6790 -+ m_standaloneJobSummaryWidget->resize(m_standaloneJobSummaryWidget->size().width(), 32);
6791 -+ m_standaloneJobSummaryWidget->setMaximumHeight(32);
6792 -+ m_standaloneJobSummaryWidget->setMinimumHeight(32);
6793 -+ m_standaloneJobSummaryWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
6794 -+ }
6795 -+
6796 -+ m_standaloneJobSummaryDialog->syncToGraphicsWidget();
6797 -+ KWindowSystem::setState(m_standaloneJobSummaryDialog->winId(), NET::KeepBelow);
6798 -+
6799 -+ if (containment() && containment()->corona()) {
6800 -+ m_standaloneJobSummaryDialog->move(containment()->corona()->popupPosition(this, m_standaloneJobSummaryDialog->size()));
6801 -+ m_standaloneJobSummaryDialog->show();
6802 -+ Plasma::WindowEffects::slideWindow(m_standaloneJobSummaryDialog, location());
6803 -+
6804 -+ KWindowSystem::setOnAllDesktops(m_standaloneJobSummaryDialog->winId(), true);
6805 -+ KWindowSystem::clearState(m_standaloneJobSummaryDialog->winId(), NET::KeepAbove|NET::StaysOnTop);
6806 -+
6807 -+ KWindowSystem::setState(m_standaloneJobSummaryDialog->winId(), NET::SkipTaskbar|NET::SkipPager);
6808 -+ KWindowSystem::raiseWindow(m_standaloneJobSummaryDialog->winId());
6809 -+ KWindowSystem::setOnAllDesktops(m_standaloneJobSummaryDialog->winId(), true);
6810 -+ }
6811 -+}
6812 -+
6813 -+void Notifications::initExtenderItem(Plasma::ExtenderItem *extenderItem)
6814 -+{
6815 -+ if (extenderItem->name() == "jobGroup") {
6816 -+ m_jobSummaryWidget = new JobTotalsWidget(m_manager->jobTotals(), extenderItem);
6817 -+ extenderItem->setWidget(m_jobSummaryWidget);
6818 -+ Plasma::ExtenderGroup *group = qobject_cast<Plasma::ExtenderGroup*>(extenderItem);
6819 -+ if (group) {
6820 -+ extenderItem->setCollapsed(!group->isGroupCollapsed());
6821 -+ }
6822 -+ return;
6823 -+ }
6824 -+
6825 -+ if (extenderItem->config().readEntry("type", QString()) == "job") {
6826 -+ extenderItem->setWidget(new JobWidget(0, extenderItem));
6827 -+ } else {
6828 -+ //unknown type, this should never happen
6829 -+ extenderItem->destroy();
6830 -+ }
6831 -+
6832 -+}
6833 -+
6834 -+void Notifications::popupEvent(bool show)
6835 -+{
6836 -+ if (m_busyWidget) {
6837 -+ m_busyWidget->suppressToolTips(show);
6838 -+ }
6839 -+
6840 -+ //decide about showing the tiny progressbar or not
6841 -+ if (m_standaloneJobSummaryDialog) {
6842 -+ if (show || !m_manager->jobs().isEmpty()) {
6843 -+ if (!show) {
6844 -+ KWindowSystem::raiseWindow(m_standaloneJobSummaryDialog->winId());
6845 -+ KWindowSystem::setState(m_standaloneJobSummaryDialog->winId(), NET::SkipTaskbar|NET::SkipPager);
6846 -+ KWindowSystem::setState(m_standaloneJobSummaryDialog->winId(), NET::KeepBelow);
6847 -+ } else {
6848 -+ m_standaloneJobSummaryDialog->hide();
6849 -+ }
6850 -+ }
6851 -+ }
6852 -+
6853 -+ if (m_notificationStackDialog && show) {
6854 -+ m_notificationStackDialog->hide();
6855 -+ }
6856 -+
6857 -+ Plasma::ExtenderGroup * jobGroup = extender()->group("jobGroup");
6858 -+ if (!jobGroup) {
6859 -+ return;
6860 -+ }
6861 -+
6862 -+ foreach (Plasma::ExtenderItem *item, jobGroup->items()) {
6863 -+ JobWidget *job = dynamic_cast<JobWidget *>(item->widget());
6864 -+ if (job) {
6865 -+ job->poppedUp(show);
6866 -+ }
6867 -+ }
6868 -+}
6869 -+
6870 -+void Notifications::finishJob(Job *job)
6871 -+{
6872 -+ //finished all jobs? hide the mini progressbar
6873 -+ if (m_standaloneJobSummaryDialog && m_manager->jobs().isEmpty()) {
6874 -+ m_standaloneJobSummaryDialog->hide();
6875 -+ }
6876 -+
6877 -+ //create a fake notification
6878 -+ CompletedJobNotification *notification = new CompletedJobNotification(this);
6879 -+ notification->setJob(job);
6880 -+ m_manager->addNotification(notification);
6881 -+
6882 -+ Plasma::ExtenderGroup *group = extender()->group("jobGroup");
6883 -+ if (group) {
6884 -+ // < 3 because the second still hasn't been removed from the extendergroup
6885 -+ group->setCollapsed(!group->isGroupCollapsed() && group->items().count() < 3);
6886 -+ }
6887 -+}
6888 -+
6889 -+void Notifications::open(const QString &url)
6890 -+{
6891 -+ //kDebug() << "open " << url;
6892 -+ QProcess::startDetached("kde-open", QStringList() << url);
6893 -+}
6894 -+
6895 -+void Notifications::createJobGroups()
6896 -+{
6897 -+ if (!extender()->hasItem("jobGroup")) {
6898 -+ Plasma::ExtenderGroup *extenderGroup = new Plasma::ExtenderGroup(extender());
6899 -+ extenderGroup->setName("jobGroup");
6900 -+ initExtenderItem(extenderGroup);
6901 -+ extenderGroup->setAutoHide(true);
6902 -+ } else if (extender()->group("jobGroup")) {
6903 -+ extender()->group("jobGroup")->setAutoHide(true);
6904 -+ }
6905 -+}
6906 -+
6907 -+
6908 -+#include "notifications.moc"
6909 -diff --git a/plasma/generic/applets/notifications/ui/notifications.h b/plasma/generic/applets/notifications/ui/notifications.h
6910 -new file mode 100644
6911 -index 0000000..827b28e
6912 ---- /dev/null
6913 -+++ b/plasma/generic/applets/notifications/ui/notifications.h
6914 -@@ -0,0 +1,101 @@
6915 -+/***************************************************************************
6916 -+ * applet.h *
6917 -+ * *
6918 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
6919 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
6920 -+ * *
6921 -+ * This program is free software; you can redistribute it and/or modify *
6922 -+ * it under the terms of the GNU General Public License as published by *
6923 -+ * the Free Software Foundation; either version 2 of the License, or *
6924 -+ * (at your option) any later version. *
6925 -+ * *
6926 -+ * This program is distributed in the hope that it will be useful, *
6927 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
6928 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
6929 -+ * GNU General Public License for more details. *
6930 -+ * *
6931 -+ * You should have received a copy of the GNU General Public License *
6932 -+ * along with this program; if not, write to the *
6933 -+ * Free Software Foundation, Inc., *
6934 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
6935 -+ ***************************************************************************/
6936 -+
6937 -+#ifndef NOTIFICATIONS_H
6938 -+#define NOTIFICATIONS_H
6939 -+
6940 -+#include <plasma/popupapplet.h>
6941 -+
6942 -+#include "ui_notificationsconfig.h"
6943 -+
6944 -+
6945 -+namespace Plasma
6946 -+{
6947 -+class ExtenderItem;
6948 -+class TabBar;
6949 -+class Dialog;
6950 -+}
6951 -+
6952 -+class NotificationWidget;
6953 -+class StackDialog;
6954 -+
6955 -+
6956 -+class Job;
6957 -+class JobTotalsWidget;
6958 -+class Manager;
6959 -+class Notification;
6960 -+class NotificationGroup;
6961 -+class NotificationStack;
6962 -+class BusyWidget;
6963 -+
6964 -+class Notifications : public Plasma::PopupApplet
6965 -+{
6966 -+ Q_OBJECT
6967 -+
6968 -+public:
6969 -+ explicit Notifications(QObject *parent, const QVariantList &arguments = QVariantList());
6970 -+ ~Notifications();
6971 -+
6972 -+ void init();
6973 -+ Manager *manager() const;
6974 -+
6975 -+protected:
6976 -+ void createConfigurationInterface(KConfigDialog *parent);
6977 -+ void initExtenderItem(Plasma::ExtenderItem *extenderItem);
6978 -+ void configChanged();
6979 -+
6980 -+ void popupEvent(bool show);
6981 -+
6982 -+private slots:
6983 -+ void configAccepted();
6984 -+ void addNotification(Notification *notification);
6985 -+ void addJob(Job *job);
6986 -+ void finishJob(Job *job);
6987 -+ void open(const QString &url);
6988 -+ void syncNotificationBarNeeded();
6989 -+
6990 -+private:
6991 -+ void createJobGroups();
6992 -+
6993 -+ Manager *m_manager;
6994 -+ static int s_managerUsage;
6995 -+
6996 -+ QWeakPointer<QWidget> m_notificationInterface;
6997 -+ QDateTime m_lastActivity;
6998 -+
6999 -+ JobTotalsWidget *m_jobSummaryWidget;
7000 -+ bool m_autoHidePopup;
7001 -+
7002 -+ QWeakPointer<NotificationGroup> m_notificationGroup;
7003 -+ NotificationStack *m_notificationStack;
7004 -+ StackDialog *m_notificationStackDialog;
7005 -+ JobTotalsWidget *m_standaloneJobSummaryWidget;
7006 -+ Plasma::Dialog *m_standaloneJobSummaryDialog;
7007 -+
7008 -+ BusyWidget *m_busyWidget;
7009 -+
7010 -+ Ui::NotificationsConfig m_notificationUi;
7011 -+};
7012 -+
7013 -+
7014 -+
7015 -+#endif
7016 -diff --git a/plasma/generic/applets/notifications/ui/notificationsconfig.ui b/plasma/generic/applets/notifications/ui/notificationsconfig.ui
7017 -new file mode 100644
7018 -index 0000000..aaa6a82
7019 ---- /dev/null
7020 -+++ b/plasma/generic/applets/notifications/ui/notificationsconfig.ui
7021 -@@ -0,0 +1,114 @@
7022 -+<?xml version="1.0" encoding="UTF-8"?>
7023 -+<ui version="4.0">
7024 -+ <class>NotificationsConfig</class>
7025 -+ <widget class="QWidget" name="ProtocolsConfig">
7026 -+ <property name="geometry">
7027 -+ <rect>
7028 -+ <x>0</x>
7029 -+ <y>0</y>
7030 -+ <width>213</width>
7031 -+ <height>236</height>
7032 -+ </rect>
7033 -+ </property>
7034 -+ <layout class="QFormLayout" name="formLayout">
7035 -+ <property name="fieldGrowthPolicy">
7036 -+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
7037 -+ </property>
7038 -+ <item row="0" column="0" colspan="2">
7039 -+ <widget class="QLabel" name="label_2">
7040 -+ <property name="font">
7041 -+ <font>
7042 -+ <weight>75</weight>
7043 -+ <bold>true</bold>
7044 -+ </font>
7045 -+ </property>
7046 -+ <property name="text">
7047 -+ <string>Pop Up Notices</string>
7048 -+ </property>
7049 -+ </widget>
7050 -+ </item>
7051 -+ <item row="2" column="0">
7052 -+ <widget class="QLabel" name="label_4">
7053 -+ <property name="text">
7054 -+ <string>Application notifications</string>
7055 -+ </property>
7056 -+ <property name="buddy">
7057 -+ <cstring>showNotifications</cstring>
7058 -+ </property>
7059 -+ </widget>
7060 -+ </item>
7061 -+ <item row="2" column="1">
7062 -+ <widget class="QCheckBox" name="showNotifications">
7063 -+ <property name="text">
7064 -+ <string/>
7065 -+ </property>
7066 -+ </widget>
7067 -+ </item>
7068 -+ <item row="4" column="0">
7069 -+ <widget class="QLabel" name="label_5">
7070 -+ <property name="text">
7071 -+ <string>File transfers and other jobs</string>
7072 -+ </property>
7073 -+ <property name="buddy">
7074 -+ <cstring>showJobs</cstring>
7075 -+ </property>
7076 -+ </widget>
7077 -+ </item>
7078 -+ <item row="4" column="1">
7079 -+ <widget class="QCheckBox" name="showJobs">
7080 -+ <property name="text">
7081 -+ <string/>
7082 -+ </property>
7083 -+ </widget>
7084 -+ </item>
7085 -+ <item row="8" column="0">
7086 -+ <spacer name="verticalSpacer">
7087 -+ <property name="orientation">
7088 -+ <enum>Qt::Vertical</enum>
7089 -+ </property>
7090 -+ <property name="sizeType">
7091 -+ <enum>QSizePolicy::Fixed</enum>
7092 -+ </property>
7093 -+ <property name="sizeHint" stdset="0">
7094 -+ <size>
7095 -+ <width>20</width>
7096 -+ <height>6</height>
7097 -+ </size>
7098 -+ </property>
7099 -+ </spacer>
7100 -+ </item>
7101 -+ <item row="9" column="0" colspan="2">
7102 -+ <widget class="QLabel" name="label_3">
7103 -+ <property name="font">
7104 -+ <font>
7105 -+ <weight>75</weight>
7106 -+ <bold>true</bold>
7107 -+ </font>
7108 -+ </property>
7109 -+ <property name="text">
7110 -+ <string>Popup</string>
7111 -+ </property>
7112 -+ </widget>
7113 -+ </item>
7114 -+ <item row="10" column="1">
7115 -+ <widget class="QCheckBox" name="autoHide">
7116 -+ <property name="text">
7117 -+ <string/>
7118 -+ </property>
7119 -+ </widget>
7120 -+ </item>
7121 -+ <item row="10" column="0">
7122 -+ <widget class="QLabel" name="label_10">
7123 -+ <property name="text">
7124 -+ <string>Automatically hide</string>
7125 -+ </property>
7126 -+ <property name="buddy">
7127 -+ <cstring>autoHide</cstring>
7128 -+ </property>
7129 -+ </widget>
7130 -+ </item>
7131 -+ </layout>
7132 -+ </widget>
7133 -+ <resources/>
7134 -+ <connections/>
7135 -+</ui>
7136 -diff --git a/plasma/generic/applets/notifications/ui/notificationstack.cpp b/plasma/generic/applets/notifications/ui/notificationstack.cpp
7137 -new file mode 100644
7138 -index 0000000..f0fc52e
7139 ---- /dev/null
7140 -+++ b/plasma/generic/applets/notifications/ui/notificationstack.cpp
7141 -@@ -0,0 +1,233 @@
7142 -+/***************************************************************************
7143 -+ * notificationstack.cpp *
7144 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
7145 -+ * *
7146 -+ * This program is free software; you can redistribute it and/or modify *
7147 -+ * it under the terms of the GNU General Public License as published by *
7148 -+ * the Free Software Foundation; either version 2 of the License, or *
7149 -+ * (at your option) any later version. *
7150 -+ * *
7151 -+ * This program is distributed in the hope that it will be useful, *
7152 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
7153 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
7154 -+ * GNU General Public License for more details. *
7155 -+ * *
7156 -+ * You should have received a copy of the GNU General Public License *
7157 -+ * along with this program; if not, write to the *
7158 -+ * Free Software Foundation, Inc., *
7159 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
7160 -+ ***************************************************************************/
7161 -+
7162 -+#include "notificationstack.h"
7163 -+#include "../core/notification.h"
7164 -+#include "notificationwidget.h"
7165 -+
7166 -+#include <QGraphicsLinearLayout>
7167 -+#include <QTimer>
7168 -+
7169 -+#include <KDebug>
7170 -+#include <KGlobalSettings>
7171 -+
7172 -+#include <Plasma/FrameSvg>
7173 -+#include <Plasma/Dialog>
7174 -+
7175 -+NotificationStack::NotificationStack(QGraphicsItem *parent)
7176 -+ : QGraphicsWidget(parent),
7177 -+ m_size(4),
7178 -+ m_underMouse(false)
7179 -+{
7180 -+ m_mainLayout = new QGraphicsLinearLayout(Qt::Vertical, this);
7181 -+ m_canDismissTimer = new QTimer(this);
7182 -+ m_canDismissTimer->setSingleShot(true);
7183 -+
7184 -+ m_delayedRemoveTimer = new QTimer(this);
7185 -+ m_delayedRemoveTimer->setSingleShot(true);
7186 -+ connect(m_delayedRemoveTimer, SIGNAL(timeout()), this, SLOT(popNotification()));
7187 -+
7188 -+ setAcceptsHoverEvents(true);
7189 -+}
7190 -+
7191 -+NotificationStack::~NotificationStack()
7192 -+{
7193 -+}
7194 -+
7195 -+void NotificationStack::addNotification(Notification *notification)
7196 -+{
7197 -+ m_canDismissTimer->start(1000);
7198 -+ connect(notification, SIGNAL(notificationDestroyed(Notification*)), this, SLOT(removeNotification(Notification*)), Qt::UniqueConnection);
7199 -+ connect(notification, SIGNAL(expired(Notification*)), this, SLOT(delayedRemoveNotification(Notification*)), Qt::UniqueConnection);
7200 -+ connect(notification, SIGNAL(changed(Notification*)), this, SLOT(notificationChanged(Notification*)), Qt::UniqueConnection);
7201 -+
7202 -+ NotificationWidget *notificationWidget = new NotificationWidget(notification, this);
7203 -+ notificationWidget->installEventFilter(this);
7204 -+ notificationWidget->setAcceptsHoverEvents(this);
7205 -+ connect(notificationWidget, SIGNAL(actionTriggered(Notification*)), this, SLOT(removeNotification(Notification*)));
7206 -+
7207 -+ m_notificationWidgets[notification] = notificationWidget;
7208 -+ m_notifications.append(notification);
7209 -+
7210 -+ if (m_notifications.size() > 1) {
7211 -+ notificationWidget->setCollapsed(true, false);
7212 -+ } else {
7213 -+ m_currentNotificationWidget = notificationWidget;
7214 -+ }
7215 -+
7216 -+ if (m_notifications.size() > m_size) {
7217 -+ bool found = false;
7218 -+
7219 -+ //try to kill the oldest notification of the same app
7220 -+ foreach (Notification *notif, m_notifications) {
7221 -+ if (notif->applicationName() == notification->applicationName()) {
7222 -+ m_notificationWidgets[notif]->deleteLater();
7223 -+ m_notificationWidgets.remove(notif);
7224 -+ m_notifications.removeAll(notif);
7225 -+ found = true;
7226 -+ break;
7227 -+ }
7228 -+ }
7229 -+ //or kill the oldest one
7230 -+ if (!found) {
7231 -+ Notification *notif = m_notifications.first();
7232 -+ m_notificationWidgets[notif]->deleteLater();
7233 -+ m_notificationWidgets.remove(notif);
7234 -+ m_notifications.pop_front();
7235 -+ }
7236 -+ }
7237 -+
7238 -+ m_mainLayout->insertItem(0, notificationWidget);
7239 -+ m_mainLayout->activate();
7240 -+ updateGeometry();
7241 -+ resize(size().width(), effectiveSizeHint(Qt::MinimumSize).height());
7242 -+ emit updateRequested();
7243 -+}
7244 -+
7245 -+void NotificationStack::notificationChanged(Notification *notification)
7246 -+{
7247 -+ //if it was gone away put in on the stack again
7248 -+ if (!m_notificationWidgets.contains(notification)) {
7249 -+ addNotification(notification);
7250 -+ }
7251 -+ emit showRequested();
7252 -+}
7253 -+
7254 -+void NotificationStack::removeNotification(Notification *notification)
7255 -+{
7256 -+ NotificationWidget *nw = m_notificationWidgets.value(notification);
7257 -+ if (nw) {
7258 -+ nw->deleteLater();
7259 -+ }
7260 -+ m_mainLayout->removeItem(nw);
7261 -+ m_notificationWidgets.remove(notification);
7262 -+ m_notifications.removeAll(notification);
7263 -+
7264 -+ if (m_notifications.count() > 0) {
7265 -+ setCurrentNotification(m_notifications.first());
7266 -+ }
7267 -+
7268 -+ if (m_notifications.count() == 0) {
7269 -+ emit stackEmpty();
7270 -+ }
7271 -+
7272 -+ updateGeometry();
7273 -+ resize(size().width(), sizeHint(Qt::MinimumSize, QSizeF()).height());
7274 -+ emit updateRequested();
7275 -+}
7276 -+
7277 -+void NotificationStack::delayedRemoveNotification(Notification *notification)
7278 -+{
7279 -+ m_notificationsToRemove.append(notification);
7280 -+ if (!m_underMouse) {
7281 -+ m_delayedRemoveTimer->start(1000);
7282 -+ }
7283 -+}
7284 -+
7285 -+void NotificationStack::setCurrentNotification(Notification *notification)
7286 -+{
7287 -+ if (m_notificationWidgets.contains(notification)) {
7288 -+ if (m_currentNotificationWidget) {
7289 -+ m_currentNotificationWidget.data()->setCollapsed(true);
7290 -+ }
7291 -+ m_currentNotificationWidget = m_notificationWidgets.value(notification);
7292 -+ m_currentNotificationWidget.data()->setCollapsed(false);
7293 -+ }
7294 -+}
7295 -+
7296 -+void NotificationStack::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
7297 -+{
7298 -+ Q_UNUSED(event)
7299 -+
7300 -+ m_underMouse = true;
7301 -+ m_delayedRemoveTimer->stop();
7302 -+}
7303 -+
7304 -+void NotificationStack::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
7305 -+{
7306 -+ Q_UNUSED(event)
7307 -+
7308 -+ m_underMouse = false;
7309 -+ m_delayedRemoveTimer->start(1000);
7310 -+}
7311 -+
7312 -+void NotificationStack::mousePressEvent(QGraphicsSceneMouseEvent *event)
7313 -+{
7314 -+ event->accept();
7315 -+}
7316 -+
7317 -+void NotificationStack::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
7318 -+{
7319 -+ Q_UNUSED(event)
7320 -+
7321 -+ if (!m_canDismissTimer->isActive() &&
7322 -+ QPointF(event->buttonDownScenePos(event->button()) - event->scenePos()).manhattanLength() < KGlobalSettings::dndEventDelay()) {
7323 -+ emit hideRequested();
7324 -+ }
7325 -+}
7326 -+
7327 -+NotificationWidget *NotificationStack::currentNotificationWidget() const
7328 -+{
7329 -+ if (m_currentNotificationWidget) {
7330 -+ return m_currentNotificationWidget.data();
7331 -+ } else {
7332 -+ return 0;
7333 -+ }
7334 -+}
7335 -+
7336 -+bool NotificationStack::eventFilter(QObject *watched, QEvent *event)
7337 -+{
7338 -+ NotificationWidget *nw = qobject_cast<NotificationWidget *>(watched);
7339 -+
7340 -+ if (!nw) {
7341 -+ return false;
7342 -+ }
7343 -+
7344 -+ if (event->type() == QEvent::GraphicsSceneHoverEnter) {
7345 -+ if (m_currentNotificationWidget && m_currentNotificationWidget.data() == nw) {
7346 -+ return false;
7347 -+ } else if (m_currentNotificationWidget) {
7348 -+ m_currentNotificationWidget.data()->setCollapsed(true);
7349 -+ }
7350 -+ nw->setCollapsed(false);
7351 -+ m_currentNotificationWidget = nw;
7352 -+ m_canDismissTimer->start(1000);
7353 -+ } else if (event->type() == QEvent::GraphicsSceneMove) {
7354 -+ emit updateRequested();
7355 -+ }
7356 -+
7357 -+
7358 -+ return false;
7359 -+}
7360 -+
7361 -+void NotificationStack::popNotification()
7362 -+{
7363 -+ if (m_notificationsToRemove.isEmpty()) {
7364 -+ return;
7365 -+ }
7366 -+
7367 -+ Notification *notif = m_notificationsToRemove.first();
7368 -+ removeNotification(notif);
7369 -+ m_notificationsToRemove.pop_front();
7370 -+ m_delayedRemoveTimer->start(1000);
7371 -+}
7372 -+
7373 -+
7374 -+#include "notificationstack.moc"
7375 -diff --git a/plasma/generic/applets/notifications/ui/notificationstack.h b/plasma/generic/applets/notifications/ui/notificationstack.h
7376 -new file mode 100644
7377 -index 0000000..783e5ae
7378 ---- /dev/null
7379 -+++ b/plasma/generic/applets/notifications/ui/notificationstack.h
7380 -@@ -0,0 +1,81 @@
7381 -+/***************************************************************************
7382 -+ * notificationscroller.h *
7383 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
7384 -+ * *
7385 -+ * This program is free software; you can redistribute it and/or modify *
7386 -+ * it under the terms of the GNU General Public License as published by *
7387 -+ * the Free Software Foundation; either version 2 of the License, or *
7388 -+ * (at your option) any later version. *
7389 -+ * *
7390 -+ * This program is distributed in the hope that it will be useful, *
7391 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
7392 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
7393 -+ * GNU General Public License for more details. *
7394 -+ * *
7395 -+ * You should have received a copy of the GNU General Public License *
7396 -+ * along with this program; if not, write to the *
7397 -+ * Free Software Foundation, Inc., *
7398 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
7399 -+ ***************************************************************************/
7400 -+
7401 -+#ifndef NOTIFICATIONSTACK_H
7402 -+#define NOTIFICATIONSTACK_H
7403 -+
7404 -+#include <QGraphicsWidget>
7405 -+
7406 -+class QGraphicsLinearLayout;
7407 -+class QTimer;
7408 -+
7409 -+class NotificationWidget;
7410 -+
7411 -+class Notification;
7412 -+
7413 -+class NotificationStack : public QGraphicsWidget
7414 -+{
7415 -+ Q_OBJECT
7416 -+
7417 -+public:
7418 -+ NotificationStack(QGraphicsItem *parent = 0);
7419 -+ ~NotificationStack();
7420 -+
7421 -+ void addNotification(Notification *notification);
7422 -+
7423 -+ //TODO:accessor
7424 -+ void setCurrentNotification(Notification *notification);
7425 -+
7426 -+ NotificationWidget *currentNotificationWidget() const;
7427 -+
7428 -+protected:
7429 -+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
7430 -+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
7431 -+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
7432 -+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
7433 -+ bool eventFilter(QObject *watched, QEvent *event);
7434 -+
7435 -+public Q_SLOTS:
7436 -+ void removeNotification(Notification *notification);
7437 -+ void delayedRemoveNotification(Notification *notification);
7438 -+
7439 -+private Q_SLOTS:
7440 -+ void popNotification();
7441 -+ void notificationChanged(Notification *notification);
7442 -+
7443 -+Q_SIGNALS:
7444 -+ void stackEmpty();
7445 -+ void updateRequested();
7446 -+ void hideRequested();
7447 -+ void showRequested();
7448 -+
7449 -+private:
7450 -+ QList<Notification *> m_notifications;
7451 -+ QList<Notification *> m_notificationsToRemove;
7452 -+ QHash<Notification *, NotificationWidget *> m_notificationWidgets;
7453 -+ QGraphicsLinearLayout *m_mainLayout;
7454 -+ int m_size;
7455 -+ bool m_underMouse;
7456 -+ QWeakPointer<NotificationWidget> m_currentNotificationWidget;
7457 -+ QTimer *m_delayedRemoveTimer;
7458 -+ QTimer *m_canDismissTimer;
7459 -+};
7460 -+
7461 -+#endif
7462 -diff --git a/plasma/generic/applets/notifications/ui/notificationwidget.cpp b/plasma/generic/applets/notifications/ui/notificationwidget.cpp
7463 -new file mode 100644
7464 -index 0000000..02ed38f
7465 ---- /dev/null
7466 -+++ b/plasma/generic/applets/notifications/ui/notificationwidget.cpp
7467 -@@ -0,0 +1,486 @@
7468 -+/***************************************************************************
7469 -+ * notificationwidget.cpp *
7470 -+ * *
7471 -+ * Copyright (C) 2008 Dmitry Suzdalev <dimsuz@×××××.com> *
7472 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
7473 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
7474 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
7475 -+ * *
7476 -+ * This program is free software; you can redistribute it and/or modify *
7477 -+ * it under the terms of the GNU Library General Public License as *
7478 -+ * published by the Free Software Foundation; either version 2 of the *
7479 -+ * License, or (at your option) any later version. *
7480 -+ * *
7481 -+ * This program is distributed in the hope that it will be useful, *
7482 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
7483 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
7484 -+ * GNU Library General Public License for more details. *
7485 -+ * *
7486 -+ * You should have received a copy of the GNU Library General Public *
7487 -+ * License along with this library; if not, write to the *
7488 -+ * Free Software Foundation, Inc., *
7489 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
7490 -+ ***************************************************************************/
7491 -+
7492 -+#include "notificationwidget.h"
7493 -+
7494 -+#include <QSignalMapper>
7495 -+
7496 -+#include <QtGui/QGraphicsLinearLayout>
7497 -+#include <QtGui/QGraphicsGridLayout>
7498 -+#include <QtGui/QTextDocument>
7499 -+#include <QtGui/QFontMetrics>
7500 -+#include <QtGui/QGraphicsSceneResizeEvent>
7501 -+#include <QtGui/QPainter>
7502 -+#include <QAction>
7503 -+#include <QLabel>
7504 -+#include <QPropertyAnimation>
7505 -+#include <QParallelAnimationGroup>
7506 -+
7507 -+#include <KColorScheme>
7508 -+#include <KPushButton>
7509 -+#include <KTextBrowser>
7510 -+
7511 -+#include <Plasma/Animation>
7512 -+#include <Plasma/Animator>
7513 -+#include <Plasma/Frame>
7514 -+#include <Plasma/IconWidget>
7515 -+#include <Plasma/Label>
7516 -+#include <Plasma/PushButton>
7517 -+#include <Plasma/TextBrowser>
7518 -+#include <Plasma/Theme>
7519 -+
7520 -+class NotificationWidgetPrivate
7521 -+{
7522 -+public:
7523 -+ NotificationWidgetPrivate(NotificationWidget *q)
7524 -+ : q(q),
7525 -+ destroyOnClose(true),
7526 -+ autoDelete(false),
7527 -+ collapsed(false),
7528 -+ icon(0),
7529 -+ actionsWidget(0),
7530 -+ signalMapper(new QSignalMapper(q))
7531 -+ {
7532 -+ }
7533 -+
7534 -+ void setTextFields(const QString &applicationName, const QString &summary, const QString &message);
7535 -+ void completeDetach();
7536 -+ void updateActions();
7537 -+ void updateNotification();
7538 -+ void buttonClicked();
7539 -+ void hideFinished();
7540 -+ QRectF bigIconRect() const;
7541 -+
7542 -+ NotificationWidget *q;
7543 -+
7544 -+ QWeakPointer<Notification> notification;
7545 -+ bool destroyOnClose;
7546 -+ bool autoDelete;
7547 -+ bool collapsed;
7548 -+
7549 -+ QString message;
7550 -+ Plasma::TextBrowser *messageLabel;
7551 -+ Plasma::Label *title;
7552 -+ Plasma::IconWidget *closeButton;
7553 -+ Plasma::IconWidget *icon;
7554 -+ QGraphicsLinearLayout *titleLayout;
7555 -+ QGraphicsLinearLayout *mainLayout;
7556 -+ QGraphicsGridLayout *bodyLayout;
7557 -+ QGraphicsWidget *body;
7558 -+ QGraphicsWidget *iconPlaceSmall;
7559 -+ QGraphicsWidget *iconPlaceBig;
7560 -+ QGraphicsWidget *actionsWidget;
7561 -+ QHash<QString, QString> actions;
7562 -+ QStringList actionOrder;
7563 -+ QPropertyAnimation *hideAnimation;
7564 -+ QPropertyAnimation *iconAnimation;
7565 -+ QParallelAnimationGroup *animationGroup;
7566 -+
7567 -+ QSignalMapper *signalMapper;
7568 -+};
7569 -+
7570 -+NotificationWidget::NotificationWidget(Notification *notification, QGraphicsWidget *parent)
7571 -+ : QGraphicsWidget(parent),
7572 -+ d(new NotificationWidgetPrivate(this))
7573 -+{
7574 -+ setFlag(QGraphicsItem::ItemHasNoContents, true);
7575 -+ setMinimumWidth(300);
7576 -+
7577 -+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
7578 -+
7579 -+
7580 -+ d->iconPlaceSmall = new QGraphicsWidget(this);
7581 -+ d->iconPlaceSmall->setMinimumSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
7582 -+ d->iconPlaceSmall->setMaximumSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
7583 -+ d->icon = new Plasma::IconWidget(this);
7584 -+ d->icon->setAcceptHoverEvents(false);
7585 -+ d->icon->setAcceptedMouseButtons(Qt::NoButton);
7586 -+
7587 -+ d->title = new Plasma::Label(this);
7588 -+ d->title->setWordWrap(false);
7589 -+ d->title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
7590 -+ d->title->setAlignment(Qt::AlignCenter);
7591 -+
7592 -+ d->closeButton = new Plasma::IconWidget(this);
7593 -+ d->closeButton->setSvg("widgets/configuration-icons", "close");
7594 -+ d->closeButton->setMaximumSize(d->closeButton->sizeFromIconSize(KIconLoader::SizeSmall));
7595 -+ d->closeButton->setMinimumSize(d->closeButton->maximumSize());
7596 -+ connect(d->closeButton, SIGNAL(clicked()), notification, SLOT(deleteLater()));
7597 -+
7598 -+ d->titleLayout = new QGraphicsLinearLayout(Qt::Horizontal);
7599 -+ d->titleLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
7600 -+ d->titleLayout->addItem(d->iconPlaceSmall);
7601 -+ d->titleLayout->addItem(d->title);
7602 -+ d->titleLayout->addItem(d->closeButton);
7603 -+
7604 -+
7605 -+
7606 -+ d->body = new QGraphicsWidget(this);
7607 -+ d->body->setContentsMargins(0,0,0,0);
7608 -+ d->body->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
7609 -+ d->bodyLayout = new QGraphicsGridLayout(d->body);
7610 -+ d->bodyLayout->setSpacing(0);
7611 -+ d->bodyLayout->setContentsMargins(0,0,0,0);
7612 -+
7613 -+ d->messageLabel = new Plasma::TextBrowser(d->body);
7614 -+ d->messageLabel->setPreferredWidth(0);
7615 -+ d->messageLabel->nativeWidget()->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
7616 -+ d->messageLabel->nativeWidget()->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
7617 -+ d->messageLabel->nativeWidget()->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
7618 -+ d->messageLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
7619 -+ connect(d->messageLabel->nativeWidget(), SIGNAL(urlClick(QString)),
7620 -+ notification, SLOT(linkActivated(QString)));
7621 -+
7622 -+ d->iconPlaceBig = new QGraphicsWidget(this);
7623 -+ d->iconPlaceBig->setMaximumHeight(KIconLoader::SizeLarge);
7624 -+ d->iconPlaceBig->setMinimumHeight(KIconLoader::SizeLarge);
7625 -+ d->iconPlaceBig->setMaximumWidth(KIconLoader::SizeLarge);
7626 -+ d->iconPlaceBig->setMinimumWidth(KIconLoader::SizeLarge);
7627 -+ d->iconPlaceBig->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
7628 -+ d->bodyLayout->addItem(d->iconPlaceBig, 0, 0, Qt::AlignCenter);
7629 -+ d->bodyLayout->addItem(d->messageLabel, 0, 1, Qt::AlignCenter);
7630 -+
7631 -+ d->mainLayout = new QGraphicsLinearLayout(Qt::Vertical, this);
7632 -+ d->mainLayout->setSpacing(0);
7633 -+ d->mainLayout->addItem(d->titleLayout);
7634 -+ d->mainLayout->addItem(d->body);
7635 -+
7636 -+ d->notification = notification;
7637 -+
7638 -+ connect(d->signalMapper, SIGNAL(mapped(QString)),
7639 -+ notification, SLOT(triggerAction(QString)));
7640 -+ connect(notification, SIGNAL(changed()),
7641 -+ this, SLOT(updateNotification()));
7642 -+ connect(notification, SIGNAL(destroyed()),
7643 -+ this, SLOT(deleteLater()));
7644 -+
7645 -+ d->hideAnimation = new QPropertyAnimation(this, "bodyHeight", this);
7646 -+ d->hideAnimation->setDuration(250);
7647 -+ connect(d->hideAnimation, SIGNAL(finished()), this, SLOT(hideFinished()));
7648 -+
7649 -+ d->iconAnimation = new QPropertyAnimation(d->icon, "geometry", d->icon);
7650 -+ d->iconAnimation->setDuration(250);
7651 -+
7652 -+ d->animationGroup = new QParallelAnimationGroup(this);
7653 -+ d->animationGroup->addAnimation(d->hideAnimation);
7654 -+ d->animationGroup->addAnimation(d->iconAnimation);
7655 -+
7656 -+ d->updateNotification();
7657 -+
7658 -+ d->mainLayout->activate();
7659 -+ updateGeometry();
7660 -+}
7661 -+
7662 -+NotificationWidget::~NotificationWidget()
7663 -+{
7664 -+ delete d;
7665 -+}
7666 -+
7667 -+void NotificationWidget::setCollapsed(bool collapse, bool animate)
7668 -+{
7669 -+ if (collapse == d->collapsed) {
7670 -+ return;
7671 -+ }
7672 -+
7673 -+ setTitleBarVisible(true);
7674 -+
7675 -+ //use this weird way to make easy to animate
7676 -+ if (animate) {
7677 -+ setMinimumHeight(-1);
7678 -+ if (collapse) {
7679 -+ d->hideAnimation->setStartValue(d->body->size().height());
7680 -+ d->hideAnimation->setEndValue(0);
7681 -+
7682 -+ d->iconAnimation->setStartValue(d->icon->geometry());
7683 -+ d->iconAnimation->setEndValue(d->iconPlaceSmall->geometry());
7684 -+ d->animationGroup->start();
7685 -+ } else {
7686 -+ d->body->setVisible(true);
7687 -+ d->hideAnimation->setStartValue(d->body->size().height());
7688 -+ d->body->setMaximumHeight(-1);
7689 -+ d->hideAnimation->setEndValue(d->body->effectiveSizeHint(Qt::PreferredSize).height());
7690 -+
7691 -+ d->iconAnimation->setStartValue(d->icon->geometry());
7692 -+ d->iconAnimation->setEndValue(d->bigIconRect());
7693 -+ d->animationGroup->start();
7694 -+ }
7695 -+ } else {
7696 -+ if (collapse) {
7697 -+ //setMaximumHeight(d->titleLayout->geometry().bottom());
7698 -+ d->body->setMinimumHeight(0);
7699 -+ d->body->setMaximumHeight(0);
7700 -+ d->body->hide();
7701 -+ setMinimumHeight(-1);
7702 -+ d->icon->setGeometry(d->iconPlaceSmall->geometry());
7703 -+ } else {
7704 -+ d->body->show();
7705 -+ d->body->setMaximumHeight(-1);
7706 -+ d->body->setMinimumHeight(-1);
7707 -+ d->body->setMaximumHeight(d->body->effectiveSizeHint(Qt::PreferredSize).height());
7708 -+ d->body->setMinimumHeight(d->body->maximumHeight());
7709 -+ updateGeometry();
7710 -+ d->mainLayout->invalidate();
7711 -+ setMinimumHeight(sizeHint(Qt::PreferredSize, QSizeF()).height());
7712 -+
7713 -+ d->icon->setGeometry(d->bigIconRect());
7714 -+ }
7715 -+ }
7716 -+
7717 -+ if (collapse) {
7718 -+ d->messageLabel->nativeWidget()->setTextInteractionFlags(Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse|Qt::TextSelectableByKeyboard);
7719 -+ } else {
7720 -+ d->messageLabel->nativeWidget()->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
7721 -+ }
7722 -+
7723 -+ d->body->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
7724 -+
7725 -+ d->collapsed = collapse;
7726 -+}
7727 -+
7728 -+Notification *NotificationWidget::notification() const
7729 -+{
7730 -+ return d->notification.data();
7731 -+}
7732 -+
7733 -+qreal NotificationWidget::bodyHeight() const
7734 -+{
7735 -+ return d->body->maximumHeight();
7736 -+}
7737 -+
7738 -+void NotificationWidget::setBodyHeight(const qreal height)
7739 -+{
7740 -+ d->body->setMaximumHeight(height);
7741 -+ d->body->setMinimumHeight(height);
7742 -+ updateGeometry();
7743 -+ d->mainLayout->invalidate();
7744 -+ setMinimumHeight(sizeHint(Qt::PreferredSize, QSizeF()).height());
7745 -+}
7746 -+
7747 -+bool NotificationWidget::isCollapsed() const
7748 -+{
7749 -+ return d->collapsed;
7750 -+}
7751 -+
7752 -+void NotificationWidget::setTitleBarVisible(bool visible)
7753 -+{
7754 -+ if (visible) {
7755 -+ d->iconPlaceSmall->show();
7756 -+ d->title->show();
7757 -+ d->closeButton->show();
7758 -+ d->titleLayout->setMaximumHeight(QWIDGETSIZE_MAX);
7759 -+ } else {
7760 -+ d->iconPlaceSmall->hide();
7761 -+ d->title->hide();
7762 -+ d->closeButton->hide();
7763 -+ d->titleLayout->setMaximumHeight(0);
7764 -+ }
7765 -+}
7766 -+
7767 -+bool NotificationWidget::isTitleBarVisible() const
7768 -+{
7769 -+ return d->title->isVisible();
7770 -+}
7771 -+
7772 -+void NotificationWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
7773 -+{
7774 -+ QGraphicsWidget::resizeEvent(event);
7775 -+ if (d->icon && !d->collapsed && d->animationGroup->state() != QAbstractAnimation::Running) {
7776 -+ d->icon->setGeometry(d->bigIconRect());
7777 -+ }
7778 -+}
7779 -+
7780 -+QRectF NotificationWidgetPrivate::bigIconRect() const
7781 -+{
7782 -+ return q->mapFromScene(iconPlaceBig->mapToScene(iconPlaceBig->boundingRect())).boundingRect();
7783 -+}
7784 -+
7785 -+void NotificationWidgetPrivate::setTextFields(const QString &applicationName,
7786 -+ const QString &summary, const QString &message)
7787 -+{
7788 -+ if (!summary.isEmpty()) {
7789 -+ title->setText(summary);
7790 -+ } else {
7791 -+ title->setText(i18n("Notification from %1", applicationName));
7792 -+ }
7793 -+
7794 -+
7795 -+ QString processed = message.trimmed();
7796 -+
7797 -+ /*if there is a < that is not closed as a tag, replace it with an entity*/
7798 -+ processed = processed.replace(QRegExp("<(?![^<]*>)"), "&lt;");
7799 -+ processed.replace('\n', "<br>");
7800 -+
7801 -+ QFontMetricsF fm(messageLabel->font());
7802 -+ qreal maxLine = messageLabel->rect().width();
7803 -+
7804 -+ QString parsed;
7805 -+
7806 -+ QString::const_iterator i = processed.begin();
7807 -+ bool inTag = false;
7808 -+ QString word;
7809 -+ QString sentence;
7810 -+
7811 -+ while (i != processed.end()) {
7812 -+ QChar c = *i;
7813 -+
7814 -+ if (c == '<') {
7815 -+ inTag = true;
7816 -+ sentence.append(word);
7817 -+ parsed.append(fm.elidedText(sentence, Qt::ElideRight, maxLine*4.6));
7818 -+ sentence = QString();
7819 -+ word = QString();
7820 -+ word.append(c);
7821 -+ } else if (c == '>') {
7822 -+ word.append(c);
7823 -+ if (!sentence.isEmpty()) {
7824 -+ parsed.append(fm.elidedText(sentence, Qt::ElideRight, maxLine*4.6));
7825 -+ sentence.clear();
7826 -+ }
7827 -+ inTag = false;
7828 -+ parsed.append(word);
7829 -+ word = QString();
7830 -+ } else if (c == ' ') {
7831 -+ word.append(c);
7832 -+ if (inTag) {
7833 -+ parsed.append(word);
7834 -+ } else {
7835 -+ sentence.append(word);
7836 -+ }
7837 -+ word = QString();
7838 -+ } else {
7839 -+ word.append(c);
7840 -+ }
7841 -+
7842 -+ ++i;
7843 -+ }
7844 -+
7845 -+ sentence.append(word);
7846 -+ parsed.append(fm.elidedText(sentence, Qt::ElideRight, maxLine*4.6));
7847 -+
7848 -+ messageLabel->setText(QLatin1String("<html>") + parsed + QLatin1String("</html>"));
7849 -+
7850 -+ if (!collapsed) {
7851 -+ icon->setGeometry(bigIconRect());
7852 -+ }
7853 -+}
7854 -+
7855 -+void NotificationWidgetPrivate::completeDetach()
7856 -+{
7857 -+ actions.clear();
7858 -+ actionOrder.clear();
7859 -+
7860 -+ delete actionsWidget;
7861 -+ actionsWidget = 0;
7862 -+}
7863 -+
7864 -+void NotificationWidgetPrivate::updateActions()
7865 -+{
7866 -+ if (actions.isEmpty() || actionsWidget) {
7867 -+ return;
7868 -+ }
7869 -+
7870 -+ actionsWidget = new QGraphicsWidget(body);
7871 -+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(actionsWidget);
7872 -+ layout->setOrientation(Qt::Vertical);
7873 -+ layout->setContentsMargins(0, 0, 0, 0);
7874 -+ layout->addStretch();
7875 -+ actionsWidget->setContentsMargins(0, 0, 0, 0);
7876 -+
7877 -+ foreach (const QString &actionId, actionOrder) {
7878 -+ Plasma::PushButton *button = new Plasma::PushButton(actionsWidget);
7879 -+ QString &action = actions[actionId];
7880 -+ button->setText(action);
7881 -+ button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
7882 -+ //TODO: we need smaller buttons but I don't like this method of accomplishing it.
7883 -+ button->setPreferredHeight(button->minimumHeight() - 6);
7884 -+
7885 -+ q->connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
7886 -+ q->connect(button, SIGNAL(clicked()), q, SLOT(buttonClicked()));
7887 -+ signalMapper->setMapping(button, actionId);
7888 -+
7889 -+ layout->addItem(button);
7890 -+ }
7891 -+ layout->addStretch();
7892 -+ layout->activate();
7893 -+
7894 -+ if (actionsWidget->size().width() > q->size().width() * 0.4) {
7895 -+ layout->setOrientation(Qt::Horizontal);
7896 -+ bodyLayout->addItem(actionsWidget, 1, 0, 1, 2, Qt::AlignCenter);
7897 -+ } else {
7898 -+ bodyLayout->addItem(actionsWidget, 0, 2, Qt::AlignCenter);
7899 -+ }
7900 -+}
7901 -+
7902 -+void NotificationWidgetPrivate::buttonClicked()
7903 -+{
7904 -+ //a decsion has already been taken
7905 -+ if (actionsWidget) {
7906 -+ notification.data()->deleteLater();
7907 -+ }
7908 -+ emit q->actionTriggered(notification.data());
7909 -+}
7910 -+
7911 -+void NotificationWidgetPrivate::updateNotification()
7912 -+{
7913 -+ if (!notification) {
7914 -+ return;
7915 -+ }
7916 -+
7917 -+
7918 -+ //set text fields and icon
7919 -+ setTextFields(notification.data()->applicationName(), notification.data()->summary(), notification.data()->message());
7920 -+ icon->setIcon(notification.data()->applicationIcon());
7921 -+ messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
7922 -+
7923 -+ //set the actions provided
7924 -+ actions = notification.data()->actions();
7925 -+ actionOrder = notification.data()->actionOrder();
7926 -+ updateActions();
7927 -+
7928 -+ if (!notification.data()->image().isNull()) {
7929 -+
7930 -+ icon->setIcon(QPixmap::fromImage(notification.data()->image()));
7931 -+
7932 -+ QSize imageSize = notification.data()->image().size();
7933 -+
7934 -+ if (imageSize.width() > KIconLoader::SizeLarge || imageSize.height() > KIconLoader::SizeLarge) {
7935 -+ imageSize.scale(KIconLoader::SizeLarge, KIconLoader::SizeLarge, Qt::KeepAspectRatio);
7936 -+ }
7937 -+
7938 -+ icon->setMaximumIconSize(QSizeF(qMin((int)KIconLoader::SizeLarge, imageSize.width()),
7939 -+ qMin((int)KIconLoader::SizeLarge, imageSize.height())));
7940 -+ }
7941 -+
7942 -+
7943 -+ //FIXME: this sounds wrong
7944 -+ q->setPreferredHeight(mainLayout->effectiveSizeHint(Qt::MinimumSize).height());
7945 -+}
7946 -+
7947 -+void NotificationWidgetPrivate::hideFinished()
7948 -+{
7949 -+ body->setVisible(!collapsed);
7950 -+ body->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
7951 -+}
7952 -+
7953 -+#include "notificationwidget.moc"
7954 -diff --git a/plasma/generic/applets/notifications/ui/notificationwidget.h b/plasma/generic/applets/notifications/ui/notificationwidget.h
7955 -new file mode 100644
7956 -index 0000000..7c1a436
7957 ---- /dev/null
7958 -+++ b/plasma/generic/applets/notifications/ui/notificationwidget.h
7959 -@@ -0,0 +1,72 @@
7960 -+/***************************************************************************
7961 -+ * notificationwidget.h *
7962 -+ * *
7963 -+ * Copyright (C) 2008 Dmitry Suzdalev <dimsuz@×××××.com> *
7964 -+ * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@×××××××××××××××.nl> *
7965 -+ * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@×××××.com> *
7966 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
7967 -+ * *
7968 -+ * This program is free software; you can redistribute it and/or modify *
7969 -+ * it under the terms of the GNU Library General Public License as *
7970 -+ * published by the Free Software Foundation; either version 2 of the *
7971 -+ * License, or (at your option) any later version. *
7972 -+ * *
7973 -+ * This program is distributed in the hope that it will be useful, *
7974 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
7975 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
7976 -+ * GNU Library General Public License for more details. *
7977 -+ * *
7978 -+ * You should have received a copy of the GNU Library General Public *
7979 -+ * License along with this library; if not, write to the *
7980 -+ * Free Software Foundation, Inc., *
7981 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
7982 -+ ***************************************************************************/
7983 -+
7984 -+#ifndef NOTIFICATIONWIDGET_H
7985 -+#define NOTIFICATIONWIDGET_H
7986 -+
7987 -+#include <Plasma/Frame>
7988 -+
7989 -+#include "../core/notification.h"
7990 -+
7991 -+class NotificationWidgetPrivate;
7992 -+
7993 -+/**
7994 -+ * A graphics item, representing notification message.
7995 -+ */
7996 -+class NotificationWidget : public QGraphicsWidget
7997 -+{
7998 -+ Q_OBJECT
7999 -+ Q_PROPERTY(qreal bodyHeight READ bodyHeight WRITE setBodyHeight)
8000 -+
8001 -+public:
8002 -+ NotificationWidget(Notification *notification, QGraphicsWidget *parent);
8003 -+ ~NotificationWidget();
8004 -+
8005 -+ void setCollapsed(bool collapse, bool animate = true);
8006 -+ bool isCollapsed() const;
8007 -+
8008 -+ void setTitleBarVisible(bool visible);
8009 -+ bool isTitleBarVisible() const;
8010 -+
8011 -+ qreal bodyHeight() const;
8012 -+ void setBodyHeight(const qreal height);
8013 -+
8014 -+ Notification *notification() const;
8015 -+
8016 -+protected:
8017 -+ void resizeEvent(QGraphicsSceneResizeEvent *event);
8018 -+
8019 -+Q_SIGNALS:
8020 -+ void actionTriggered(Notification *);
8021 -+
8022 -+private:
8023 -+ friend class NotificationWidgetPrivate;
8024 -+ NotificationWidgetPrivate* const d;
8025 -+
8026 -+ Q_PRIVATE_SLOT(d, void updateNotification())
8027 -+ Q_PRIVATE_SLOT(d, void buttonClicked())
8028 -+ Q_PRIVATE_SLOT(d, void hideFinished())
8029 -+};
8030 -+
8031 -+#endif // NOTIFICATIONWIDGET_H
8032 -diff --git a/plasma/generic/applets/notifications/ui/stackdialog.cpp b/plasma/generic/applets/notifications/ui/stackdialog.cpp
8033 -new file mode 100644
8034 -index 0000000..9be364e
8035 ---- /dev/null
8036 -+++ b/plasma/generic/applets/notifications/ui/stackdialog.cpp
8037 -@@ -0,0 +1,446 @@
8038 -+/***************************************************************************
8039 -+ * stacdialog.h *
8040 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
8041 -+ * *
8042 -+ * This program is free software; you can redistribute it and/or modify *
8043 -+ * it under the terms of the GNU General Public License as published by *
8044 -+ * the Free Software Foundation; either version 2 of the License, or *
8045 -+ * (at your option) any later version. *
8046 -+ * *
8047 -+ * This program is distributed in the hope that it will be useful, *
8048 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
8049 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
8050 -+ * GNU General Public License for more details. *
8051 -+ * *
8052 -+ * You should have received a copy of the GNU General Public License *
8053 -+ * along with this program; if not, write to the *
8054 -+ * Free Software Foundation, Inc., *
8055 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
8056 -+ ***************************************************************************/
8057 -+
8058 -+#include "stackdialog.h"
8059 -+#include "notificationstack.h"
8060 -+#include "notificationwidget.h"
8061 -+
8062 -+#include <QApplication>
8063 -+#include <QDesktopWidget>
8064 -+#include <QGraphicsLayout>
8065 -+#include <QLayout>
8066 -+#include <QPropertyAnimation>
8067 -+#include <QTimer>
8068 -+
8069 -+#include <KWindowSystem>
8070 -+
8071 -+#include <Plasma/Applet>
8072 -+#include <Plasma/Containment>
8073 -+#include <Plasma/Corona>
8074 -+#include <Plasma/FrameSvg>
8075 -+#include <Plasma/WindowEffects>
8076 -+
8077 -+static const uint hideTimeout = 15 * 1000;
8078 -+
8079 -+StackDialog::StackDialog(QWidget *parent, Qt::WindowFlags f)
8080 -+ : Plasma::Dialog(parent, f),
8081 -+ m_applet(0),
8082 -+ m_windowToTile(0),
8083 -+ m_notificationStack(0),
8084 -+ m_view(0),
8085 -+ m_drawLeft(true),
8086 -+ m_drawRight(true),
8087 -+ m_autoHide(true),
8088 -+ m_hasCustomPosition(false)
8089 -+{
8090 -+ m_background = new Plasma::FrameSvg(this);
8091 -+ m_background->setImagePath("widgets/extender-background");
8092 -+ setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
8093 -+ KWindowSystem::setType(winId(), NET::Dock);
8094 -+
8095 -+ m_showTimer = new QTimer(this);
8096 -+ m_showTimer->setSingleShot(true);
8097 -+ m_showTimer->setInterval(0);
8098 -+ connect(m_showTimer, SIGNAL(timeout()), this, SLOT(show()));
8099 -+
8100 -+ m_hideTimer = new QTimer(this);
8101 -+ m_hideTimer->setSingleShot(true);
8102 -+ connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(hideRequested()));
8103 -+}
8104 -+
8105 -+StackDialog::~StackDialog()
8106 -+{
8107 -+}
8108 -+
8109 -+void StackDialog::setNotificationStack(NotificationStack *stack)
8110 -+{
8111 -+ setGraphicsWidget(stack);
8112 -+
8113 -+ if (!m_view && layout()) {
8114 -+ m_view = qobject_cast<QGraphicsView *>(layout()->itemAt(0)->widget());
8115 -+ if (m_view) {
8116 -+ m_view->installEventFilter(this);
8117 -+ }
8118 -+ }
8119 -+
8120 -+ if (m_notificationStack) {
8121 -+ disconnect(m_notificationStack, 0, this, 0);
8122 -+ }
8123 -+
8124 -+ m_notificationStack = stack;
8125 -+
8126 -+ connect(m_notificationStack, SIGNAL(updateRequested()), this, SLOT(update()));
8127 -+ connect(m_notificationStack, SIGNAL(hideRequested()), this, SLOT(hideRequested()));
8128 -+}
8129 -+
8130 -+NotificationStack *StackDialog::notificartionStack() const
8131 -+{
8132 -+ return m_notificationStack;
8133 -+}
8134 -+
8135 -+void StackDialog::setApplet(Plasma::Applet *applet)
8136 -+{
8137 -+ m_applet = applet;
8138 -+ adjustPosition(QPoint(-1, -1));
8139 -+}
8140 -+
8141 -+Plasma::Applet *StackDialog::applet() const
8142 -+{
8143 -+ return m_applet;
8144 -+}
8145 -+
8146 -+void StackDialog::setWindowToTile(QWidget *widget)
8147 -+{
8148 -+ if (m_windowToTile) {
8149 -+ m_windowToTile->removeEventFilter(this);
8150 -+ delete m_windowToTileAnimation;
8151 -+ }
8152 -+
8153 -+ m_windowToTile = widget;
8154 -+ m_windowToTile->installEventFilter(this);
8155 -+ m_windowToTileAnimation = new QPropertyAnimation(m_windowToTile, "pos", this);
8156 -+ m_windowToTileAnimation->setDuration(250);
8157 -+ m_windowToTileAnimation->setEasingCurve(QEasingCurve::InOutQuad);
8158 -+}
8159 -+
8160 -+QWidget *StackDialog::windowToTile() const
8161 -+{
8162 -+ return m_windowToTile;
8163 -+}
8164 -+
8165 -+void StackDialog::setAutoHide(const bool autoHide)
8166 -+{
8167 -+ m_autoHide = autoHide;
8168 -+}
8169 -+
8170 -+bool StackDialog::autoHide() const
8171 -+{
8172 -+ return m_autoHide;
8173 -+}
8174 -+
8175 -+void StackDialog::adjustWindowToTilePos()
8176 -+{
8177 -+ if (m_applet && m_windowToTile && m_hasCustomPosition) {
8178 -+ m_windowToTileAnimation->setStartValue(m_windowToTile->pos());
8179 -+
8180 -+ if (isVisible()) {
8181 -+ const QRect realScreenRect = qApp->desktop()->screenGeometry(m_applet->containment()->screen());
8182 -+ if (m_applet->location() == Plasma::TopEdge || (pos().y() - realScreenRect.top()) < m_windowToTile->size().height()) {
8183 -+ m_windowToTileAnimation->setEndValue(QPoint(m_windowToTile->pos().x(), geometry().bottom()));
8184 -+ } else {
8185 -+ m_windowToTileAnimation->setEndValue(QPoint(m_windowToTile->pos().x(), pos().y() - m_windowToTile->size().height()));
8186 -+ }
8187 -+ } else if (m_applet && m_applet->containment() && m_applet->containment()->corona()) {
8188 -+ m_windowToTileAnimation->setEndValue(QPoint(m_applet->containment()->corona()->popupPosition(m_applet, m_windowToTile->size())));
8189 -+ }
8190 -+ m_windowToTileAnimation->start();
8191 -+ }
8192 -+}
8193 -+
8194 -+void StackDialog::paintEvent(QPaintEvent *e)
8195 -+{
8196 -+ Plasma::Dialog::paintEvent(e);
8197 -+
8198 -+ QPainter painter(this);
8199 -+ if (m_notificationStack) {
8200 -+ //FIXME: assumption++
8201 -+ QGraphicsLayout *mainLayout = static_cast<QGraphicsLayout *>(m_notificationStack->layout());
8202 -+
8203 -+ if (!m_notificationStack->currentNotificationWidget() || mainLayout->count() < 2) {
8204 -+ return;
8205 -+ }
8206 -+
8207 -+ for (int i = 0; i < mainLayout->count(); ++i) {
8208 -+ //assumption++ all items are NotificationWidget
8209 -+ NotificationWidget *nw = static_cast<NotificationWidget *>(mainLayout->itemAt(i));
8210 -+
8211 -+ //first element
8212 -+ if (i == 0 && m_notificationStack->currentNotificationWidget() != nw) {
8213 -+ continue;
8214 -+ } else if (i == 0) {
8215 -+ m_background->setEnabledBorders((Plasma::FrameSvg::EnabledBorders)(Plasma::FrameSvg::AllBorders&~Plasma::FrameSvg::TopBorder));
8216 -+ //last element
8217 -+ } else if (i == mainLayout->count()-1 && m_notificationStack->currentNotificationWidget() != nw) {
8218 -+ continue;
8219 -+ } else if (i == mainLayout->count()-1) {
8220 -+ m_background->setEnabledBorders((Plasma::FrameSvg::EnabledBorders)Plasma::FrameSvg::AllBorders&~Plasma::FrameSvg::BottomBorder);
8221 -+ //element under the active one
8222 -+ } else if (m_notificationStack->currentNotificationWidget()->pos().y() < nw->pos().y()) {
8223 -+ m_background->setEnabledBorders((Plasma::FrameSvg::EnabledBorders)Plasma::FrameSvg::AllBorders&~Plasma::FrameSvg::TopBorder);
8224 -+ //element over the active one
8225 -+ } else if (m_notificationStack->currentNotificationWidget()->pos().y() > nw->pos().y()) {
8226 -+ m_background->setEnabledBorders((Plasma::FrameSvg::EnabledBorders)Plasma::FrameSvg::AllBorders&~Plasma::FrameSvg::BottomBorder);
8227 -+ //active element
8228 -+ } else {
8229 -+ m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders);
8230 -+ }
8231 -+
8232 -+ qreal left, top, right, bottom;
8233 -+ m_background->getMargins(left, top, right, bottom);
8234 -+ m_background->resizeFrame(QSizeF(size().width(), nw->size().height() + top + bottom));
8235 -+
8236 -+ Plasma::FrameSvg::EnabledBorders borders = m_background->enabledBorders();
8237 -+
8238 -+ if (!m_drawLeft) {
8239 -+ borders &= ~Plasma::FrameSvg::LeftBorder;
8240 -+ }
8241 -+
8242 -+ if (!m_drawRight) {
8243 -+ borders &= ~Plasma::FrameSvg::RightBorder;
8244 -+ }
8245 -+
8246 -+ m_background->setEnabledBorders(borders);
8247 -+
8248 -+ const int topMargin = contentsRect().top();
8249 -+ m_background->paintFrame(&painter, QPointF(0, nw->pos().y() - top + topMargin));
8250 -+ }
8251 -+ }
8252 -+}
8253 -+
8254 -+void StackDialog::perhapsShow()
8255 -+{
8256 -+ if (m_applet && m_applet->view()) {
8257 -+ // we use a timer here because when the stack is going to be shown, the applet is likely
8258 -+ // to also be in movement (e.g. from hidden away to now shown to the user) and that will
8259 -+ // likely result in an odd geometry for the applet when popupPosition is called on this
8260 -+ // dialog. so instead we wait a bit after the show request to allow the applet to find
8261 -+ // it's proper place
8262 -+ m_showTimer->start();
8263 -+ }
8264 -+}
8265 -+
8266 -+void StackDialog::showEvent(QShowEvent *event)
8267 -+{
8268 -+ Q_UNUSED(event)
8269 -+
8270 -+ adjustPosition(adjustedSavedPos());
8271 -+ adjustWindowToTilePos();
8272 -+
8273 -+ if (m_autoHide) {
8274 -+ m_hideTimer->start(hideTimeout);
8275 -+ }
8276 -+
8277 -+ Plasma::Dialog::showEvent(event);
8278 -+}
8279 -+
8280 -+void StackDialog::hideRequested()
8281 -+{
8282 -+ // we have this method because hide() may not always cause a hideEvent, e.g. when
8283 -+ // the StackDialog has not been shown yet .. however, we always want to ensure the
8284 -+ // show timer is stopped. we also stop it in the hideEvent for completeness and to
8285 -+ // catch any direct calls to hide() that may happen
8286 -+ m_showTimer->stop();
8287 -+ hide();
8288 -+}
8289 -+
8290 -+void StackDialog::hideEvent(QHideEvent *event)
8291 -+{
8292 -+ Q_UNUSED(event)
8293 -+
8294 -+ m_showTimer->stop();
8295 -+ m_hideTimer->stop();
8296 -+
8297 -+ adjustWindowToTilePos();
8298 -+
8299 -+ m_notificationStack->adjustSize();
8300 -+ Plasma::Dialog::hideEvent(event);
8301 -+}
8302 -+
8303 -+void StackDialog::resizeEvent(QResizeEvent *event)
8304 -+{
8305 -+ Q_UNUSED(event)
8306 -+ adjustWindowToTilePos();
8307 -+ Plasma::Dialog::resizeEvent(event);
8308 -+ if (m_hasCustomPosition) {
8309 -+ adjustPosition(pos());
8310 -+ } else if (m_applet && m_applet->containment() && m_applet->containment()->corona()) {
8311 -+ move(m_applet->containment()->corona()->popupPosition(m_applet, size()));
8312 -+ }
8313 -+}
8314 -+
8315 -+void StackDialog::moveEvent(QMoveEvent *event)
8316 -+{
8317 -+ Q_UNUSED(event)
8318 -+
8319 -+ adjustWindowToTilePos();
8320 -+ Plasma::Dialog::moveEvent(event);
8321 -+}
8322 -+
8323 -+void StackDialog::enterEvent(QEvent *event)
8324 -+{
8325 -+ Q_UNUSED(event)
8326 -+
8327 -+ m_hideTimer->stop();
8328 -+}
8329 -+
8330 -+void StackDialog::leaveEvent(QEvent *event)
8331 -+{
8332 -+ Q_UNUSED(event)
8333 -+
8334 -+ if (m_autoHide) {
8335 -+ m_hideTimer->start(hideTimeout);
8336 -+ }
8337 -+ Plasma::Dialog::leaveEvent(event);
8338 -+}
8339 -+
8340 -+void StackDialog::adjustPosition(const QPoint &pos)
8341 -+{
8342 -+ if (!m_applet) {
8343 -+ return;
8344 -+ }
8345 -+
8346 -+ if (pos == QPoint(-1, -1)) {
8347 -+ const QPoint popupPosition = m_applet->containment()->corona()->popupPosition(m_applet, size());
8348 -+ move(popupPosition);
8349 -+ Plasma::WindowEffects::slideWindow(this, m_applet->location());
8350 -+ m_hasCustomPosition = false;
8351 -+ } else {
8352 -+ QPoint customPosition = pos;
8353 -+
8354 -+ if (m_applet->containment() &&
8355 -+ m_applet->containment()->corona() &&
8356 -+ m_notificationStack) {
8357 -+ QRect screenRect = m_applet->containment()->corona()->availableScreenRegion(m_applet->containment()->screen()).boundingRect();
8358 -+
8359 -+ customPosition.rx() = qMax(customPosition.x(), screenRect.left());
8360 -+ customPosition.ry() = qMax(customPosition.y(), screenRect.top());
8361 -+ customPosition.rx() = qMin(customPosition.x() + size().width(), screenRect.right()) - size().width();
8362 -+ customPosition.ry() = qMin(customPosition.y() + size().height(), screenRect.bottom()) - size().height();
8363 -+
8364 -+ bool closerToBottom = (customPosition.ry() > (screenRect.height() / 2));
8365 -+ if (!m_lastSize.isNull() && closerToBottom
8366 -+ && (m_lastSize.height() > size().height())) {
8367 -+ customPosition.ry() += m_lastSize.height() - size().height();
8368 -+ }
8369 -+ m_lastSize = size();
8370 -+ }
8371 -+
8372 -+ move(customPosition);
8373 -+ Plasma::WindowEffects::slideWindow(this, Plasma::Desktop);
8374 -+ m_hasCustomPosition = true;
8375 -+ }
8376 -+}
8377 -+
8378 -+void StackDialog::savePosition(const QPoint& pos)
8379 -+{
8380 -+ if (!m_applet || !m_applet->containment()) {
8381 -+ return;
8382 -+ }
8383 -+
8384 -+ QByteArray horizSide, vertSide;
8385 -+ QPoint pixelsToSave;
8386 -+ const QRect realScreenRect = qApp->desktop()->screenGeometry(m_applet->containment()->screen());
8387 -+
8388 -+ int screenRelativeX = pos.x() - realScreenRect.x();
8389 -+ int diffWithRight = realScreenRect.width() - (screenRelativeX + size().width());
8390 -+ if (screenRelativeX < diffWithRight) {
8391 -+ horizSide = "l";
8392 -+ pixelsToSave.rx() = screenRelativeX;
8393 -+ } else {
8394 -+ horizSide = "r";
8395 -+ pixelsToSave.rx() = diffWithRight;
8396 -+ }
8397 -+
8398 -+ int screenRelativeY = pos.y() - realScreenRect.y();
8399 -+ int diffWithBottom = realScreenRect.height() - (screenRelativeY + size().height());
8400 -+ if (screenRelativeY < diffWithBottom) {
8401 -+ vertSide = "t";
8402 -+ pixelsToSave.ry() = screenRelativeY;
8403 -+ } else {
8404 -+ vertSide = "b";
8405 -+ pixelsToSave.ry() = diffWithBottom;
8406 -+ }
8407 -+
8408 -+ kDebug() << "Affinity-v" << vertSide;
8409 -+ kDebug() << "Affinity-h" << horizSide;
8410 -+ kDebug() << "Y: " << pixelsToSave.ry();
8411 -+ kDebug() << "X: " << pixelsToSave.rx();
8412 -+
8413 -+ m_applet->config().writeEntry("customPosition", pixelsToSave);
8414 -+ m_applet->config().writeEntry("customPositionAffinityHoriz", horizSide);
8415 -+ m_applet->config().writeEntry("customPositionAffinityVert", vertSide);
8416 -+}
8417 -+
8418 -+QPoint StackDialog::adjustedSavedPos() const
8419 -+{
8420 -+ if (!m_applet) {
8421 -+ return QPoint(-1, -1);
8422 -+ }
8423 -+
8424 -+ QPoint pos = m_applet->config().readEntry("customPosition", QPoint(-1, -1));
8425 -+
8426 -+ if (pos != QPoint(-1, -1)) {
8427 -+ const QRect realScreenRect = qApp->desktop()->screenGeometry(m_applet->containment()->screen());
8428 -+ QByteArray horizSide = m_applet->config().readEntry("customPositionAffinityHoriz").toLatin1();
8429 -+ QByteArray vertSide = m_applet->config().readEntry("customPositionAffinityVert").toLatin1();
8430 -+
8431 -+ if (horizSide == "l") {
8432 -+ pos.rx() += realScreenRect.x();
8433 -+ } else {
8434 -+ pos.rx() = realScreenRect.x() + (realScreenRect.width() - pos.rx() - size().width());
8435 -+ }
8436 -+
8437 -+ if (vertSide == "t") {
8438 -+ pos.ry() += realScreenRect.y();
8439 -+ } else {
8440 -+ pos.ry() = realScreenRect.y() + (realScreenRect.height() - pos.ry() - size().height());
8441 -+ }
8442 -+ }
8443 -+
8444 -+ return pos;
8445 -+}
8446 -+
8447 -+bool StackDialog::event(QEvent *event)
8448 -+{
8449 -+ bool ret = Dialog::event(event);
8450 -+
8451 -+ if (event->type() == QEvent::ContentsRectChange) {
8452 -+ int left, top, right, bottom;
8453 -+ getContentsMargins(&left, &top, &right, &bottom);
8454 -+
8455 -+ m_drawLeft = (left != 0);
8456 -+ m_drawRight = (right != 0);
8457 -+ update();
8458 -+ }
8459 -+
8460 -+ return ret;
8461 -+}
8462 -+
8463 -+bool StackDialog::eventFilter(QObject *watched, QEvent *event)
8464 -+{
8465 -+ if (m_windowToTile && watched == m_windowToTile &&
8466 -+ event->type() == QEvent::Show && isVisible()) {
8467 -+ adjustWindowToTilePos();
8468 -+ } else if (watched == m_notificationStack && event->type() == QEvent::GraphicsSceneMousePress) {
8469 -+ QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(event);
8470 -+ m_dragPos = me->pos().toPoint();
8471 -+ } else if (watched == m_notificationStack && event->type() == QEvent::GraphicsSceneMouseMove) {
8472 -+ QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(event);
8473 -+ adjustPosition(me->screenPos() - m_dragPos);
8474 -+ } else if (watched == m_notificationStack && event->type() == QEvent::GraphicsSceneMouseRelease) {
8475 -+ QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(event);
8476 -+ adjustPosition(me->screenPos() - m_dragPos);
8477 -+ savePosition(me->screenPos() - m_dragPos);
8478 -+ }
8479 -+
8480 -+ return Plasma::Dialog::eventFilter(watched, event);
8481 -+}
8482 -+
8483 -+#include "stackdialog.moc"
8484 -diff --git a/plasma/generic/applets/notifications/ui/stackdialog.h b/plasma/generic/applets/notifications/ui/stackdialog.h
8485 -new file mode 100644
8486 -index 0000000..4360c4a
8487 ---- /dev/null
8488 -+++ b/plasma/generic/applets/notifications/ui/stackdialog.h
8489 -@@ -0,0 +1,99 @@
8490 -+/***************************************************************************
8491 -+ * stacdialog.h *
8492 -+ * Copyright (C) 2010 Marco Martin <notmart@×××××.com> *
8493 -+ * *
8494 -+ * This program is free software; you can redistribute it and/or modify *
8495 -+ * it under the terms of the GNU General Public License as published by *
8496 -+ * the Free Software Foundation; either version 2 of the License, or *
8497 -+ * (at your option) any later version. *
8498 -+ * *
8499 -+ * This program is distributed in the hope that it will be useful, *
8500 -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
8501 -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
8502 -+ * GNU General Public License for more details. *
8503 -+ * *
8504 -+ * You should have received a copy of the GNU General Public License *
8505 -+ * along with this program; if not, write to the *
8506 -+ * Free Software Foundation, Inc., *
8507 -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
8508 -+ ***************************************************************************/
8509 -+
8510 -+#ifndef STACKDIALOG_H
8511 -+#define STACKDIALOG_H
8512 -+
8513 -+#include <Plasma/Dialog>
8514 -+
8515 -+#include <QPoint>
8516 -+
8517 -+class QPropertyAnimation;
8518 -+class QTimer;
8519 -+
8520 -+namespace Plasma
8521 -+{
8522 -+ class Applet;
8523 -+ class FrameSvg;
8524 -+}
8525 -+
8526 -+class NotificationStack;
8527 -+
8528 -+
8529 -+class StackDialog : public Plasma::Dialog
8530 -+{
8531 -+ Q_OBJECT
8532 -+public:
8533 -+ StackDialog(QWidget *parent = 0, Qt::WindowFlags f = Qt::Window);
8534 -+ ~StackDialog();
8535 -+
8536 -+ void setNotificationStack(NotificationStack *stack);
8537 -+ NotificationStack *notificartionStack() const;
8538 -+
8539 -+ void setApplet(Plasma::Applet *applet);
8540 -+ Plasma::Applet *applet() const;
8541 -+
8542 -+ void setWindowToTile(QWidget *widget);
8543 -+ QWidget *windowToTile() const;
8544 -+
8545 -+ void setAutoHide(const bool autoHide);
8546 -+ bool autoHide() const;
8547 -+
8548 -+public Q_SLOTS:
8549 -+ void perhapsShow();
8550 -+
8551 -+protected:
8552 -+ void adjustWindowToTilePos();
8553 -+
8554 -+ void paintEvent(QPaintEvent *e);
8555 -+ void showEvent(QShowEvent *event);
8556 -+ void hideEvent(QHideEvent *event);
8557 -+ void enterEvent(QEvent *event);
8558 -+ void leaveEvent(QEvent *event);
8559 -+ void resizeEvent(QResizeEvent *event);
8560 -+ void moveEvent(QMoveEvent *event);
8561 -+ bool event(QEvent *event);
8562 -+ bool eventFilter(QObject *watched, QEvent *event);
8563 -+ void adjustPosition(const QPoint &pos = QPoint(-1, -1));
8564 -+ void savePosition(const QPoint &pos);
8565 -+ QPoint adjustedSavedPos() const;
8566 -+
8567 -+private Q_SLOTS:
8568 -+ void hideRequested();
8569 -+
8570 -+private:
8571 -+ Plasma::Applet *m_applet;
8572 -+ QWidget *m_windowToTile;
8573 -+ QPropertyAnimation *m_windowToTileAnimation;
8574 -+ QPoint m_dragPos;
8575 -+ QSize m_lastSize;
8576 -+
8577 -+ Plasma::FrameSvg *m_background;
8578 -+ NotificationStack *m_notificationStack;
8579 -+ QTimer *m_showTimer;
8580 -+ QTimer *m_hideTimer;
8581 -+ QGraphicsView *m_view;
8582 -+ bool m_drawLeft;
8583 -+ bool m_drawRight;
8584 -+ bool m_autoHide;
8585 -+ bool m_hasCustomPosition;
8586 -+};
8587 -+
8588 -+#endif
8589
8590 diff --git a/kde-base/plasma-workspace/files/plasma-workspace-4.10.1-noplasmalock.patch b/kde-base/plasma-workspace/files/plasma-workspace-4.10.1-noplasmalock.patch
8591 deleted file mode 100644
8592 index 2380d20..0000000
8593 --- a/kde-base/plasma-workspace/files/plasma-workspace-4.10.1-noplasmalock.patch
8594 +++ /dev/null
8595 @@ -1,11 +0,0 @@
8596 -diff --git a/plasma/screensaver/CMakeLists.txt b/plasma/screensaver/CMakeLists.txt
8597 -index 514c856..9dcb5f4 100644
8598 ---- a/plasma/screensaver/CMakeLists.txt
8599 -+++ b/plasma/screensaver/CMakeLists.txt
8600 -@@ -1,6 +1,3 @@
8601 - add_subdirectory(containments)
8602 --if(NOT WIN32)
8603 --add_subdirectory(shell)
8604 --endif(NOT WIN32)
8605 -
8606 -
8607
8608 diff --git a/kde-base/plasma-workspace/metadata.xml b/kde-base/plasma-workspace/metadata.xml
8609 deleted file mode 100644
8610 index 3b3fc4f..0000000
8611 --- a/kde-base/plasma-workspace/metadata.xml
8612 +++ /dev/null
8613 @@ -1,9 +0,0 @@
8614 -<?xml version="1.0" encoding="UTF-8"?>
8615 -<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
8616 -<pkgmetadata>
8617 -<herd>kde</herd>
8618 -<use>
8619 - <flag name="json">Enable JSON support via <pkg>dev-libs/qjson</pkg></flag>
8620 - <flag name="qalculate">Enable Qalculate runner using <pkg>sci-libs/libqalculate</pkg></flag>
8621 -</use>
8622 -</pkgmetadata>
8623
8624 diff --git a/kde-base/plasma-workspace/plasma-workspace-4.11.2-r2.ebuild b/kde-base/plasma-workspace/plasma-workspace-4.11.2-r2.ebuild
8625 deleted file mode 100644
8626 index 4ed968e..0000000
8627 --- a/kde-base/plasma-workspace/plasma-workspace-4.11.2-r2.ebuild
8628 +++ /dev/null
8629 @@ -1,125 +0,0 @@
8630 -# Copyright 1999-2013 Gentoo Foundation
8631 -# Distributed under the terms of the GNU General Public License v2
8632 -# $Header: $
8633 -
8634 -EAPI=5
8635 -
8636 -DECLARATIVE_REQUIRED="always"
8637 -KDE_HANDBOOK="optional"
8638 -KMNAME="kde-workspace"
8639 -KMMODULE="plasma"
8640 -PYTHON_COMPAT=( python2_{6,7} )
8641 -OPENGL_REQUIRED="always"
8642 -inherit python-single-r1 kde4-meta
8643 -
8644 -DESCRIPTION="Plasma: KDE desktop framework"
8645 -KEYWORDS="~amd64 ~arm ~ppc ~ppc64 ~x86 ~amd64-linux ~x86-linux"
8646 -IUSE="debug gps json python qalculate semantic-desktop"
8647 -
8648 -REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
8649 -
8650 -COMMONDEPEND="
8651 - dev-libs/libdbusmenu-qt
8652 - >=dev-qt/qtcore-4.8.4-r3:4
8653 - !kde-misc/ktouchpadenabler
8654 - $(add_kdebase_dep kactivities)
8655 - $(add_kdebase_dep kdelibs 'semantic-desktop?')
8656 - $(add_kdebase_dep kdepimlibs)
8657 - $(add_kdebase_dep kephal)
8658 - $(add_kdebase_dep ksysguard)
8659 - $(add_kdebase_dep libkworkspace)
8660 - $(add_kdebase_dep libplasmaclock)
8661 - $(add_kdebase_dep libplasmagenericshell)
8662 - $(add_kdebase_dep libtaskmanager)
8663 - x11-libs/libX11
8664 - x11-libs/libXcomposite
8665 - x11-libs/libXdamage
8666 - x11-libs/libXext
8667 - x11-libs/libXfixes
8668 - x11-libs/libXi
8669 - x11-libs/libXrender
8670 - gps? ( >=sci-geosciences/gpsd-2.37 )
8671 - json? ( dev-libs/qjson )
8672 - python? (
8673 - ${PYTHON_DEPS}
8674 - >=dev-python/PyQt4-4.4.0[X,${PYTHON_USEDEP}]
8675 - $(add_kdebase_dep pykde4 "${PYTHON_USEDEP}")
8676 - )
8677 - qalculate? ( sci-libs/libqalculate )
8678 - semantic-desktop? (
8679 - dev-libs/soprano
8680 - $(add_kdebase_dep nepomuk-core)
8681 - )
8682 -"
8683 -DEPEND="${COMMONDEPEND}
8684 - dev-libs/boost
8685 - x11-proto/compositeproto
8686 - x11-proto/damageproto
8687 - x11-proto/fixesproto
8688 - x11-proto/renderproto
8689 -"
8690 -RDEPEND="${COMMONDEPEND}
8691 - $(add_kdebase_dep plasma-runtime)
8692 -"
8693 -
8694 -KMEXTRA="
8695 - appmenu/
8696 - ktouchpadenabler/
8697 - statusnotifierwatcher/
8698 -"
8699 -KMEXTRACTONLY="
8700 - kcheckpass/
8701 - krunner/dbus/org.freedesktop.ScreenSaver.xml
8702 - krunner/dbus/org.kde.krunner.App.xml
8703 - ksmserver/org.kde.KSMServerInterface.xml
8704 - ksmserver/screenlocker/
8705 - libs/kephal/
8706 - libs/kworkspace/
8707 - libs/taskmanager/
8708 - libs/plasmagenericshell/
8709 - libs/ksysguard/
8710 - libs/kdm/kgreeterplugin.h
8711 - ksysguard/
8712 -"
8713 -
8714 -KMLOADLIBS="libkworkspace libplasmaclock libplasmagenericshell libtaskmanager"
8715 -
8716 -PATCHES=( "${FILESDIR}/${PN}-4.10.1-noplasmalock.patch" "${FILESDIR}/oldnotify.patch" )
8717 -
8718 -pkg_setup() {
8719 - if use python ; then
8720 - python-single-r1_pkg_setup
8721 - fi
8722 - kde4-meta_pkg_setup
8723 -}
8724 -
8725 -src_unpack() {
8726 - if use handbook; then
8727 - KMEXTRA+=" doc/plasma-desktop"
8728 - fi
8729 -
8730 - kde4-meta_src_unpack
8731 -}
8732 -
8733 -src_configure() {
8734 - mycmakeargs=(
8735 - $(cmake-utils_use_with gps libgps)
8736 - $(cmake-utils_use_with json QJSON)
8737 - $(cmake-utils_use_with python PythonLibrary)
8738 - $(cmake-utils_use_with qalculate)
8739 - $(cmake-utils_use_with semantic-desktop Akonadi)
8740 - $(cmake-utils_use_with semantic-desktop NepomukCore)
8741 - $(cmake-utils_use_with semantic-desktop Soprano)
8742 - -DWITH_Xmms=OFF
8743 - )
8744 -
8745 - kde4-meta_src_configure
8746 -}
8747 -
8748 -src_install() {
8749 - kde4-meta_src_install
8750 -
8751 - if use python; then
8752 - python_optimize "${ED}"
8753 - fi
8754 -}