@@ -19,7 +19,8 @@
1919
2020import QtQuick 2.0
2121import Ubuntu.Settings.Menus 0.1 as Menus
22−import QMenuModel 0.1 as QMenuModel
22+import Ubuntu.Settings.Components 0.1 as SettingsComponents
23+import QMenuModel 0.1
2324import Utils 0.1 as Utils
2425import Ubuntu.Components.ListItems 0.1 as ListItems
2526import Ubuntu.Components 0.1
@@ -27,20 +28,23 @@ import Ubuntu.Components 0.1
2728Item {
2829 id: menuFactory
2930
31+ property var rootModel: null
3032 property var menuModel: null
3133
3234 property var _map: {
3335 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
3436 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
3537
36− "com.canonical.indicator.button" : buttonMenu,
37− "com.canonical.indicator.div" : separatorMenu,
38− "com.canonical.indicator.section" : sectionMenu,
39− "com.canonical.indicator.progress" : progressMenu,
40− "com.canonical.indicator.slider" : sliderMenu,
41− "com.canonical.indicator.switch" : switchMenu,
42− "com.canonical.indicator.alarm" : alarmMenu,
43− "com.canonical.indicator.appointment" : appointmentMenu,
38+ "com.canonical.indicator.button" : buttonMenu,
39+ "com.canonical.indicator.div" : separatorMenu,
40+ "com.canonical.indicator.section" : sectionMenu,
41+ "com.canonical.indicator.progress" : progressMenu,
42+ "com.canonical.indicator.slider" : sliderMenu,
43+ "com.canonical.indicator.switch" : switchMenu,
44+ "com.canonical.indicator.alarm" : alarmMenu,
45+ "com.canonical.indicator.appointment" : appointmentMenu,
46+ "com.canonical.indicator.transfer" : transferMenu,
47+ "com.canonical.indicator.button-section" : buttonSectionMenu,
4448
4549 "com.canonical.indicator.messages.messageitem" : messageItem,
4650 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
@@ -64,6 +68,7 @@ Item {
6468
6569 Component {
6670 id: separatorMenu;
71+
6772 Menus.SeparatorMenu {
6873 objectName: "separatorMenu"
6974 }
@@ -71,6 +76,7 @@ Item {
7176
7277 Component {
7378 id: sliderMenu;
79+
7480 Menus.SliderMenu {
7581 objectName: "sliderMenu"
7682 property QtObject menuData: null
@@ -122,6 +128,7 @@ Item {
122128
123129 Component {
124130 id: buttonMenu;
131+
125132 Menus.ButtonMenu {
126133 objectName: "buttonMenu"
127134 property QtObject menuData: null
@@ -139,6 +146,7 @@ Item {
139146 }
140147 Component {
141148 id: sectionMenu;
149+
142150 Menus.SectionMenu {
143151 objectName: "sectionMenu"
144152 property QtObject menuData: null
@@ -151,6 +159,7 @@ Item {
151159
152160 Component {
153161 id: progressMenu;
162+
154163 Menus.ProgressValueMenu {
155164 objectName: "progressMenu"
156165 property QtObject menuData: null
@@ -165,6 +174,7 @@ Item {
165174
166175 Component {
167176 id: standardMenu;
177+
168178 Menus.StandardMenu {
169179 objectName: "standardMenu"
170180 property QtObject menuData: null
@@ -183,6 +193,7 @@ Item {
183193
184194 Component {
185195 id: checkableMenu;
196+
186197 Menus.CheckableMenu {
187198 objectName: "checkableMenu"
188199 property QtObject menuData: null
@@ -202,6 +213,7 @@ Item {
202213
203214 Component {
204215 id: switchMenu;
216+
205217 Menus.SwitchMenu {
206218 objectName: "switchMenu"
207219 property QtObject menuData: null
@@ -221,6 +233,7 @@ Item {
221233
222234 Component {
223235 id: alarmMenu;
236+
224237 Menus.EventMenu {
225238 objectName: "alarmMenu"
226239 property QtObject menuData: null
@@ -258,6 +271,7 @@ Item {
258271
259272 Component {
260273 id: appointmentMenu;
274+
261275 Menus.EventMenu {
262276 objectName: "appointmentMenu"
263277 property QtObject menuData: null
@@ -297,6 +311,7 @@ Item {
297311
298312 Component {
299313 id: wifiSection;
314+
300315 Menus.SectionMenu {
301316 objectName: "wifiSection"
302317 property QtObject menuData: null
@@ -323,6 +338,7 @@ Item {
323338
324339 Component {
325340 id: accessPoint;
341+
326342 Menus.AccessPointMenu {
327343 objectName: "accessPoint"
328344 property QtObject menuData: null
@@ -330,7 +346,7 @@ Item {
330346 property int menuIndex: -1
331347 property var extendedData: menuData && menuData.ext || undefined
332348
333− property var strengthAction: QMenuModel.UnityMenuAction {
349+ property var strengthAction: UnityMenuAction {
334350 model: menuModel
335351 index: menuIndex
336352 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
@@ -365,6 +381,7 @@ Item {
365381
366382 Component {
367383 id: messageItem
384+
368385 MessageMenuItemFactory {
369386 objectName: "messageItem"
370387 menuModel: menuFactory.menuModel
@@ -373,6 +390,7 @@ Item {
373390
374391 Component {
375392 id: groupedMessage
393+
376394 Menus.GroupedMessageMenu {
377395 objectName: "groupedMessage"
378396 property QtObject menuData: null
@@ -409,6 +427,7 @@ Item {
409427
410428 Component {
411429 id: mediaPayerMenu;
430+
412431 Menus.MediaPlayerMenu {
413432 objectName: "mediaPayerMenu"
414433 property QtObject menuData: null
@@ -435,6 +454,7 @@ Item {
435454
436455 Component {
437456 id: playbackItemMenu;
457+
438458 Menus.PlaybackItemMenu {
439459 objectName: "playbackItemMenu"
440460 property QtObject menuData: null
@@ -442,17 +462,17 @@ Item {
442462 property int menuIndex: -1
443463 property var extendedData: menuData && menuData.ext || undefined
444464
445− property var playAction: QMenuModel.UnityMenuAction {
465+ property var playAction: UnityMenuAction {
446466 model: menuModel
447467 index: menuIndex
448468 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
449469 }
450− property var nextAction: QMenuModel.UnityMenuAction {
470+ property var nextAction: UnityMenuAction {
451471 model: menuModel
452472 index: menuIndex
453473 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
454474 }
455− property var previousAction: QMenuModel.UnityMenuAction {
475+ property var previousAction: UnityMenuAction {
456476 model: menuModel
457477 index: menuIndex
458478 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
@@ -489,6 +509,150 @@ Item {
489509 }
490510 }
491511
512+ Component {
513+ id: transferMenu
514+
515+ Menus.TransferMenu {
516+ objectName: "transferMenu"
517+ id: transfer
518+ property QtObject menuData: null
519+ property var menuModel: menuFactory.menuModel
520+ property int menuIndex: -1
521+ property var extendedData: menuData && menuData.ext || undefined
522+ property var uid: getExtendedProperty(extendedData, "xCanonicalUid", undefined)
523+
524+ text: menuData && menuData.label || ""
525+ iconSource: menuData && menuData.icon || ""
526+ maximum: 1.0
527+ enabled: menuData && menuData.sensitive || false
528+ removable: true
529+ confirmRemoval: true
530+
531+ QDBusActionGroup {
532+ id: actionGroup
533+ busType: 1
534+ busName: rootModel.busName
535+ objectPath: rootModel.actions["indicator"]
536+
537+ property var activateAction: action("activate-transfer")
538+ property var cancelAction: action("cancel-transfer")
539+ property var transferStateAction: uid !== undefined ? action("transfer-state."+uid) : null
540+
541+ Component.onCompleted: actionGroup.start()
542+ }
543+
544+ property var transferState: {
545+ if (actionGroup.transferStateAction === null) return undefined;
546+ return actionGroup.transferStateAction.valid ? actionGroup.transferStateAction.state : undefined
547+ }
548+
549+ property var runningState : transferState !== undefined ? transferState["state"] : undefined
550+ property var secondsLeft : transferState !== undefined ? transferState["seconds-left"] : undefined
551+
552+ active: runningState !== undefined && runningState !== Menus.TransferState.Finished
553+ progress: transferState !== undefined ? transferState["percent"] : 0.0
554+
555+ // TODO - Should be in the SDK
556+ property var timeRemaining: {
557+ if (secondsLeft === undefined) return undefined;
558+
559+ var remaining = "";
560+ var hours = Math.floor(secondsLeft / (60 * 60));
561+ var minutes = Math.floor(secondsLeft / 60) % 60;
562+ var seconds = secondsLeft % 60;
563+ if (hours > 0) {
564+ remaining += hours + (hours == 1 ? " hour" : " hours");
565+ }
566+ if (minutes > 0) {
567+ if (remaining != "") remaining += ", ";
568+ remaining += minutes + (minutes == 1 ? " minute" : " minutes");
569+ }
570+ // don't include seconds if hours > 0
571+ if (hours == 0 && minutes < 5 && seconds > 0) {
572+ if (remaining != "") remaining += ", ";
573+ remaining += seconds + (seconds == 1 ? " second" : " seconds");
574+ }
575+ if (remaining == "")
576+ remaining = "0 seconds";
577+ return remaining + " remaining";
578+ }
579+
580+ stateText: {
581+ switch (runningState) {
582+ case Menus.TransferState.Queued:
583+ return i18n.tr("In queue…");
584+ case Menus.TransferState.Hashing:
585+ case Menus.TransferState.Processing:
586+ case Menus.TransferState.Running:
587+ return timeRemaining === undefined ? i18n.tr("Downloading") : timeRemaining;
588+ case Menus.TransferState.Paused:
589+ return i18n.tr("Paused, tap to resume");
590+ case Menus.TransferState.Canceled:
591+ return i18n.tr("Canceled");
592+ case Menus.TransferState.Finished:
593+ return i18n.tr("Finished");
594+ case Menus.TransferState.Error:
595+ return i18n.tr("Failed, tap to retry");
596+ }
597+ return "";
598+ }
599+
600+ onMenuModelChanged: {
601+ loadAttributes();
602+ }
603+ onMenuIndexChanged: {
604+ loadAttributes();
605+ }
606+ onTriggered: {
607+ actionGroup.activateAction.activate(uid);
608+ }
609+ onItemRemoved: {
610+ actionGroup.cancelAction.activate(uid);
611+ }
612+
613+ function loadAttributes() {
614+ if (!menuModel || menuIndex == -1) return;
615+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-uid': 'string'});
616+ }
617+ }
618+ }
619+
620+ Component {
621+ id: buttonSectionMenu;
622+
623+ ListItems.Standard {
624+ objectName: "buttonSectionMenu"
625+ property QtObject menuData: null
626+ property var menuModel: menuFactory.menuModel
627+ property int menuIndex: -1
628+ property var extendedData: menuData && menuData.ext || undefined
629+
630+ iconSource: menuData && menuData.icon || ""
631+ enabled: menuData && menuData.sensitive || false
632+ text: menuData && menuData.label || ""
633+ showDivider: false
634+
635+ onMenuModelChanged: {
636+ loadAttributes();
637+ }
638+ onMenuIndexChanged: {
639+ loadAttributes();
640+ }
641+ function loadAttributes() {
642+ if (!menuModel || menuIndex == -1) return;
643+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-extra-label': 'string'});
644+ }
645+
646+ control: Button {
647+ text: getExtendedProperty(extendedData, "xCanonicalExtraLabel", "")
648+
649+ onClicked: {
650+ menuModel.activate(menuIndex);
651+ }
652+ }
653+ }
654+ }
655+
492656 function load(modelData) {
493657 if (modelData.type !== undefined) {
494658 var component = _map[modelData.type];