@@ -16,11 +16,13 @@
1616
1717import QtQuick 2.0
1818import QtMultimedia 5.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.1
2020import Unity.Notifications 1.0
2121import QMenuModel 0.1
2222import Utils 0.1
2323
24+import Ubuntu.Components.ListItems 0.1 as ListItem
25+
2426Item {
2527 id: notification
2628
@@ -34,11 +36,18 @@ Item {
3436 property var hints
3537 property var notification
3638 property color color
37− property bool fullscreen
39+ property bool fullscreen: false
3840 property int maxHeight
3941 property int margins
42+ property Gradient greenGradient : Gradient {
43+ GradientStop { position: 0.0; color: "#3fb24f" }
44+ GradientStop { position: 1.0; color: "#3fb24f" }
45+ }
46+ property Gradient darkgreyGradient: Gradient {
47+ GradientStop { position: 0.0; color: "#4d4745" }
48+ GradientStop { position: 1.0; color: "#4d4745" }
49+ }
4050
41− fullscreen: false
4251 objectName: "background"
4352 implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : contentColumn.height + contentColumn.spacing * 2) : 0
4453
@@ -70,7 +79,7 @@ Item {
7079 Audio {
7180 id: sound
7281 objectName: "sound"
73− source: hints["suppress-sound"] != "" ? hints["sound-file"] : undefined
82+ source: hints["suppress-sound"] != "true" && hints["sound-file"] != undefined ? hints["sound-file"] : ""
7483 }
7584
7685 onOpacityChanged: {
@@ -149,9 +158,17 @@ Item {
149158 UnityMenuModel {
150159 id: unityMenuModel
151160
161+ property string lastNameOwner: ""
162+
152163 busName: paths.busName
153164 actions: paths.actions
154165 menuObjectPath: paths.menuObjectPath
166+ onNameOwnerChanged: {
167+ if (lastNameOwner != "" && nameOwner == "" && notification.notification != undefined) {
168+ notification.notification.close()
169+ }
170+ lastNameOwner = nameOwner
171+ }
155172 }
156173
157174 Behavior on implicitHeight {
@@ -262,14 +279,18 @@ Item {
262279 }
263280
264281 Column {
282+ id: dialogColumn
265283 objectName: "dialogListView"
266284 spacing: units.gu(2)
267285
268286 visible: count > 0
269287
270− anchors.left: parent.left; anchors.right: parent.right
271− anchors.top: fullscreen ? parent.top : undefined
272− anchors.bottom: fullscreen ? parent.bottom : undefined
288+ anchors {
289+ left: parent.left
290+ right: parent.right
291+ top: fullscreen ? parent.top : undefined
292+ bottom: fullscreen ? parent.bottom : undefined
293+ }
273294
274295 Repeater {
275296 model: unityMenuModel
@@ -277,7 +298,10 @@ Item {
277298 NotificationMenuItemFactory {
278299 id: menuItemFactory
279300
280− anchors.left: parent.left; anchors.right: parent.right
301+ anchors {
302+ left: dialogColumn.left
303+ right: dialogColumn.right
304+ }
281305
282306 menuModel: unityMenuModel
283307 menuData: model
@@ -291,7 +315,7 @@ Item {
291315 }
292316 }
293317
294− Item {
318+ Row {
295319 id: buttonRow
296320
297321 objectName: "buttonRow"
@@ -300,70 +324,8 @@ Item {
300324 right: parent.right
301325 }
302326 visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
303− height: units.gu(5)
304−
305− property real buttonWidth: (width - contentColumn.spacing) / 2
306− property bool expanded
307−
308− Button {
309− id: leftButton
310−
311− objectName: "button1"
312− width: parent.expanded ? parent.width : parent.buttonWidth
313− anchors {
314− top: parent.top
315− bottom: parent.bottom
316− }
317− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
318− gradient: UbuntuColors.greyGradient
319− onClicked: {
320− if (actionRepeater.count > 2) {
321− buttonRow.expanded = !buttonRow.expanded
322− } else {
323− notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
324− }
325− }
326−
327− Behavior on width {
328− UbuntuNumberAnimation {
329− duration: UbuntuAnimation.SnapDuration
330− }
331− }
332− }
333−
334− Button {
335− id: rightButton
336−
337− objectName: "button0"
338− anchors {
339− left: leftButton.right
340− leftMargin: contentColumn.spacing
341− right: parent.right
342− }
343− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
344− anchors {
345− top: parent.top
346− bottom: parent.bottom
347− }
348− gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
349− visible: width > 0
350− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
351− }
352− }
353−
354− Column {
355− objectName: "buttonColumn"
356− spacing: contentColumn.spacing
357− anchors {
358− left: parent.left
359− right: parent.right
360− }
361−
362− // calculate initial position before Column takes over
363− y: buttonRow.y + buttonRow.height + contentColumn.spacing
364−
365− visible: notification.type == Notification.SnapDecision && buttonRow.expanded
366− height: buttonRow.expanded ? implicitHeight : 0
327+ spacing: units.gu(1)
328+ layoutDirection: Qt.RightToLeft
367329
368330 Repeater {
369331 id: actionRepeater
@@ -375,28 +337,105 @@ Item {
375337 property string actionId: id
376338 property string actionLabel: label
377339
378− anchors {
379− left: parent.left
380− right: parent.right
381− }
382−
383340 Component {
384341 id: actionButton
385342
386343 Button {
387344 objectName: "button" + index
388− anchors {
389− left: parent.left
390− right: parent.right
391− }
392−
345+ width: buttonRow.width / 2 - spacing
393346 text: loader.actionLabel
394− height: units.gu(5)
395− gradient: UbuntuColors.greyGradient
347+ gradient: notification.hints["x-canonical-private-button-tint"] == "true" && index == 0 ? greenGradient : darkgreyGradient
396348 onClicked: notification.notification.invokeAction(loader.actionId)
397349 }
398350 }
399− sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
351+ sourceComponent: (index == 0 || index == 1) ? actionButton : undefined
352+ }
353+ }
354+ }
355+
356+ ComboButton {
357+ id: comboButton
358+
359+ objectName: "button2"
360+ width: parent.width
361+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 3
362+ gradient: darkgreyGradient
363+ onClicked: notification.notification.invokeAction(comboRepeater.itemAt(2).actionId)
364+ expanded: false
365+ expandedHeight: (comboRepeater.count - 2) * units.gu(4) + units.gu(.5)
366+ comboList: Flickable {
367+ // this has to be wrapped inside a flickable
368+ // to work around a feature/bug? of the
369+ // ComboButton SDK-element, making a regular
370+ // unwrapped Column item flickable
371+ // see LP: #1332590
372+ interactive: false
373+ Column {
374+ Repeater {
375+ id: comboRepeater
376+
377+ onVisibleChanged: {
378+ comboButton.text = comboRepeater.itemAt(2).actionLabel
379+ }
380+
381+ model: notification.actions
382+ delegate: Loader {
383+ id: comboLoader
384+
385+ asynchronous: true
386+ visible: status == Loader.Ready
387+ property string actionId: id
388+ property string actionLabel: label
389+ readonly property var splitLabel: actionLabel.match(/(^([-a-z0-9]+):)?(.*)$/)
390+ Component {
391+ id: comboEntry
392+
393+ MouseArea {
394+ id: comboInputArea
395+
396+ objectName: "button" + index
397+ width: comboButton.width
398+ height: comboIcon.height + units.gu(2)
399+
400+ onClicked: {
401+ notification.notification.invokeAction(actionId)
402+ }
403+
404+ ListItem.ThinDivider {
405+ visible: index > 3
406+ }
407+
408+ Icon {
409+ id: comboIcon
410+
411+ anchors {
412+ left: parent.left
413+ leftMargin: units.gu(.5)
414+ verticalCenter: parent.verticalCenter
415+ }
416+ width: units.gu(2)
417+ height: units.gu(2)
418+ color: "white"
419+ name: splitLabel[2]
420+ }
421+
422+ Label {
423+ id: comboLabel
424+
425+ anchors {
426+ left: comboIcon.right
427+ leftMargin: units.gu(1)
428+ verticalCenter: comboIcon.verticalCenter
429+ }
430+ fontSize: "small"
431+ color: "white"
432+ text: splitLabel[3]
433+ }
434+ }
435+ }
436+ sourceComponent: (index > 2) ? comboEntry : undefined
437+ }
438+ }
400439 }
401440 }
402441 }