on xenial help sign in
merge trunk
8bcb154Michał Sawicz
Components/FilterGrid.qml+31−61
@@ -35,12 +35,18 @@ Item {
35
35
36 /* Whether, when collapsed, a button should be displayed enabling the user to expand
36 /* Whether, when collapsed, a button should be displayed enabling the user to expand
37 the grid to its full size. */
37 the grid to its full size. */
38− property bool expandable: true
38+ readonly property bool expandable: model.count > collapsedRowCount * iconTileGrid.columns
39
39
40 property var model: null
40 property var model: null
41
41
42 /* Maximum number of rows to be show when filter=true. */
42 /* Maximum number of rows to be show when filter=true. */
43 property int collapsedRowCount: 2
43 property int collapsedRowCount: 2
44+ readonly property int collapsedHeight: {
45+ return iconTileGrid.contentHeightForRows(Math.min(collapsedRowCount, Math.ceil(model.count / columns)))
46+ }
47+ readonly property int uncollapsedHeight: {
48+ return iconTileGrid.contentHeightForRows(Math.ceil(model.count / columns))
49+ }
44
50
45 property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
51 property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
46 property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
52 property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
@@ -55,7 +61,29 @@ Item {
55 readonly property alias moving: iconTileGrid.moving
61 readonly property alias moving: iconTileGrid.moving
56 readonly property alias pressDelay: iconTileGrid.pressDelay
62 readonly property alias pressDelay: iconTileGrid.pressDelay
57
63
58− height: childrenRect.height
64+ height: !filterAnimation.running ? childrenRect.height : height
65+ clip: filterAnimation.running
66+
67+ NumberAnimation {
68+ property bool filterEndValue
69+ id: filterAnimation
70+ target: root
71+ property: "height"
72+ to: filterEndValue ? root.collapsedHeight : root.uncollapsedHeight
73+ // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
74+ // otherwise since both animations can run at the same time you'll get
75+ // some visual weirdness.
76+ duration: 200
77+ easing.type: Easing.InOutQuad
78+ onStopped: {
79+ root.filter = filterEndValue;
80+ }
81+ }
82+
83+ function startFilterAnimation(filter) {
84+ filterAnimation.filterEndValue = filter
85+ filterAnimation.start();
86+ }
59
87
60 ResponsiveGridView {
88 ResponsiveGridView {
61 id: iconTileGrid
89 id: iconTileGrid
@@ -72,66 +100,8 @@ Item {
72
100
73 model: LimitProxyModel {
101 model: LimitProxyModel {
74 model: root.model
102 model: root.model
75− limit: (filter) ? collapsedRowCount * iconTileGrid.columns : -1
103+ limit: (filter && !filterAnimation.running) ? collapsedRowCount * iconTileGrid.columns : -1
76 }
104 }
77
105
78 }
106 }
79−
80− Item {
81− anchors {
82− left: parent.left
83− right: parent.right
84− top: iconTileGrid.bottom
85− }
86− visible: (expandable && filter && model.count > collapsedRowCount * iconTileGrid.columns)
87− height: (visible) ? childrenRect.height + units.gu(2) : 0
88−
89− AbstractButton {
90− id: button
91− objectName: "filterToggleButton"
92−
93− anchors {
94− top: parent.top
95− horizontalCenter: parent.horizontalCenter
96− }
97− width: units.gu(22)
98− height: units.gu(4)
99−
100− UbuntuShape {
101− anchors.fill: parent
102− color: "#33ffffff" // FIXME no palette
103− radius: "small"
104− }
105−
106− UbuntuShape {
107− id: borderPressed
108−
109− anchors.fill: parent
110− radius: "small"
111− borderSource: "radius_pressed.sci"
112− opacity: button.pressed ? 1.0 : 0.0
113− Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
114− }
115−
116− Label {
117− anchors {
118− verticalCenter: parent.verticalCenter
119− left: parent.left
120− right: parent.right
121− leftMargin: units.gu(1)
122− rightMargin: units.gu(1)
123− }
124− text: (filter) ? "+ View all (" + model.count + ")" : "- Show fewer"
125− fontSize: "small"
126− color: Theme.palette.selected.backgroundText
127− opacity: 0.6
128− style: Text.Raised
129− styleColor: "black"
130− elide: Text.ElideMiddle
131− horizontalAlignment: Text.AlignHCenter
132− }
133−
134− onClicked: filter = !filter
135− }
136− }
137}
107}
Components/ListItems/Header.qml+19−2
@@ -24,6 +24,9 @@ Item {
24 \qmlproperty string text
24 \qmlproperty string text
25 */
25 */
26 property alias text: label.text
26 property alias text: label.text
27+ property alias image: image.source
28+
29+ signal clicked(variant mouse)
27
30
28 height: units.gu(4.5)
31 height: units.gu(4.5)
29
32
@@ -31,6 +34,7 @@ Item {
31 anchors {
34 anchors {
32 left: parent.left
35 left: parent.left
33 right: parent.right
36 right: parent.right
37+ rightMargin: units.gu(0.5)
34 top: parent.top
38 top: parent.top
35 bottom: bottomBorder.top
39 bottom: bottomBorder.top
36 }
40 }
@@ -40,8 +44,6 @@ Item {
40 anchors {
44 anchors {
41 left: parent.left
45 left: parent.left
42 leftMargin: units.gu(2)
46 leftMargin: units.gu(2)
43− right: parent.right
44− rightMargin: units.gu(0.5)
45 verticalCenter: parent.verticalCenter
47 verticalCenter: parent.verticalCenter
46 }
48 }
47
49
@@ -53,6 +55,16 @@ Item {
53 textFormat: Text.PlainText
55 textFormat: Text.PlainText
54 style: Text.Raised
56 style: Text.Raised
55 styleColor: "black"
57 styleColor: "black"
58+ width: parent.width - image.width - image.leftMargin - anchors.leftMargin
59+ }
60+
61+ Image {
62+ id: image
63+ readonly property double leftMargin: units.gu(1)
64+ x: label.x + label.contentWidth + leftMargin
65+ anchors {
66+ verticalCenter: parent.verticalCenter
67+ }
56 }
68 }
57 }
69 }
58
70
@@ -64,4 +76,9 @@ Item {
64 bottom: parent.bottom
76 bottom: parent.bottom
65 }
77 }
66 }
78 }
79+
80+ MouseArea {
81+ anchors.fill: parent
82+ onClicked: parent.clicked(mouse)
83+ }
67}
84}
Components/ResponsiveGridView.qml+7−1
@@ -32,12 +32,18 @@ Item {
32 property alias delegate: gridView.delegate
32 property alias delegate: gridView.delegate
33 readonly property int cellWidth: gridView.cellWidth
33 readonly property int cellWidth: gridView.cellWidth
34 readonly property int cellHeight: gridView.cellHeight
34 readonly property int cellHeight: gridView.cellHeight
35− readonly property int totalContentHeight: Math.ceil(gridView.model.count / columns) * cellHeight + verticalSpacing
35+ readonly property int totalContentHeight: {
36+ return contentHeightForRows(Math.ceil(gridView.model.count / columns))
37+ }
36 property alias interactive: gridView.interactive
38 property alias interactive: gridView.interactive
37 readonly property alias flicking: gridView.flicking
39 readonly property alias flicking: gridView.flicking
38 readonly property alias moving: gridView.moving
40 readonly property alias moving: gridView.moving
39 readonly property alias pressDelay: gridView.pressDelay
41 readonly property alias pressDelay: gridView.pressDelay
40
42
43+ function contentHeightForRows(rows) {
44+ return rows * cellHeight + verticalSpacing
45+ }
46+
41 GridView {
47 GridView {
42 id: gridView
48 id: gridView
43 objectName: "responsiveGridViewGrid"
49 objectName: "responsiveGridViewGrid"
Components/Tile.qml−6
@@ -84,10 +84,4 @@ AbstractButton {
84 horizontalAlignment: Text.AlignHCenter
84 horizontalAlignment: Text.AlignHCenter
85 }
85 }
86 }
86 }
87−
88− GridView.onRemove: SequentialAnimation {
89− PropertyAction { target: root; property: "GridView.delayRemove"; value: true }
90− NumberAnimation { target: root; property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.InOutQuad }
91− PropertyAction { target: root; property: "GridView.delayRemove"; value: false }
92− }
93}
87}
Dash/Apps/AppInfo.qmlnew file+88
@@ -0,0 +1,88 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+
21+Row {
22+ id: root
23+ property alias icon: image.source
24+ property alias appName: appNameLabel.text
25+ property alias rating: ratingStars.rating
26+ property int rated: 0
27+ property int reviews: 0
28+
29+ spacing: units.gu(2)
30+
31+ UbuntuShape {
32+ id: imageShape
33+ width: units.gu(6)
34+ height: units.gu(6)
35+ image: Image {
36+ id: image
37+ sourceSize { width: imageShape.width; height: imageShape.height }
38+ asynchronous: true
39+ fillMode: Image.PreserveAspectFit
40+ }
41+ }
42+
43+ Column {
44+ spacing: units.gu(1)
45+
46+ Label {
47+ id: appNameLabel
48+ fontSize: "large"
49+ color: "white"
50+ style: Text.Raised
51+ styleColor: "black"
52+ opacity: .9
53+ }
54+
55+ Row {
56+ spacing: units.gu(1)
57+
58+ RatingStars {
59+ id: ratingStars
60+ maximumRating: 10
61+ }
62+
63+ Label {
64+ id: ratedLabel
65+ objectName: "ratedLabel"
66+ fontSize: "medium"
67+ color: "white"
68+ style: Text.Raised
69+ styleColor: "black"
70+ opacity: .6
71+ //TRANSLATORS: Number of persons who rated this app
72+ text: i18n.tr("(%1)").arg(root.rated)
73+ }
74+
75+ Label {
76+ id: reviewsLabel
77+ objectName: "reviewsLabel"
78+ fontSize: "medium"
79+ color: "white"
80+ style: Text.Raised
81+ styleColor: "black"
82+ opacity: .6
83+ //TRANSLATORS: Number of persons who wrote reviews for this app
84+ text: i18n.tr("%1 review", "%1 reviews", root.reviews).arg(root.reviews)
85+ }
86+ }
87+ }
88+}
Dash/Apps/AppPreview.qmlnew file+195
@@ -0,0 +1,195 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItem
20+import Ubuntu.DownloadDaemonListener 0.1
21+import ".."
22+import "../../Components"
23+import "../../Components/IconUtil.js" as IconUtil
24+
25+DashPreview {
26+ id: root
27+
28+ signal sendUserReview(string review)
29+
30+ title: root.previewData.title
31+
32+ header: ListView {
33+ spacing: units.gu(1)
34+ orientation: ListView.Horizontal
35+ height: units.gu(22)
36+ anchors {
37+ left: parent.left
38+ right: parent.right
39+ margins: units.gu(1)
40+ }
41+ model: previewData.infoMap["more-screenshots"].value
42+
43+ delegate: UbuntuShape {
44+ id: shape
45+ anchors {
46+ top: parent.top
47+ bottom: parent.bottom
48+ }
49+ width: units.gu(12)
50+ radius: "medium"
51+ borderSource: ""
52+ image: Image {
53+ asynchronous: true
54+ sourceSize { width: shape.width; height: shape.height }
55+ source: modelData ? modelData : ""
56+ fillMode: Image.PreserveAspectCrop
57+ }
58+ }
59+ }
60+
61+ Component {
62+ id: buttonsComponent
63+
64+ GridView {
65+ id: buttonsGrid
66+ objectName: "gridButtons"
67+
68+ property int numOfRows: (count + 1) / 2
69+ property int spacing: units.gu(1)
70+ height: Math.max(units.gu(5), units.gu(5)*numOfRows + spacing*(numOfRows - 1))
71+
72+ interactive: false
73+ cellWidth: Math.max(units.gu(9), width / 2)
74+ cellHeight: buttonHeight + spacing
75+ property int buttonWidth: count > 1 ? Math.max(0, width / 2 - spacing) : width
76+ property int buttonHeight: units.gu(5)
77+
78+ delegate: Button {
79+ width: Math.max(units.gu(4), buttonsGrid.buttonWidth)
80+ height: buttonsGrid.buttonHeight
81+ color: Theme.palette.selected.foreground
82+ text: modelData.displayName
83+ iconSource: modelData.iconHint
84+ iconPosition: "right"
85+ onClicked: root.previewData.execute(modelData.id, { })
86+ }
87+ }
88+ }
89+
90+ Component {
91+ id: progressComponent
92+
93+ ProgressBar {
94+ id: progressBar
95+ objectName: "progressBar"
96+ value: 0
97+ maximumValue: 100
98+ height: units.gu(5)
99+
100+ property var model
101+
102+ DownloadTracker {
103+ service: "com.canonical.applications.Downloader"
104+ dbusPath: root.previewData.infoMap["progressbar_source"] ? root.previewData.infoMap["progressbar_source"].value : ""
105+
106+ onProgress: {
107+ var percentage = parseInt(received * 100 / total);
108+ progressBar.value = percentage;
109+ }
110+
111+ onFinished: {
112+ root.previewData.execute(progressBar.model[0].id, { })
113+ }
114+ }
115+
116+ }
117+ }
118+
119+ buttons: Loader {
120+ anchors {
121+ left: parent.left
122+ right: parent.right
123+ }
124+
125+ sourceComponent: root.previewData.infoMap["show_progressbar"] ? progressComponent : buttonsComponent
126+
127+ onLoaded: {
128+ item.model = root.previewData.actions;
129+ }
130+ }
131+
132+ body: Column {
133+ spacing: units.gu(1)
134+
135+ AppInfo {
136+ objectName: "appInfo"
137+ anchors { left: parent.left; right: parent.right }
138+
139+ appName: root.previewData.title
140+ icon: IconUtil.from_gicon(root.previewData.appIcon)
141+ rating: root.previewData.infoMap["rating"] ? root.previewData.infoMap["rating"].value : 0
142+ rated: root.previewData.infoMap["rated"] ? root.previewData.infoMap["rated"].value : 0
143+ reviews: root.previewData.infoMap["reviews"] ? root.previewData.infoMap["reviews"].value : 0
144+ }
145+
146+ Label {
147+ anchors { left: parent.left; right: parent.right }
148+ text: root.previewData.description
149+ fontSize: "medium"
150+ color: Theme.palette.selected.backgroundText
151+ opacity: .6
152+ wrapMode: Text.WordWrap
153+ style: Text.Raised
154+ styleColor: "black"
155+ }
156+
157+ ListItem.ThinDivider {}
158+
159+ Item {
160+ anchors { left: parent.left; right: parent.right }
161+ height: rateLabel.height
162+
163+ Label {
164+ id: rateLabel
165+ fontSize: "medium"
166+ color: "white"
167+ style: Text.Raised
168+ styleColor: "black"
169+ opacity: .9
170+ text: i18n.tr("Rate this")
171+
172+ anchors.left: parent.left
173+ anchors.verticalCenter: parent.verticalCenter
174+ }
175+
176+ // FIXME these need to be made interactive and connected to the scope
177+ RatingStars {
178+ anchors.right: parent.right
179+ anchors.verticalCenter: parent.verticalCenter
180+ }
181+ }
182+
183+ ListItem.ThinDivider {}
184+
185+ AppReviews {
186+ objectName: "appReviews"
187+ anchors { left: parent.left; right: parent.right }
188+
189+ model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
190+
191+ onSendReview: root.sendUserReview(review);
192+ }
193+
194+ }
195+}
Dash/Apps/AppReviews.qmlnew file+191
@@ -0,0 +1,191 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItem
20+import "../../Components"
21+
22+Column {
23+ id: root
24+
25+ property var model
26+
27+ signal sendReview(string review)
28+
29+ spacing: units.gu(2)
30+ state: ""
31+
32+ states: [
33+ State {
34+ name: ""
35+ PropertyChanges { target: reviewField; width: root.width }
36+ PropertyChanges { target: sendButton; opacity: 0 }
37+ PropertyChanges { target: inverseArea; enabled: false }
38+ },
39+ State {
40+ name: "editing"
41+ PropertyChanges { target: reviewField; width: (root.width - row.spacing - sendButton.width) }
42+ PropertyChanges { target: sendButton; opacity: 1 }
43+ PropertyChanges { target: inverseArea; enabled: true }
44+ }
45+ ]
46+
47+ transitions: [
48+ Transition {
49+ from: ""
50+ to: "editing"
51+ SequentialAnimation {
52+ UbuntuNumberAnimation { target: reviewField; properties: "width"; duration: UbuntuAnimation.SlowDuration }
53+ UbuntuNumberAnimation { target: sendButton; properties: "opacity"; duration: UbuntuAnimation.SlowDuration }
54+ }
55+ },
56+ Transition {
57+ from: "editing"
58+ to: ""
59+ SequentialAnimation {
60+ UbuntuNumberAnimation { target: sendButton; properties: "opacity"; duration: UbuntuAnimation.SlowDuration }
61+ UbuntuNumberAnimation { target: reviewField; properties: "width"; duration: UbuntuAnimation.SlowDuration }
62+ }
63+ }
64+ ]
65+
66+ Label {
67+ fontSize: "medium"
68+ color: "white"
69+ style: Text.Raised
70+ styleColor: "black"
71+ opacity: .9
72+ text: i18n.tr("Add a review")
73+ }
74+
75+ Row {
76+ id: row
77+ spacing: units.gu(1)
78+ width: root.width
79+
80+ // FIXME: needs to react to Qt.inputMethod geometry
81+ TextArea {
82+ id: reviewField
83+ objectName: "reviewField"
84+ placeholderText: i18n.tr("Review")
85+ width: parent.width
86+ verticalAlignment: Text.AlignVCenter
87+ autoSize: true
88+ maximumLineCount: 5
89+
90+ Behavior on height { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
91+
92+ onFocusChanged: {
93+ if(reviewField.focus){
94+ root.state = "editing";
95+ reviewField.selectAll();
96+ }
97+ }
98+
99+ // FIXME: not active when in wide mode
100+ InverseMouseArea {
101+ id: inverseArea
102+ anchors.fill: parent
103+ enabled: false
104+ onPressed: {
105+ reviewField.focus = false;
106+ root.state = "";
107+ }
108+ }
109+ }
110+
111+ Button {
112+ id: sendButton
113+ objectName: "sendButton"
114+ width: units.gu(10)
115+ height: units.gu(4)
116+ anchors.bottom: reviewField.bottom
117+ color: Theme.palette.selected.foreground
118+ text: i18n.tr("Send")
119+ opacity: 0
120+
121+ onClicked: {
122+ root.sendReview(reviewField.text);
123+ reviewField.text = ""
124+ }
125+ }
126+ }
127+
128+ ListItem.ThinDivider {}
129+
130+ Label {
131+ fontSize: "medium"
132+ color: "white"
133+ style: Text.Raised
134+ styleColor: "black"
135+ opacity: .9
136+ text: i18n.tr("Comments:")
137+ }
138+
139+ Repeater {
140+ objectName: "commentsArea"
141+ model: root.model
142+
143+ Column {
144+ anchors { left: parent.left; right: parent.right }
145+
146+ Column {
147+ anchors { left: parent.left; right: parent.right }
148+
149+ Label {
150+ anchors { left: parent.left; right: parent.right }
151+ text: modelData[0]
152+ fontSize: "medium"
153+ color: "white"
154+ opacity: .8
155+ wrapMode: Text.WordWrap
156+ style: Text.Raised
157+ styleColor: "black"
158+ }
159+
160+ Row {
161+ spacing: units.gu(1)
162+
163+ RatingStars {
164+ maximumRating: 10
165+ rating: modelData[1]
166+ }
167+
168+ Label {
169+ text: modelData[2]
170+ fontSize: "medium"
171+ color: Theme.palette.selected.backgroundText
172+ opacity: .6
173+ style: Text.Raised
174+ styleColor: "black"
175+ }
176+ }
177+ }
178+
179+ Label {
180+ anchors { left: parent.left; right: parent.right }
181+ text: modelData[3]
182+ fontSize: "medium"
183+ color: Theme.palette.selected.backgroundText
184+ opacity: .6
185+ wrapMode: Text.WordWrap
186+ style: Text.Raised
187+ styleColor: "black"
188+ }
189+ }
190+ }
191+}
Dash/Apps/ApplicationsFilterGrid.qml−1
@@ -23,7 +23,6 @@ FilterGrid {
23 id: filterGrid
23 id: filterGrid
24
24
25 filter: false
25 filter: false
26− expandable: false
27 minimumHorizontalSpacing: units.gu(0.5)
26 minimumHorizontalSpacing: units.gu(0.5)
28 maximumNumberOfColumns: 6
27 maximumNumberOfColumns: 6
29 delegateWidth: units.gu(11)
28 delegateWidth: units.gu(11)
Dash/Apps/AppsAvailableForDownloadModel.qml+61−6
@@ -15,12 +15,67 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import "../../Applications"
18
19
19ListModel {
20ListModel {
21+ ListElement {
22+ uri: "application://evernote.desktop"
23+ icon: "../../graphics/applicationIcons/evernote.png"
24+ category: 0
25+ mimetype: "application/x-desktop"
26+ title: "Evernote"
27+ comment: ""
20− ListElement { desktopFile: "/usr/share/applications/evernote.desktop"; }
28+ dndUri: "file:///usr/share/applications/evernote.desktop"
29+ metadata: ""
30+ }
31+ ListElement {
32+ uri: "application://map.desktop"
33+ icon: "../../graphics/applicationIcons/map.png"
34+ category: 0
35+ mimetype: "application/x-desktop"
36+ title: "Map"
37+ comment: ""
21− ListElement { desktopFile: "/usr/share/applications/map.desktop"; }
38+ dndUri: "file:///usr/share/applications/map.desktop"
39+ metadata: ""
40+ }
41+ ListElement {
42+ uri: "application://pinterest.desktop"
43+ icon: "../../graphics/applicationIcons/pinterest.png"
44+ category: 0
45+ mimetype: "application/x-desktop"
46+ title: "Pinterest"
47+ comment: ""
22− ListElement { desktopFile: "/usr/share/applications/pinterest.desktop"; }
48+ dndUri: "file:///usr/share/applications/pinterest.desktop"
49+ metadata: ""
50+ }
51+ ListElement {
52+ uri: "application://soundcloud.desktop"
53+ icon: "../../graphics/applicationIcons/soundcloud.png"
54+ category: 0
55+ mimetype: "application/x-desktop"
56+ title: "Soundcloud"
57+ comment: ""
23− ListElement { desktopFile: "/usr/share/applications/soundcloud.desktop"; }
58+ dndUri: "file:///usr/share/applications/soundcloud.desktop"
59+ metadata: ""
60+ }
61+ ListElement {
62+ uri: "application://wikipedia.desktop"
63+ icon: "../../graphics/applicationIcons/wikipedia.png"
64+ category: 0
65+ mimetype: "application/x-desktop"
66+ title: "Wikipedia"
67+ comment: ""
24− ListElement { desktopFile: "/usr/share/applications/wikipedia.desktop"; }
68+ dndUri: "file:///usr/share/applications/wikipedia.desktop"
69+ metadata: ""
70+ }
71+ ListElement {
72+ uri: "application://youtube.desktop"
73+ icon: "../../graphics/applicationIcons/youtube.png"
74+ category: 0
75+ mimetype: "application/x-desktop"
76+ title: "Youtube"
77+ comment: ""
25− ListElement { desktopFile: "/usr/share/applications/youtube.desktop"; }
78+ dndUri: "file:///usr/share/applications/youtube.desktop"
79+ metadata: ""
80+ }
26}
81}
Dash/Apps/FrequentlyUsedAppsModel.qml+60−6
@@ -17,10 +17,64 @@
17import QtQuick 2.0
17import QtQuick 2.0
18
18
19ListModel {
19ListModel {
20+ ListElement {
21+ uri: "application:///usr/share/applications/camera-app.desktop"
22+ icon: "../../graphics/applicationIcons/camera.png"
23+ category: 0
24+ mimetype: "application/x-desktop"
25+ title: "Camera"
26+ comment: ""
27+ dndUri: "file:///usr/share/applications/camera-app.desktop"
28+ metadata: ""
29+ }
30+ ListElement {
31+ uri: "application:///usr/share/applications/phone-app.desktop"
32+ icon: "../../graphics/applicationIcons/phone-app.png"
33+ category: 0
34+ mimetype: "application/x-desktop"
35+ title: "Phone"
36+ comment: ""
37+ dndUri: "file:///usr/share/applications/phone-app.desktop"
38+ metadata: ""
39+ }
40+ ListElement {
41+ uri: "application:///usr/share/applications/galery-app.desktop"
42+ icon: "../../graphics/applicationIcons/gallery.png"
43+ category: 0
44+ mimetype: "application/x-desktop"
45+ title: "Gallery"
46+ comment: ""
47+ dndUri: "file:///usr/share/applications/gallery.desktop"
48+ metadata: ""
49+ }
50+ ListElement {
20− ListElement { desktopFile: "/usr/share/applications/camera-app.desktop"; }
51+ uri: "application:///usr/share/applications/facebook-webapp.desktop"
52+ icon: "../../graphics/applicationIcons/facebook.png"
53+ category: 0
54+ mimetype: "application/x-desktop"
55+ title: "Facebook"
56+ comment: ""
21− ListElement { desktopFile: "/usr/share/applications/phone-app.desktop"; }
57+ dndUri: "file:///usr/share/applications/facebook-webapp.desktop"
58+ metadata: ""
59+ }
60+ ListElement {
22− ListElement { desktopFile: "/usr/share/applications/gallery-app.desktop"; }
61+ uri: "application:///usr/share/applications/webbrowser-app.desktop"
62+ icon: "../../graphics/applicationIcons/browser.png"
63+ category: 0
64+ mimetype: "application/x-desktop"
65+ title: "Browser"
66+ comment: ""
23− ListElement { desktopFile: "/usr/share/applications/facebook-webapp.desktop"; }
67+ dndUri: "file:///usr/share/applications/webbrowser-app.desktop"
68+ metadata: ""
69+ }
70+ ListElement {
24− ListElement { desktopFile: "/usr/share/applications/webbrowser-app.desktop"; }
71+ uri: "application:///usr/share/applications/gmail-webapp.desktop"
72+ icon: "../../graphics/applicationIcons/gmail.png"
73+ category: 0
74+ mimetype: "application/x-desktop"
75+ title: "GMail"
76+ comment: ""
25− ListElement { desktopFile: "/usr/share/applications/gmail-webapp.desktop"; }
77+ dndUri: "file:///usr/share/applications/gmail-webapp.desktop"
78+ metadata: ""
79+ }
26}
80}
Dash/DashApps.qml+23−132
@@ -19,155 +19,46 @@ import Ubuntu.Components 0.1
19import Utils 0.1
19import Utils 0.1
20import "../Components"
20import "../Components"
21import "../Components/ListItems"
21import "../Components/ListItems"
22+import "../Applications"
22import "Apps"
23import "Apps"
23
24
24−ScopeView {
25+GenericScopeView {
25 id: scopeView
26 id: scopeView
26
27
27 // FIXME: a way to aggregate these models would be ideal
28 // FIXME: a way to aggregate these models would be ideal
28 property var mainStageApplicationsModel: shell.applicationManager.mainStageApplications
29 property var mainStageApplicationsModel: shell.applicationManager.mainStageApplications
29 property var sideStageApplicationModel: shell.applicationManager.sideStageApplications
30 property var sideStageApplicationModel: shell.applicationManager.sideStageApplications
30
31
31− onMovementStarted: categoryView.showHeader()
32+ SearchableResultModel {
32− onPositionedAtBeginning: {
33+ id: appsAvailableForDownloadModel
33− if (isCurrent) {
34− categoryView.positionAtBeginning()
35− }
36− }
37−
38− onIsCurrentChanged: {
39− pageHeader.resetSearch();
40− }
41−
42− Binding {
43− target: scopeView.scope
44− property: "searchQuery"
45− value: pageHeader.searchQuery
46− }
47
34
48− Connections {
35+ model: AppsAvailableForDownloadModel {}
49− target: panel
36+ filterRole: 3
50− onSearchClicked: if (isCurrent) {
37+ searchQuery: scopeView.scope.searchQuery
51− pageHeader.triggerSearch()
52− categoryView.showHeader()
53− }
54 }
38 }
55
39
56 ListModel {
40 ListModel {
57− id: categoryListModel
41+ id: dummyVisibilityModifier
58− // specifies app categories, type of delegate and model used in each category
59− ListElement { category: "Running apps"; component: "Apps/RunningApplicationsGrid.qml"; modelName: "RunningApplicationsModel" }
60− ListElement { category: "Frequently used"; component: "Apps/ApplicationsFilterGrid.qml"; modelName: "FrequentlyUsedAppsModel" }
61− ListElement { category: "Installed"; component: "Apps/ApplicationsFilterGrid.qml"; modelName: "InstalledApplicationsModel" }
62− ListElement { category: "Available for download"; component: "Apps/ApplicationsFilterGrid.qml"; modelName: "AppsAvailableForDownloadModel" }
63− function getCategory(category1) {
64− if (category1 === "Running apps") {
65− return i18n.tr("Running apps");
66− }
67− if (category1 === "Frequently used") {
68− return i18n.tr("Frequently used");
69− }
70− if (category1 === "Installed") {
71− return i18n.tr("Installed");
72− }
73− if (category1 === "Available for download") {
74− return i18n.tr("Available for download");
75− }
76− return ""
77− }
78− }
79−
80− FrequentlyUsedAppsModel { id: frequentlyUsedAppsModel }
81− AppsAvailableForDownloadModel { id: appsAvailableForDownloadModel }
82−
83− // FIXME this should not be needed, the backend should handle all that itself
84− property var installedModel: null
85
42
86− Repeater {
43+ ListElement { name: "running-apps" }
87− model: scopeView.scope.categories
88−
89− delegate: Item {
90− Component.onCompleted: if (categoryId == "installed") scopeView.installedModel = Qt.binding(function() { return model.results; });
91− }
92− }
93−
94− property var categoryModels: {
95− "FrequentlyUsedAppsModel": frequentlyUsedAppsModel,
96− "InstalledApplicationsModel": installedModel,
97− "AppsAvailableForDownloadModel": appsAvailableForDownloadModel,
98 }
44 }
99
45
100− ScopeListView {
46+ SortFilterProxyModel {
101− id: categoryView
47+ id: runningApplicationsModel
102− anchors.fill: parent
103− model: SortFilterProxyModel {
104− model: categoryListModel
105− filterRole: 0 // 0 == modelName
106− // FIXME: need to use invertMatch here, otherwise the filter won't update correctly
107− // if filterRegExp is set before invertMatch. Bug in SortFilterProxyModel?
108− filterRegExp: invertMatch ? ((mainStageApplicationsModel.count === 0
109− && sideStageApplicationModel.count === 0) ? RegExp("RunningApplicationsModel") : RegExp("")) :
110− RegExp("InstalledApplicationsModel")
111− invertMatch: pageHeader.searchQuery.length == 0
112− }
113−
114− onAtYEndChanged: if (atYEnd) endReached()
115− onMovingChanged: if (moving && atYEnd) endReached()
116
48
117− delegate: Base {
49+ property var firstModel: mainStageApplicationsModel
118− id: container
50+ property var secondModel: sideStageApplicationModel
119− highlightWhenPressed: false
51+ property bool canEnableTerminationMode: scopeView.isCurrent
120
52
121− Loader {
53+ model: dummyVisibilityModifier
122− anchors {
54+ filterRole: 0
123− top: parent.top
124− left: parent.left
125− right: parent.right
126− }
127− source: component
128− onLoaded: {
129− if (modelName == "RunningApplicationsModel") {
130− item.firstModel = mainStageApplicationsModel
55+ filterRegExp: invertMatch ? ((mainStageApplicationsModel.count === 0 &&
131− item.secondModel = sideStageApplicationModel
56+ sideStageApplicationModel.count === 0) ? RegExp("running-apps") : RegExp("")) : RegExp("disabled")
132− item.canEnableTerminationMode =
57+ invertMatch: scopeView.scope.searchQuery.length == 0
133− Qt.binding(function() { return isCurrent; })
134− } else {
135− function activateApplication(index, data) {
136− shell.activateApplication(data);
137− }
138−
139− item.model = Qt.binding(function() { return categoryModels[modelName]; });
140− item.clicked.connect(activateApplication);
141−
142− }
143− }
144− }
145−
146− ListView.onRemove: SequentialAnimation {
147− PropertyAction {
148− target: container; property: "ListView.delayRemove"; value: true
149− }
150− NumberAnimation {
151− target: container; property: "height"; to: 0;
152− duration: 250; easing.type: Easing.InOutQuad
153− }
154− PropertyAction {
155− target: container; property: "ListView.delayRemove"; value: false
156− }
157− }
158− }
58+ }
159
59
160− sectionProperty: "category"
60+ onScopeChanged: {
161− sectionDelegate: Header {
61+ scopeView.scope.categories.overrideResults("recent", runningApplicationsModel);
162− width: categoryView.width
62+ scopeView.scope.categories.overrideResults("more", appsAvailableForDownloadModel);
163− text: categoryListModel.getCategory(section)
164− }
165− pageHeader: PageHeader {
166− id: pageHeader
167− width: categoryView.width
168− text: i18n.tr("Apps")
169− searchEntryEnabled: true
170− searchHistory: scopeView.searchHistory
171− }
172 }
63 }
173}
64}
Dash/DashHome.qml+8−123
@@ -19,136 +19,21 @@ import Ubuntu.Components 0.1
19import Utils 0.1
19import Utils 0.1
20import "../Components"
20import "../Components"
21import "../Components/ListItems"
21import "../Components/ListItems"
22−import "../Applications"
23import "Apps"
22import "Apps"
24−import "Video"
25−import "Music"
26
23
27−ScopeView {
24+GenericScopeView {
28 id: root
25 id: root
29 objectName: "DashHome"
26 objectName: "DashHome"
30
27
31− onMovementStarted: listView.showHeader()
28+ SearchableResultModel {
29+ id: appsModel
32
30
33− ListModel {
31+ model: FrequentlyUsedAppsModel {}
34− id: categoryListModel
32+ filterRole: 3
35− // specifies page's content categories, type of delegate and model used in each category
33+ searchQuery: root.scope.searchQuery
36− ListElement { category: "Frequent Apps"; component: "Apps/ApplicationsFilterGrid.qml"; modelName: "AppsModel" }
37− ListElement { category: "Recent Music"; component: "Music/MusicFilterGrid.qml"; modelName: "MusicModel" }
38− ListElement { category: "Videos Popular Online"; component: "Video/VideosFilterGrid.qml"; modelName: "VideosModel" }
39− function getCategory(category1) {
40− if (category1 === "Frequent Apps") {
41− return i18n.tr("Frequent Apps");
42− }
43− if (category1 === "Recent Music") {
44− return i18n.tr("Recent Music");
45− }
46− if (category1 === "Videos Popular Online") {
47− return i18n.tr("Videos Popular Online");
48− }
49− return ""
50− }
51 }
34 }
52
35
53− FrequentlyUsedAppsModel { id: appsModel }
36+ onScopeChanged: {
54−
37+ root.scope.categories.overrideResults("applications.scope", appsModel);
55− // FIXME this should be handled by the backends by populating the global search model
56− property var musicModel: null
57− property var videosModel: null
58−
59− Repeater {
60− id: musicRepeater
61−
62− delegate: Item {
63− Component.onCompleted: if (index == 1) musicModel = Qt.binding(function() { return model.results; });
64− }
65− }
66−
67− Repeater {
68− id: videosRepeater
69−
70− delegate: Item {
71− Component.onCompleted: if (index == 3) videosModel = Qt.binding(function() { return model.results; });
72− }
73− }
74−
75− Component.onCompleted: {
76− var scope = dashContent.scopes.get("mockmusicmaster.scope")
77− if (scope) {
78− musicRepeater.model = dashContent.scopes.get("mockmusicmaster.scope").categories
79− }
80− scope = dashContent.scopes.get("mockvideosmaster.scope")
81− if (scope) {
82− videosRepeater.model = dashContent.scopes.get("mockvideosmaster.scope").categories
83− }
84− }
85−
86− Connections {
87− target: dashContent
88− onScopeLoaded: switch (scopeId) {
89− case "mockmusicmaster.scope":
90− musicRepeater.model = dashContent.scopes.get("mockmusicmaster.scope").categories
91− break;
92− case "mockvideosmaster.scope":
93− videosRepeater.model = dashContent.scopes.get("mockvideosmaster.scope").categories
94− break;
95− }
96− }
97−
98− property var categoryModels: {"AppsModel": appsModel,
99− "MusicModel": musicModel,
100− "VideosModel": videosModel,
101− }
102−
103− ScopeListView {
104− id: listView
105− anchors.fill: parent
106− model: categoryListModel
107−
108− onAtYEndChanged: if (atYEnd) endReached()
109− onMovingChanged: if (moving && atYEnd) endReached()
110−
111− delegate: Base {
112− id: container
113− highlightWhenPressed: false
114− width: listView.width
115−
116− Loader {
117− anchors { top: parent.top; left: parent.left; right: parent.right }
118− source: component
119− onLoaded: {
120− item.model = Qt.binding(function() { return categoryModels[modelName]; });
121−
122− //FIXME: workaround for lack of previews for videos in Home scope.
123− //Need to connect to the clicked() signal here and act upon it here instead.
124− if (modelName === "VideosModel") {
125− function playVideo(index, data) {
126− if (data.fileUri) {
127− shell.activateApplication('/usr/share/applications/mediaplayer-app.desktop', "/usr/share/demo-assets/videos/" + data.fileUri);
128− }
129− }
130−
131− item.clicked.connect(playVideo);
132− } else if (modelName === "AppsModel") {
133− function activateApplication(index, data) {
134− shell.activateApplication(data);
135− }
136−
137− item.objectName = "dashHomeApplicationsGrid";
138− item.clicked.connect(activateApplication);
139− }
140− }
141− }
142− }
143−
144− sectionProperty: "category"
145− sectionDelegate: Header {
146− width: listView.width
147− text: listView.model.getCategory(section)
148− }
149− pageHeader: PageHeader {
150− width: listView.width
151− text: i18n.tr("Home")
152− }
153 }
38 }
154}
39}
Dash/DashPreview.qml+11−41
@@ -19,14 +19,15 @@ import Ubuntu.Components 0.1
19
19
20Rectangle {
20Rectangle {
21 id: root
21 id: root
22+
23+ property var previewData
24+
22 property string title: ""
25 property string title: ""
23− property url url: ""
24 property real previewWidthRatio: 0.5
26 property real previewWidthRatio: 0.5
25− property bool playable: false
27+
26− property bool forceSquare: false
28+ property Component header
27 property Component buttons
29 property Component buttons
28− property Component caption
30+ property Component body
29− property Component description
30
31
31 readonly property bool narrowMode: width <= height
32 readonly property bool narrowMode: width <= height
32 readonly property int contentSpacing: units.gu(3)
33 readonly property int contentSpacing: units.gu(3)
@@ -141,38 +142,13 @@ Rectangle {
141 right: parent.right
142 right: parent.right
142 }
143 }
143 height: childrenRect.height
144 height: childrenRect.height
144− spacing: root.contentSpacing
145+ spacing: units.gu(1)
145
146
146− // TODO: replace this UbuntuShape with the Video component once that lands
147+ Loader {
147− // with the player.
148+ id: headerLoader
148− UbuntuShape {
149− id: urlLoader
150 anchors.left: parent.left
149 anchors.left: parent.left
151 anchors.right: parent.right
150 anchors.right: parent.right
152− height: root.forceSquare ? width : width * previewImage.sourceSize.height / previewImage.sourceSize.width
151+ sourceComponent: root.header
153− radius: "medium"
154− image: Image {
155− id: previewImage
156− asynchronous: true
157− source: root.url
158− fillMode: Image.PreserveAspectCrop
159− }
160−
161− Image {
162− objectName: "playButton"
163− anchors.centerIn: parent
164− visible: root.playable
165− readonly property bool bigButton: parent.width > units.gu(40)
166− width: bigButton ? units.gu(8) : units.gu(4.5)
167− height: width
168− source: "graphics/play_button%1%2.png".arg(previewImageMouseArea.pressed ? "_active" : "").arg(bigButton ? "_big" : "")
169− }
170−
171− MouseArea {
172− id: previewImageMouseArea
173− anchors.fill: parent
174− onClicked: root.previewImageClicked()
175− }
176 }
152 }
177 Loader {
153 Loader {
178 id: buttonLoader
154 id: buttonLoader
@@ -180,12 +156,6 @@ Rectangle {
180 anchors.right: parent.right
156 anchors.right: parent.right
181 sourceComponent: root.buttons
157 sourceComponent: root.buttons
182 }
158 }
183− Loader {
184− id: captionLoader
185− anchors.left: parent.left
186− anchors.right: parent.right
187− sourceComponent: root.caption
188− }
189 }
159 }
190 }
160 }
191
161
@@ -213,6 +183,6 @@ Rectangle {
213 parent: root.narrowMode ? leftColumn : rightColumn
183 parent: root.narrowMode ? leftColumn : rightColumn
214 anchors.left: parent.left
184 anchors.left: parent.left
215 anchors.right: parent.right
185 anchors.right: parent.right
216− sourceComponent: root.description
186+ sourceComponent: root.body
217 }
187 }
218}
188}
Dash/Generic/GenericFilterGrid.qml−1
@@ -21,7 +21,6 @@ import "../../Components/IconUtil.js" as IconUtil
21FilterGrid {
21FilterGrid {
22 id: filtergrid
22 id: filtergrid
23
23
24− filter: false
25 minimumHorizontalSpacing: units.gu(0.5)
24 minimumHorizontalSpacing: units.gu(0.5)
26 delegateWidth: units.gu(11)
25 delegateWidth: units.gu(11)
27 delegateHeight: units.gu(9.5)
26 delegateHeight: units.gu(9.5)
Dash/Generic/GenericPreview.qml+17−3
@@ -23,12 +23,26 @@ import ".."
23
23
24DashPreview {
24DashPreview {
25 id: genericPreview
25 id: genericPreview
26− property var previewData
27
26
28 title: previewData.title
27 title: previewData.title
29− url: IconUtil.from_gicon(previewData.image)
30 previewWidthRatio: 0.6
28 previewWidthRatio: 0.6
31
29
30+ property url url: IconUtil.from_gicon(previewData.image)
31+
32+ header: UbuntuShape {
33+ id: urlLoader
34+ anchors.left: parent.left
35+ anchors.right: parent.right
36+ height: width * previewImage.sourceSize.height / previewImage.sourceSize.width
37+ radius: "medium"
38+ image: Image {
39+ id: previewImage
40+ asynchronous: true
41+ source: genericPreview.url
42+ fillMode: Image.PreserveAspectCrop
43+ }
44+ }
45+
32 buttons: GridView {
46 buttons: GridView {
33 id: buttons
47 id: buttons
34 model: genericPreview.previewData.actions
48 model: genericPreview.previewData.actions
@@ -56,7 +70,7 @@ DashPreview {
56 }
70 }
57 focus: false
71 focus: false
58 }
72 }
59− description: Column {
73+ body: Column {
60 spacing: units.gu(2)
74 spacing: units.gu(2)
61
75
62 Label {
76 Label {
Dash/GenericScopeView.qml+54−2
@@ -53,9 +53,14 @@ ScopeView {
53 onAtYEndChanged: if (atYEnd) endReached()
53 onAtYEndChanged: if (atYEnd) endReached()
54 onMovingChanged: if (moving && atYEnd) endReached()
54 onMovingChanged: if (moving && atYEnd) endReached()
55
55
56+ property int expandedIndex: -1
57+
56 delegate: ListItems.Base {
58 delegate: ListItems.Base {
57 highlightWhenPressed: false
59 highlightWhenPressed: false
58
60
61+ readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
62+ readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
63+
59 Loader {
64 Loader {
60 id: rendererLoader
65 id: rendererLoader
61 anchors {
66 anchors {
@@ -67,7 +72,14 @@ ScopeView {
67 source: getRenderer(model.renderer, model.contentType)
72 source: getRenderer(model.renderer, model.contentType)
68
73
69 onLoaded: {
74 onLoaded: {
75+ if (source.toString().indexOf("Apps/RunningApplicationsGrid.qml") != -1) {
76+ // TODO: the running apps grid doesn't support standard scope results model yet
77+ item.firstModel = results.firstModel
78+ item.secondModel = results.secondModel
79+ } else {
70− item.model = results
80+ item.model = results
81+ }
82+ item.objectName = categoryId
71 }
83 }
72
84
73 Connections {
85 Connections {
@@ -97,13 +109,47 @@ ScopeView {
97 delegateItem.model.metadata)
109 delegateItem.model.metadata)
98 }
110 }
99 }
111 }
112+ Connections {
113+ target: categoryView
114+ onExpandedIndexChanged: {
115+ var item = rendererLoader.item;
116+ if (item.expandable) {
117+ var shouldFilter = index != categoryView.expandedIndex;
118+ if (shouldFilter != item.filter) {
119+ // If the filter animation will be seen start it, otherwise, just flip the switch
120+ var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
121+ var growingVisible = !shouldFilter && y + height < categoryView.height;
122+ if (shrinkingVisible || growingVisible) {
123+ item.startFilterAnimation(shouldFilter)
124+ } else {
125+ item.filter = shouldFilter;
126+ }
127+ if (!shouldFilter) {
128+ categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
129+ }
130+ }
131+ }
132+ }
133+ }
100 }
134 }
101 }
135 }
102
136
103 sectionProperty: "name"
137 sectionProperty: "name"
104 sectionDelegate: ListItems.Header {
138 sectionDelegate: ListItems.Header {
139+ property var delegate: categoryView.item(delegateIndex)
105 width: categoryView.width
140 width: categoryView.width
106 text: section
141 text: section
142+ image: {
143+ if (delegate && delegate.expandable)
144+ return delegate.filtered ? "graphics/header_handlearrow.png" : "graphics/header_handlearrow2.png"
145+ return "";
146+ }
147+ onClicked: {
148+ if (categoryView.expandedIndex != delegateIndex)
149+ categoryView.expandedIndex = delegateIndex;
150+ else
151+ categoryView.expandedIndex = -1;
152+ }
107 }
153 }
108 pageHeader: PageHeader {
154 pageHeader: PageHeader {
109 id: pageHeader
155 id: pageHeader
@@ -132,6 +178,12 @@ ScopeView {
132 }
178 }
133 }
179 }
134 case "carousel": return "Generic/GenericCarousel.qml";
180 case "carousel": return "Generic/GenericCarousel.qml";
181+ case "special": {
182+ switch (contentType) {
183+ case "apps": return "Apps/RunningApplicationsGrid.qml";
184+ default: return "Generic/GenericFilterGrid.qml";
185+ }
186+ }
135 default: return "Generic/GenericFilterGrid.qml";
187 default: return "Generic/GenericFilterGrid.qml";
136 }
188 }
137 }
189 }
@@ -211,7 +263,7 @@ ScopeView {
211 }
263 }
212
264
213 onLoaded: {
265 onLoaded: {
214− item.previewData = previewLoader.previewData
266+ item.previewData = Qt.binding(function() { return previewLoader.previewData })
215 }
267 }
216 }
268 }
217
269
Dash/Music/MusicFilterGrid.qml−1
@@ -20,7 +20,6 @@ import "../../Components"
20FilterGrid {
20FilterGrid {
21 id: filterGrid
21 id: filterGrid
22
22
23− expandable: false
24 minimumHorizontalSpacing: units.gu(2)
23 minimumHorizontalSpacing: units.gu(2)
25 maximumNumberOfColumns: 5
24 maximumNumberOfColumns: 5
26 delegateWidth: units.gu(17)
25 delegateWidth: units.gu(17)
Dash/PreviewDelegateMapper.qml+2
@@ -19,7 +19,9 @@ import QtQuick 2.0
19QtObject {
19QtObject {
20 property var d: QtObject {
20 property var d: QtObject {
21 readonly property string genericPreview: "Generic/GenericPreview.qml"
21 readonly property string genericPreview: "Generic/GenericPreview.qml"
22+ readonly property string appPreview: "Apps/AppPreview.qml"
22 property var previewDelegateMapping: {"preview-generic": genericPreview,
23 property var previewDelegateMapping: {"preview-generic": genericPreview,
24+ "preview-application": appPreview,
23 }
25 }
24 }
26 }
25
27
Dash/ScopeView.qml+8−1
@@ -30,7 +30,14 @@ FocusScope {
30
30
31 // FIXME delay the search so that daemons have time to settle, note that
31 // FIXME delay the search so that daemons have time to settle, note that
32 // removing this will break ScopeView::test_changeScope
32 // removing this will break ScopeView::test_changeScope
33− onScopeChanged: timer.restart()
33+ onScopeChanged: {
34+ timer.restart();
35+ scope.activateApplication.connect(activateApp);
36+ }
37+
38+ function activateApp(desktopFilePath) {
39+ shell.activateApplication(desktopFilePath);
40+ }
34
41
35 Timer {
42 Timer {
36 id: timer
43 id: timer
Dash/SearchableResultModel.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import Utils 0.1
18+import Unity 0.1
19+
20+SortFilterProxyModel {
21+ id: root
22+
23+ property string searchQuery: ""
24+ property bool hideOnSearch: false
25+
26+ filterRole: CategoryResults.RoleTitle
27+
28+ onSearchQueryChanged: {
29+ if (searchQuery.length == 0) {
30+ filterRegExp = RegExp("");
31+ filterCaseSensitivity = Qt.CaseInsensitive;
32+ } else if (!hideOnSearch) {
33+ setFilterWildcard(searchQuery);
34+ filterCaseSensitivity = Qt.CaseInsensitive;
35+ } else {
36+ filterRegExp = /^$/;
37+ filterCaseSensitivity = Qt.CaseInsensitive;
38+ }
39+ }
40+}
Dash/Video/VideoPreview.qml+35−3
@@ -24,7 +24,9 @@ DashPreview {
24
24
25 property var item
25 property var item
26 property alias ready: nfo.ready
26 property alias ready: nfo.ready
27+ property bool playable: fileUri != ""
27 readonly property url fileUri: item ? item.fileUri : ""
28 readonly property url fileUri: item ? item.fileUri : ""
29+ property url url: item ? item.nfoUri.replace(/\.nfo$/, "-fanart.jpg") : ""
28
30
29 VideoInfo {
31 VideoInfo {
30 id: nfo
32 id: nfo
@@ -32,9 +34,7 @@ DashPreview {
32 }
34 }
33
35
34 title: nfo.ready ? nfo.video.title : ""
36 title: nfo.ready ? nfo.video.title : ""
35− url: item ? item.nfoUri.replace(/\.nfo$/, "-fanart.jpg") : ""
36 previewWidthRatio: 0.6
37 previewWidthRatio: 0.6
37− playable: fileUri != ""
38
38
39 onPreviewImageClicked: {
39 onPreviewImageClicked: {
40 if (playable) {
40 if (playable) {
@@ -42,6 +42,38 @@ DashPreview {
42 }
42 }
43 }
43 }
44
44
45+ // TODO: replace this UbuntuShape with the Video component once that lands
46+ // with the player.
47+ header: UbuntuShape {
48+ id: urlLoader
49+ anchors.left: parent.left
50+ anchors.right: parent.right
51+ height: width * previewImage.sourceSize.height / previewImage.sourceSize.width
52+ radius: "medium"
53+ image: Image {
54+ id: previewImage
55+ asynchronous: true
56+ source: root.url
57+ fillMode: Image.PreserveAspectCrop
58+ }
59+
60+ Image {
61+ objectName: "playButton"
62+ anchors.centerIn: parent
63+ visible: root.playable
64+ readonly property bool bigButton: parent.width > units.gu(40)
65+ width: bigButton ? units.gu(8) : units.gu(4.5)
66+ height: width
67+ source: "../graphics/play_button%1%2.png".arg(previewImageMouseArea.pressed ? "_active" : "").arg(bigButton ? "_big" : "")
68+ }
69+
70+ MouseArea {
71+ id: previewImageMouseArea
72+ anchors.fill: parent
73+ onClicked: root.previewImageClicked()
74+ }
75+ }
76+
45 buttons: Row {
77 buttons: Row {
46 spacing: units.gu(2)
78 spacing: units.gu(2)
47
79
@@ -64,7 +96,7 @@ DashPreview {
64 }
96 }
65 }
97 }
66
98
67− description: Column {
99+ body: Column {
68 spacing: units.gu(2)
100 spacing: units.gu(2)
69 RatingStars {
101 RatingStars {
70 maximumRating: 10 // FIXME: this should happen on the backend side
102 maximumRating: 10 // FIXME: this should happen on the backend side
Dash/Video/VideosFilterGrid.qml−1
@@ -20,7 +20,6 @@ import "../../Components"
20FilterGrid {
20FilterGrid {
21 id: filtergrid
21 id: filtergrid
22
22
23− expandable: false
24 minimumHorizontalSpacing: units.gu(0.5)
23 minimumHorizontalSpacing: units.gu(0.5)
25 maximumNumberOfColumns: 5
24 maximumNumberOfColumns: 5
26 delegateWidth: units.gu(11)
25 delegateWidth: units.gu(11)
Dash/graphics/header_handlearrow2@20.pngnew file

Binary file not shown.

Dash/graphics/header_handlearrow@20.pngnew file

Binary file not shown.

Panel/Indicators.qml+3−6
@@ -177,15 +177,12 @@ Showable {
177 }
177 }
178 indicatorsModel: indicatorsModel
178 indicatorsModel: indicatorsModel
179 clip: !indicators.fullyOpened
179 clip: !indicators.fullyOpened
180+ activeHeader: indicators.state == "hint" || indicators.state == "reveal"
180
181
181 Connections {
182 Connections {
182 target: indicatorRow
183 target: indicatorRow
183− onCurrentItemIndexChanged: menuContent.updateCurrentMenu();
184+ onCurrentItemIndexChanged: {
184− }
185−
186− function updateCurrentMenu() {
187− if (currentMenuIndex != indicatorRow.currentItemIndex) {
188− currentMenuIndex = indicatorRow.currentItemIndex;
185+ menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex);
189 }
186 }
190 }
187 }
191
188
Panel/Indicators/DatetimeIndicatorWidget.qml+1−1
@@ -19,7 +19,7 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import Unity.Indicators 0.1 as Indicators
22+import Unity.IndicatorsLegacy 0.1 as Indicators
23
23
24Indicators.IndicatorWidget {
24Indicators.IndicatorWidget {
25 id: indicatorWidget
25 id: indicatorWidget
Panel/Indicators/DefaultIndicatorPage.qml+1−1
@@ -18,7 +18,7 @@
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import Unity.Indicators 0.1 as Indicators
21+import Unity.IndicatorsLegacy 0.1 as Indicators
22
22
23Indicators.IndicatorPage {
23Indicators.IndicatorPage {
24 anchors.fill: parent
24 anchors.fill: parent
Panel/Indicators/DefaultIndicatorPage2.qmlnew file+25
@@ -0,0 +1,25 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+
23+Indicators.IndicatorPage {
24+ anchors.fill: parent
25+}
Panel/Indicators/DefaultIndicatorWidget.qml+1−1
@@ -19,7 +19,7 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import Unity.Indicators 0.1 as Indicators
22+import Unity.IndicatorsLegacy 0.1 as Indicators
23
23
24Indicators.IndicatorWidget {
24Indicators.IndicatorWidget {
25 id: indicatorWidget
25 id: indicatorWidget
Panel/Indicators/DefaultIndicatorWidget2.qmlnew file+76
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.IndicatorWidget {
25+ id: indicatorWidget
26+
27+ width: itemRow.width + units.gu(1)
28+
29+ property alias label: itemLabel.text
30+ property alias iconSource: itemImage.source
31+
32+ Row {
33+ id: itemRow
34+ objectName: "itemRow"
35+ anchors {
36+ top: parent.top
37+ bottom: parent.bottom
38+ horizontalCenter: parent.horizontalCenter
39+ }
40+ spacing: units.gu(0.5)
41+
42+ // FIXME : Should us Ubuntu.Icon . results in low res images
43+ Image {
44+ id: itemImage
45+ objectName: "itemImage"
46+ visible: source != ""
47+ height: indicatorWidget.iconSize
48+ width: indicatorWidget.iconSize
49+ anchors.verticalCenter: parent.verticalCenter
50+ }
51+
52+ Label {
53+ id: itemLabel
54+ objectName: "itemLabel"
55+ color: Theme.palette.selected.backgroundText
56+ opacity: 0.8
57+ font.family: "Ubuntu"
58+ fontSize: "medium"
59+ anchors.verticalCenter: parent.verticalCenter
60+ visible: text != ""
61+ }
62+ }
63+
64+ onActionStateChanged: {
65+ if (actionState == undefined) {
66+ label = "";
67+ iconSource = "";
68+ enabled = false;
69+ return;
70+ }
71+
72+ label = actionState.label;
73+ iconSource = actionState.icon;
74+ enabled = actionState.visible;
75+ }
76+}
Panel/Indicators/MessagingIndicatorPage.qml+1−1
@@ -19,7 +19,7 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import Unity.Indicators 0.1 as Indicators
22+import Unity.IndicatorsLegacy 0.1 as Indicators
23
23
24Indicators.IndicatorPage {
24Indicators.IndicatorPage {
25 anchors.fill: parent
25 anchors.fill: parent
Panel/Indicators/NetworkIndicatorPage.qml+17−13
@@ -18,28 +18,32 @@
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import Unity.Indicators 0.1 as Indicators
21+import Unity.IndicatorsLegacy 0.1 as Indicators
22−import Unity.Indicators.Network 0.1 as ICNetwork
22+import Unity.IndicatorsLegacy.Network 0.1 as ICNetwork
23import Ubuntu.Components 0.1
23import Ubuntu.Components 0.1
24
24
25PageStack {
25PageStack {
26− id: _network
26+ id: network
27+ // Stops the search for a parent tree node.
28+ // We don't want it going up to the indicator tabs.
29+ // FIXME: need a better way of doing this.
30+ // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211704
31+ __propagated: null
27
32
28 property alias title: _mainPage.title
33 property alias title: _mainPage.title
29− property alias emptyText: _pluginItem.emptyText
34+ property alias emptyText: pluginItem.emptyText
30− property alias busType: _pluginItem.busType
35+ property alias busType: pluginItem.busType
31− property alias busName: _pluginItem.busName
36+ property alias busName: pluginItem.busName
32− property alias actionsObjectPath : _pluginItem.actionsObjectPath
37+ property alias actionsObjectPath : pluginItem.actionsObjectPath
33− property alias menuObjectPaths : _pluginItem.menuObjectPaths
38+ property alias menuObjectPaths : pluginItem.menuObjectPaths
34
39
35− __showHeader: false
36 anchors.fill: parent
40 anchors.fill: parent
37
41
38 Page {
42 Page {
39 id: _mainPage
43 id: _mainPage
40
44
41 Indicators.IndicatorPage {
45 Indicators.IndicatorPage {
42− id: _pluginItem
46+ id: pluginItem
43 anchors.fill: parent
47 anchors.fill: parent
44 }
48 }
45 }
49 }
@@ -63,17 +67,17 @@ PageStack {
63 function start()
67 function start()
64 {
68 {
65 push(_mainPage);
69 push(_mainPage);
66− _pluginItem.start();
70+ pluginItem.start();
67 }
71 }
68
72
69 function stop()
73 function stop()
70 {
74 {
71 clear();
75 clear();
72− _pluginItem.stop();
76+ pluginItem.stop();
73 }
77 }
74
78
75 function reset()
79 function reset()
76 {
80 {
77− _pluginItem.reset();
81+ pluginItem.reset();
78 }
82 }
79}
83}
Panel/Indicators/NetworkIndicatorWidget.qml+1−1
@@ -19,7 +19,7 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import Unity.Indicators 0.1 as Indicators
22+import Unity.IndicatorsLegacy 0.1 as Indicators
23
23
24Indicators.IndicatorWidget {
24Indicators.IndicatorWidget {
25 id: indicatorWidget
25 id: indicatorWidget
Panel/Indicators/client/IndicatorsList.qml+1−1
@@ -20,7 +20,7 @@
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
22import Ubuntu.Components.ListItems 0.1 as ListItem
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24import "../.."
24import "../.."
25
25
26Page {
26Page {
Panel/Indicators/client/IndicatorsPage.qml+6−9
@@ -43,6 +43,12 @@ Page {
43 Loader {
43 Loader {
44 id: pageLoader
44 id: pageLoader
45 objectName: "pageLoader"
45 objectName: "pageLoader"
46+ clip:true
47+
48+ Rectangle {
49+ anchors.fill: pageLoader
50+ color: "#221e1c" // FIXME not in palette yet
51+ }
46
52
47 anchors {
53 anchors {
48 top: visualCheckItem.bottom
54 top: visualCheckItem.bottom
@@ -81,14 +87,5 @@ Page {
81 text: "Back"
87 text: "Back"
82 onClicked: page.pageStack.reset()
88 onClicked: page.pageStack.reset()
83 }
89 }
84− Button {
85− id: refresh
86− visible: !visualCheck.checked
87− anchors {
88− right: parent.right
89− }
90− text: "Refresh"
91− onClicked: pageLoader.item.refresh()
92− }
93 }
90 }
94}
91}
Panel/Indicators/client/IndicatorsTree.qml+7−7
@@ -27,8 +27,7 @@ Page {
27 id: page
27 id: page
28 anchors.fill: parent
28 anchors.fill: parent
29
29
30− property alias busType: menuModel.busType
30+ property string busName: unityModel.busName
31− property alias busName: menuModel.busName
32 property string actionsObjectPath
31 property string actionsObjectPath
33 property var menuObjectPaths: undefined
32 property var menuObjectPaths: undefined
34 readonly property string device: "phone"
33 readonly property string device: "phone"
@@ -36,17 +35,18 @@ Page {
36 property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
35 property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
37
36
38 function start() {
37 function start() {
39− menuModel.start();
40 }
38 }
41
39
42− QDBusMenuModel {
40+ UnityMenuModel {
43− id: menuModel
41+ id: unityModel
42+ busName: page.busName
43+ actions: { "indicator": page.actionsObjectPath }
44− objectPath: page.deviceMenuObjectPath
44+ menuObjectPath: page.deviceMenuObjectPath
45 }
45 }
46
46
47 Indicators.ModelPrinter {
47 Indicators.ModelPrinter {
48 id: printer
48 id: printer
49− model: menuModel
49+ model: unityModel
50 }
50 }
51
51
52 Flickable {
52 Flickable {
Panel/IndicatorsDataModel.qml+39−6
@@ -27,38 +27,71 @@ Indicators.IndicatorsModel {
27 Component.onCompleted: load()
27 Component.onCompleted: load()
28
28
29 indicatorData : {
29 indicatorData : {
30+ 'indicator-bluetooth' : {
31+ 'title': 'Bluetooth',
32+ 'description' : '',
33+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
34+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
35+ },
30 'indicator-messaging' : {
36 'indicator-messaging' : {
31 'title': 'Messaging',
37 'title': 'Messaging',
32 'description' : '',
38 'description' : '',
33− 'priority': 10,
34 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorWidget.qml',
39 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorWidget.qml',
35 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorPage.qml'
40 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/MessagingIndicatorPage.qml'
36 },
41 },
37 'indicator-sound' : {
42 'indicator-sound' : {
38 'title': 'Sound',
43 'title': 'Sound',
39 'description' : '',
44 'description' : '',
40− 'priority': 20,
45+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
46+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
47+ },
48+ 'indicator-network' : {
49+ 'title': 'Networks',
50+ 'description' : '',
51+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
52+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
53+ },
54+ 'indicator-power' : {
55+ 'title': 'Battery',
56+ 'description' : '',
57+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
58+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
59+ },
60+ 'indicator-session' : {
61+ 'title': 'Session',
62+ 'description' : '',
63+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
64+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
65+ },
66+ 'indicator-datetime' : {
67+ 'title': 'Date and Time',
68+ 'description' : '',
69+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
70+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
71+ },
72+
73+ // OLD FORMAT INDICATORS
74+ 'chewie-sound' : {
75+ 'title': 'Sound',
76+ 'description' : '',
41 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/SoundIndicatorWidget.qml',
77 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/SoundIndicatorWidget.qml',
42 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
78 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
43 },
79 },
44− 'indicator-network' : {
80+ 'chewie-network' : {
45 'title': 'Networks',
81 'title': 'Networks',
46 'description' : '',
82 'description' : '',
47− 'priority': 30,
48 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorWidget.qml',
83 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorWidget.qml',
49 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage.qml'
84 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage.qml'
50 },
85 },
51 'indicator-battery' : {
86 'indicator-battery' : {
52 'title': 'Battery',
87 'title': 'Battery',
53 'description' : '',
88 'description' : '',
54− 'priority': 40,
55 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget.qml',
89 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget.qml',
56 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
90 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
57 },
91 },
58 'indicator-time' : {
92 'indicator-time' : {
59 'title': 'Date and Time',
93 'title': 'Date and Time',
60 'description' : '',
94 'description' : '',
61− 'priority': 100,
62 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorWidget.qml',
95 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorWidget.qml',
63 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorPage.qml'
96 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorPage.qml'
64 }
97 }
Panel/MenuContent.qml+78−97
@@ -19,20 +19,31 @@ import Ubuntu.Components 0.1
19import Unity.Indicators 0.1 as Indicators
19import Unity.Indicators 0.1 as Indicators
20import "../Components"
20import "../Components"
21
21
22−Rectangle {
22+// FIXME : We dont want to use MainView.
23+// Need a regular Item which can have tabs with local header.
24+// https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211704
25+MainView {
23 id: content
26 id: content
24
27
25 property QtObject indicatorsModel: null
28 property QtObject indicatorsModel: null
26 property bool __contentActive: false
29 property bool __contentActive: false
27− property alias currentMenuIndex : menus.currentIndex
30+ readonly property int currentMenuIndex : tabs.selectedTabIndex
28− property color backgroundColor: "#221e1c" // FIXME not in palette yet
31+ backgroundColor: "#221e1c" // FIXME not in palette yet
29 property int contentReleaseInterval: 20000
32 property int contentReleaseInterval: 20000
33+ property bool activeHeader: false
30
34
31 width: units.gu(40)
35 width: units.gu(40)
32 height: units.gu(42)
36 height: units.gu(42)
33− color: backgroundColor
34
37
35− signal menuSelected(int index)
38+ function setCurrentMenuIndex(index) {
39+ if (currentMenuIndex !== index) {
40+ if (currentMenuIndex == -1) {
41+ tabs.tabBar.animate = false;
42+ }
43+ tabs.selectedTabIndex = index;
44+ tabs.tabBar.animate = true;
45+ }
46+ }
36
47
37 function activateContent() {
48 function activateContent() {
38 contentReleaseTimer.stop();
49 contentReleaseTimer.stop();
@@ -40,95 +51,75 @@ Rectangle {
40 }
51 }
41
52
42 function releaseContent() {
53 function releaseContent() {
43− if (__contentActive)
54+ if (__contentActive) {
44 contentReleaseTimer.restart();
55 contentReleaseTimer.restart();
56+ }
45 }
57 }
46
58
47− ListView {
59+ onActiveHeaderChanged: {
48− id: menus
60+ tabs.tabBar.selectionMode = activeHeader;
49− objectName: "menus"
61+ tabs.tabBar.alwaysSelectionMode = activeHeader;
50−
51− anchors.bottom: parent.bottom
52− anchors.top: header.bottom
53− width: parent.width
54−
55− spacing: units.gu(0.5)
56− enabled: opacity != 0
57− orientation: ListView.Horizontal
58− model: indicatorsModel
59− interactive: false
60− //FIXME: This will make sure that all plugins still alive
61− //check bug https://bugs.launchpad.net/manhattan/+bug/1088945 for more details
62− cacheBuffer: 2147483647
63−
64− delegate: Loader {
65− clip: true
66− property bool contentActive: content.__contentActive && menuActivator.content[index].active
67−
68− onContentActiveChanged: {
69− if (contentActive && item) {
70− item.start();
71− } else if (!contentActive && item) {
72− item.stop();
73− }
74− }
62+ }
75
63
76− width: menus.width
64+ Tabs {
77− height: menus.height
65+ id: tabs
78− source: pageSource
66+ objectName: "tabs"
79− onVisibleChanged: {
67+ anchors.fill: parent
80− // Reset the indicator states
68+ selectedTabIndex: -1
81− if (!visible && item && item["reset"]) {
69+
82− item.reset();
70+ Repeater {
83− }
71+ id: repeater
72+ model: indicatorsModel
73+ objectName: "menus"
74+
75+ // FIXME: This is needed because tabs dont handle repeaters well.
76+ // Due to the child ordering happening after child insertion.
77+ // QTBUG-32438
78+ onItemAdded: {
79+ parent.childrenChanged();
84 }
80 }
85− asynchronous: true
86
81
82+ Tab {
83+ id: tab
84+ objectName: model.identifier
85+ title: model.title
86+
87+ page: Page {
88+ Loader {
89+ clip: true
90+ anchors.fill: parent
91+ source: pageSource
92+ asynchronous: true
93+
94+ property bool contentActive: content.__contentActive
95+
96+ onContentActiveChanged: {
97+ if (contentActive && item) {
98+ item.start()
99+ } else if (!contentActive && item) {
100+ item.stop()
101+ }
102+ }
103+
104+ onVisibleChanged: {
105+ // Reset the indicator states
106+ if (!visible && item && item["reset"]) {
107+ item.reset()
108+ }
109+ }
110+
87− onLoaded: {
111+ onLoaded: {
88− for(var pName in indicatorProperties) {
112+ for(var pName in indicatorProperties) {
89− if (item.hasOwnProperty(pName)) {
113+ if (item.hasOwnProperty(pName)) {
90− item[pName] = indicatorProperties[pName];
114+ item[pName] = indicatorProperties[pName]
115+ }
116+ }
117+ if (contentActive && menus.visible) {
118+ item.start()
119+ }
120+ }
91 }
121 }
92 }
122 }
93− if (contentActive && menus.visible) {
94− item.start();
95− }
96− }
97−
98− // Need to use a binding because the handle height changes.
99− // FIXME: Dont know why we're using handle height (introduces dep).. Check with design about bottom margin
100− Binding {
101− target: item
102− property: "anchors.bottomMargin"
103− value: handle.height
104− }
105− }
106− }
107−
108− Rectangle {
109− id: header
110− objectName: "header"
111−
112− property alias title: pageHeader.text
113−
114− color: backgroundColor
115− opacity: pageHeader.opacity
116− anchors {
117− left: parent.left
118− right: parent.right
119− }
120− height: childrenRect.height
121−
122− PageHeader {
123− id: pageHeader
124− anchors {
125− left: parent.left
126− right: parent.right
127− }
128− text: {
129− if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
130− return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
131− return "";
132 }
123 }
133 }
124 }
134 }
125 }
@@ -137,16 +128,6 @@ Rectangle {
137 id: contentReleaseTimer
128 id: contentReleaseTimer
138
129
139 interval: contentReleaseInterval
130 interval: contentReleaseInterval
140− onTriggered: {
141− __contentActive = false;
131+ onTriggered: content.__contentActive = false
142− menuActivator.clear();
143− }
144− }
145−
146− Indicators.MenuContentActivator {
147− id: menuActivator
148− running: content.__contentActive
149− baseIndex: content.currentMenuIndex
150− count: indicatorsModel.count
151 }
132 }
152}
133}
Shell.qml+1
@@ -404,6 +404,7 @@ FocusScope {
404
404
405 Greeter {
405 Greeter {
406 id: greeter
406 id: greeter
407+ objectName: "greeter"
407
408
408 available: true
409 available: true
409 hides: [launcher, panel.indicators, hud]
410 hides: [launcher, panel.indicators, hud]
debian/changelog+52
@@ -1,3 +1,55 @@
1+unity8 (7.81.3+13.10.20130814.3-0ubuntu1) saucy; urgency=low
2+
3+ [ Ted Gould ]
4+ * Upstart signals to control indicator services.
5+
6+ [ Nick Dedekind ]
7+ * Replaced indicator menu listView with tabs view.
8+ * Transition Unity.Indicators to UnityMenuModel.
9+
10+ [ Ubuntu daily release ]
11+ * Automatic snapshot from revision 197
12+
13+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 14 Aug 2013 14:33:39 +0000
14+
15+unity8 (7.81.3+13.10.20130814.1-0ubuntu1) saucy; urgency=low
16+
17+ [ Michał Sawicz ]
18+ * Add AppPreview.
19+
20+ [ Nick Dedekind ]
21+ * Use key from indicator service file to source indicator positions.
22+
23+ [ Diego Sarmentero ]
24+ * Add AppPreview.
25+
26+ [ Ubuntu daily release ]
27+ * Automatic snapshot from revision 193
28+
29+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 14 Aug 2013 06:33:14 +0000
30+
31+unity8 (7.81.3+13.10.20130813.1-0ubuntu1) saucy; urgency=low
32+
33+ [ Michael Zanetti ]
34+ * don't scale the EARLY ALPHA warning text bigger than the screen is.
35+
36+ [ Michał Sawicz ]
37+ * Add debug logging to passphrase entry.
38+
39+ [ Albert Astals ]
40+ * Remove unneeded stuff from CMakelists.txt set(CMAKE_AUTOMOC ON)
41+ include(FindPkgConfig) find_package(Qt5Core REQUIRED)
42+ find_package(Qt5Quick REQUIRED) Are already on the top-level
43+ CMakeLists.txt so no need to write them again Well, actually the
44+ Qt5Core wasn't and i added it, it's not really necessary since it's
45+ pulled by the others that depend on it, but it doesn't hurt to be
46+ explicit.
47+
48+ [ Ubuntu daily release ]
49+ * Automatic snapshot from revision 189
50+
51+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 13 Aug 2013 14:08:32 +0000
52+
1unity8 (7.81.3+13.10.20130812.1-0ubuntu1) saucy; urgency=low
53unity8 (7.81.3+13.10.20130812.1-0ubuntu1) saucy; urgency=low
2
54
3 [ Michael Zanetti ]
55 [ Michael Zanetti ]
debian/control+7−3
@@ -10,15 +10,19 @@ Build-Depends: cmake,
10 libgles2-mesa-dev[armhf],
10 libgles2-mesa-dev[armhf],
11 libhud-client2-dev,
11 libhud-client2-dev,
12 libjson-perl,
12 libjson-perl,
13+ libnih-dbus-dev,
14+ libnih-dev,
13 libnm-glib-dev,
15 libnm-glib-dev,
14 libnm-util-dev,
16 libnm-util-dev,
15 libpulse-dev,
17 libpulse-dev,
16− libqmenumodel-dev,
18+ libqmenumodel-dev (>= 0.2.7),
17 libqt5v8-5-private-dev,
19 libqt5v8-5-private-dev,
20+ libsigc++-2.0-dev,
18 libunity-api-dev (>= 7.80.3),
21 libunity-api-dev (>= 7.80.3),
19 libunity-core-6.0-dev (<< 7.80),
22 libunity-core-6.0-dev (<< 7.80),
20 libunity-dev (>= 7.0.3),
23 libunity-dev (>= 7.0.3),
21 libunity-scopes-json-def-phone,
24 libunity-scopes-json-def-phone,
25+ libupstart-dev,
22 libusermetricsoutput1-dev,
26 libusermetricsoutput1-dev,
23 libxcb1-dev,
27 libxcb1-dev,
24 pkg-config,
28 pkg-config,
@@ -46,7 +50,7 @@ Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
46
50
47Package: indicators-client
51Package: indicators-client
48Architecture: amd64 armhf i386
52Architecture: amd64 armhf i386
49−Depends: qmenumodel-qml,
53+Depends: qmenumodel-qml (>= 0.2.7),
50 qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
54 qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
51 unity8 (= ${binary:Version}),
55 unity8 (= ${binary:Version}),
52 ${misc:Depends},
56 ${misc:Depends},
@@ -56,7 +60,7 @@ Description: Indicators client test application
56
60
57Package: unity8
61Package: unity8
58Architecture: any
62Architecture: any
59−Depends: qmenumodel-qml,
63+Depends: qmenumodel-qml (>= 0.2.7),
60 qtdeclarative5-dee-plugin,
64 qtdeclarative5-dee-plugin,
61 qtdeclarative5-ubuntu-ui-toolkit-plugin,
65 qtdeclarative5-ubuntu-ui-toolkit-plugin,
62 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
66 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
debian/rules+2−1
@@ -8,7 +8,8 @@ export NO_PNG_PKG_MANGLE=1
8
8
9SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
9SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
10
10
11+.PHONY: build
11−%:
12+build %:
12 dh $@ --parallel --fail-missing --with python2
13 dh $@ --parallel --fail-missing --with python2
13
14
14override_dh_auto_clean:
15override_dh_auto_clean:
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+46−11
@@ -280,7 +280,7 @@ void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
280
280
281 m_sectionDelegate = delegate;
281 m_sectionDelegate = delegate;
282
282
283− m_topSectionItem = getSectionItem(-1, QString());
283+ m_topSectionItem = getSectionItem(QString());
284 m_topSectionItem->setZ(3);
284 m_topSectionItem->setZ(3);
285 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
285 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
286
286
@@ -380,20 +380,51 @@ void ListViewWithPageHeader::showHeader()
380 }
380 }
381}
381}
382
382
383+QQuickItem *ListViewWithPageHeader::item(int modelIndex) const
384+{
385+ ListItem *item = itemAtIndex(modelIndex);
386+ if (item)
387+ return item->m_item;
388+ else
389+ return nullptr;
390+}
391+
383bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex)
392bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex)
384{
393{
385 ListItem *listItem = itemAtIndex(modelIndex);
394 ListItem *listItem = itemAtIndex(modelIndex);
386− if (listItem)
395+ if (listItem) {
387− {
396+ return maximizeVisibleArea(listItem, listItem->height());
397+ }
398+
399+ return false;
400+}
401+
402+bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex, int itemHeight)
403+{
404+ if (itemHeight < 0)
405+ return false;
406+
407+ ListItem *listItem = itemAtIndex(modelIndex);
408+ if (listItem) {
409+ return maximizeVisibleArea(listItem, itemHeight + (listItem->m_sectionItem ? listItem->m_sectionItem->height() : 0));
410+ }
411+
412+ return false;
413+}
414+
415+bool ListViewWithPageHeader::maximizeVisibleArea(ListItem *listItem, int listItemHeight)
416+{
417+ if (listItem) {
418+ layout();
388 const auto listItemY = m_clipItem->y() + listItem->y();
419 const auto listItemY = m_clipItem->y() + listItem->y();
389− if (listItemY > contentY() && listItemY + listItem->height() > contentY() + height()) {
420+ if (listItemY > contentY() && listItemY + listItemHeight > contentY() + height()) {
390 // we can scroll the list up to show more stuff
421 // we can scroll the list up to show more stuff
391− const auto to = qMin(listItemY, listItemY + listItem->height() - height());
422+ const auto to = qMin(listItemY, listItemY + listItemHeight - height());
392 m_contentYAnimation->setTo(to);
423 m_contentYAnimation->setTo(to);
393 contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
424 contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
394 m_contentYAnimation->start();
425 m_contentYAnimation->start();
395− } else if ((listItemY < contentY() && listItemY + listItem->height() < contentY() + height()) ||
426+ } else if ((listItemY < contentY() && listItemY + listItemHeight < contentY() + height()) ||
396− (m_topSectionItem && !listItem->m_sectionItem && listItemY - m_topSectionItem->height() < contentY() && listItemY + listItem->height() < contentY() + height()))
427+ (m_topSectionItem && !listItem->m_sectionItem && listItemY - m_topSectionItem->height() < contentY() && listItemY + listItemHeight < contentY() + height()))
397 {
428 {
398 // we can scroll the list down to show more stuff
429 // we can scroll the list down to show more stuff
399 auto realVisibleListItemY = listItemY;
430 auto realVisibleListItemY = listItemY;
@@ -406,7 +437,7 @@ bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex)
406 realVisibleListItemY -= m_topSectionItem->height();
437 realVisibleListItemY -= m_topSectionItem->height();
407 }
438 }
408 }
439 }
409− const auto to = qMax(realVisibleListItemY, listItemY + listItem->height() - height());
440+ const auto to = qMax(realVisibleListItemY, listItemY + listItemHeight - height());
410 m_contentYAnimation->setTo(to);
441 m_contentYAnimation->setTo(to);
411 contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
442 contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
412 m_contentYAnimation->start();
443 m_contentYAnimation->start();
@@ -641,17 +672,17 @@ QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyI
641 }
672 }
642 }
673 }
643
674
644− return getSectionItem(modelIndex, section);
675+ return getSectionItem(section);
645}
676}
646
677
647−QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, const QString &sectionText)
678+QQuickItem *ListViewWithPageHeader::getSectionItem(const QString &sectionText)
648{
679{
649 QQuickItem *sectionItem = nullptr;
680 QQuickItem *sectionItem = nullptr;
650
681
651 QQmlContext *creationContext = m_sectionDelegate->creationContext();
682 QQmlContext *creationContext = m_sectionDelegate->creationContext();
652 QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
683 QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
653 context->setContextProperty(QLatin1String("section"), sectionText);
684 context->setContextProperty(QLatin1String("section"), sectionText);
654− context->setContextProperty(QLatin1String("delegateIndex"), modelIndex);
685+ context->setContextProperty(QLatin1String("delegateIndex"), -1);
655 QObject *nobj = m_sectionDelegate->beginCreate(context);
686 QObject *nobj = m_sectionDelegate->beginCreate(context);
656 if (nobj) {
687 if (nobj) {
657 QQml_setParent_noEvent(context, nobj);
688 QQml_setParent_noEvent(context, nobj);
@@ -786,6 +817,10 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
786 m_firstVisibleIndex = modelIndex;
817 m_firstVisibleIndex = modelIndex;
787 polish();
818 polish();
788 }
819 }
820+ if (listItem->m_sectionItem) {
821+ QQmlContext *context = QQmlEngine::contextForObject(listItem->m_sectionItem)->parentContext();
822+ context->setContextProperty(QLatin1String("delegateIndex"), modelIndex);
823+ }
789 adjustMinYExtent();
824 adjustMinYExtent();
790 m_contentHeightDirty = true;
825 m_contentHeightDirty = true;
791 }
826 }
plugins/ListViewWithPageHeader/listviewwithpageheader.h+5−1
@@ -88,11 +88,13 @@ public:
88
88
89 Q_INVOKABLE void positionAtBeginning();
89 Q_INVOKABLE void positionAtBeginning();
90 Q_INVOKABLE void showHeader();
90 Q_INVOKABLE void showHeader();
91+ Q_INVOKABLE QQuickItem *item(int modelIndex) const;
91
92
92 // The index has to be created for this to try to do something
93 // The index has to be created for this to try to do something
93 // Created items are those visible and the precached ones
94 // Created items are those visible and the precached ones
94 // Returns if the item existed or not
95 // Returns if the item existed or not
95 Q_INVOKABLE bool maximizeVisibleArea(int modelIndex);
96 Q_INVOKABLE bool maximizeVisibleArea(int modelIndex);
97+ Q_INVOKABLE bool maximizeVisibleArea(int modelIndex, int itemHeight);
96
98
97Q_SIGNALS:
99Q_SIGNALS:
98 void modelChanged();
100 void modelChanged();
@@ -141,6 +143,8 @@ private:
141 QQuickItem *m_sectionItem;
143 QQuickItem *m_sectionItem;
142 };
144 };
143
145
146+ bool maximizeVisibleArea(ListItem *listItem, int listItemHeight);
147+
144 void createDelegateModel();
148 void createDelegateModel();
145
149
146 void layout();
150 void layout();
@@ -157,7 +161,7 @@ private:
157 void reallyReleaseItem(ListItem *item);
161 void reallyReleaseItem(ListItem *item);
158 void updateWatchedRoles();
162 void updateWatchedRoles();
159 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
163 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
160− QQuickItem *getSectionItem(int modelIndex, const QString &sectionText);
164+ QQuickItem *getSectionItem(const QString &sectionText);
161
165
162#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
166#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
163 QQuickVisualDataModel *m_delegateModel;
167 QQuickVisualDataModel *m_delegateModel;
plugins/Ubuntu/CMakeLists.txt+1
@@ -1 +1,2 @@
1add_subdirectory(Gestures)
1add_subdirectory(Gestures)
2+add_subdirectory(DownloadDaemonListener)
plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txtnew file+22
@@ -0,0 +1,22 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+include_directories(
5+ ${CMAKE_CURRENT_SOURCE_DIR}
6+ ${CMAKE_CURRENT_BINARY_DIR}
7+ ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
8+)
9+
10+set(DOWNLOADDAEMONLISTENER_SOURCES
11+ plugin.cpp
12+ DownloadTracker.cpp
13+ interface/downloadtrackeradaptor.cpp
14+ )
15+
16+add_library(DownloadDaemonListener MODULE ${DOWNLOADDAEMONLISTENER_SOURCES})
17+
18+qt5_use_modules(DownloadDaemonListener Qml Quick DBus Core)
19+
20+# export the qmldir qmltypes and plugin files
21+export_qmlfiles(Ubuntu.DownloadDaemonListener Ubuntu/DownloadDaemonListener)
22+export_qmlplugin(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS DownloadDaemonListener)
plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cppnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
19+ */
20+
21+
22+#include "DownloadTracker.h"
23+
24+DownloadTracker::DownloadTracker(QObject *parent)
25+ : QObject(parent)
26+ , m_adaptor(nullptr)
27+{
28+}
29+
30+bool DownloadTracker::isServiceReady() const
31+{
32+ bool ready = false;
33+ if(m_adaptor != nullptr) {
34+ ready = m_adaptor->isValid();
35+ }
36+
37+ return ready;
38+}
39+
40+QString DownloadTracker::dbusPath() const
41+{
42+ return m_dbusPath;
43+}
44+
45+void DownloadTracker::setDbusPath(const QString& path)
46+{
47+ if(m_dbusPath != path){
48+ m_dbusPath = path;
49+ startService();
50+ Q_EMIT dbusPathChanged(m_dbusPath);
51+ }
52+}
53+
54+QString DownloadTracker::service() const
55+{
56+ return m_service;
57+}
58+
59+void DownloadTracker::setService(const QString& service)
60+{
61+ if(m_service != service){
62+ m_service = service;
63+ startService();
64+ Q_EMIT serviceChanged(m_service);
65+ }
66+}
67+
68+void DownloadTracker::startService()
69+{
70+ // FIXME update dbus path and service on changes
71+ if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
72+ m_adaptor = new DownloadTrackerAdaptor(m_service, m_dbusPath, QDBusConnection::sessionBus(), this);
73+
74+ connect(m_adaptor, SIGNAL(canceled(bool)), this, SIGNAL(canceled(bool)));
75+ connect(m_adaptor, SIGNAL(error(const QString &)), this, SIGNAL(error(const QString &)));
76+ connect(m_adaptor, SIGNAL(finished(const QString &)), this, SIGNAL(finished(const QString &)));
77+ connect(m_adaptor, SIGNAL(paused(bool)), this, SIGNAL(paused(bool)));
78+ connect(m_adaptor, SIGNAL(progress(qulonglong, qulonglong)), this, SIGNAL(progress(qulonglong, qulonglong)));
79+ connect(m_adaptor, SIGNAL(resumed(bool)), this, SIGNAL(resumed(bool)));
80+ connect(m_adaptor, SIGNAL(started(bool)), this, SIGNAL(started(bool)));
81+ }
82+ // FIXME find a better way of determining if the service is ready
83+ Q_EMIT serviceReadyChanged(m_adaptor && m_adaptor->isValid());
84+}
plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.hnew file+69
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
19+ */
20+
21+
22+#ifndef DOWNLOADTRACKER_H
23+#define DOWNLOADTRACKER_H
24+
25+#include <interface/downloadtrackeradaptor.h>
26+
27+#include <QObject>
28+#include <QDBusObjectPath>
29+
30+class DownloadTracker : public QObject
31+{
32+ Q_OBJECT
33+ Q_DISABLE_COPY(DownloadTracker)
34+ Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged)
35+ Q_PROPERTY(QString dbusPath READ dbusPath WRITE setDbusPath NOTIFY dbusPathChanged)
36+ Q_PROPERTY(bool serviceReady READ isServiceReady NOTIFY serviceReadyChanged)
37+
38+public:
39+ explicit DownloadTracker(QObject *parent = 0);
40+
41+ QString service() const;
42+ QString dbusPath() const;
43+ bool isServiceReady() const;
44+
45+ void setDbusPath(const QString& path);
46+ void setService(const QString& service);
47+
48+Q_SIGNALS:
49+ void serviceChanged(const QString &service);
50+ void dbusPathChanged(const QString &dbusPath);
51+ void serviceReadyChanged(const bool &serviceReady);
52+
53+ void canceled(bool success);
54+ void error(const QString &error);
55+ void finished(const QString &path);
56+ void paused(bool success);
57+ void progress(qulonglong received, qulonglong total);
58+ void resumed(bool success);
59+ void started(bool success);
60+
61+private:
62+ QString m_dbusPath;
63+ QString m_service;
64+ DownloadTrackerAdaptor* m_adaptor;
65+
66+ void startService();
67+};
68+
69+#endif // DOWNLOADTRACKER_H
plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cppnew file+25
@@ -0,0 +1,25 @@
1+/*
2+ * This file was generated by qdbusxml2cpp version 0.8
3+ * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h com.canonical.applications.download.xml
4+ *
5+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
6+ *
7+ * This is an auto-generated file.
8+ * This file may have been hand-edited. Look for HAND-EDIT comments
9+ * before re-generating it.
10+ */
11+
12+#include "downloadtrackeradaptor.h"
13+
14+/*
15+ * Implementation of interface class DownloadTrackerAdaptor
16+ */
17+
18+DownloadTrackerAdaptor::DownloadTrackerAdaptor(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
19+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
20+{
21+}
22+
23+DownloadTrackerAdaptor::~DownloadTrackerAdaptor()
24+{
25+}
plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.hnew file+125
@@ -0,0 +1,125 @@
1+/*
2+ * This file was generated by qdbusxml2cpp version 0.8
3+ * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h com.canonical.applications.download.xml
4+ *
5+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
6+ *
7+ * This is an auto-generated file.
8+ * Do not edit! All changes made to it will be lost.
9+ */
10+
11+#ifndef DOWNLOADTRACKERADAPTOR_H_1374434371
12+#define DOWNLOADTRACKERADAPTOR_H_1374434371
13+
14+#include <QtCore/QObject>
15+#include <QtCore/QByteArray>
16+#include <QtCore/QList>
17+#include <QtCore/QMap>
18+#include <QtCore/QString>
19+#include <QtCore/QStringList>
20+#include <QtCore/QVariant>
21+#include <QtDBus/QtDBus>
22+#include "metatypes.h"
23+
24+/*
25+ * Proxy class for interface com.canonical.applications.Download
26+ */
27+class DownloadTrackerAdaptor: public QDBusAbstractInterface
28+{
29+ Q_OBJECT
30+public:
31+ static inline const char *staticInterfaceName()
32+ { return "com.canonical.applications.Download"; }
33+
34+public:
35+ DownloadTrackerAdaptor(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
36+
37+ ~DownloadTrackerAdaptor();
38+
39+public Q_SLOTS: // METHODS
40+ inline QDBusPendingReply<> allowGSMDownload(bool allowed)
41+ {
42+ QList<QVariant> argumentList;
43+ argumentList << QVariant::fromValue(allowed);
44+ return asyncCallWithArgumentList(QLatin1String("allowGSMDownload"), argumentList);
45+ }
46+
47+ inline QDBusPendingReply<> cancel()
48+ {
49+ QList<QVariant> argumentList;
50+ return asyncCallWithArgumentList(QLatin1String("cancel"), argumentList);
51+ }
52+
53+ inline QDBusPendingReply<bool> isGSMDownloadAllowed()
54+ {
55+ QList<QVariant> argumentList;
56+ return asyncCallWithArgumentList(QLatin1String("isGSMDownloadAllowed"), argumentList);
57+ }
58+
59+ inline QDBusPendingReply<QVariantMap> metadata()
60+ {
61+ QList<QVariant> argumentList;
62+ return asyncCallWithArgumentList(QLatin1String("metadata"), argumentList);
63+ }
64+
65+ inline QDBusPendingReply<> pause()
66+ {
67+ QList<QVariant> argumentList;
68+ return asyncCallWithArgumentList(QLatin1String("pause"), argumentList);
69+ }
70+
71+ inline QDBusPendingReply<qulonglong> progress()
72+ {
73+ QList<QVariant> argumentList;
74+ return asyncCallWithArgumentList(QLatin1String("progress"), argumentList);
75+ }
76+
77+ inline QDBusPendingReply<> resume()
78+ {
79+ QList<QVariant> argumentList;
80+ return asyncCallWithArgumentList(QLatin1String("resume"), argumentList);
81+ }
82+
83+ inline QDBusPendingReply<> setThrottle(qulonglong speed)
84+ {
85+ QList<QVariant> argumentList;
86+ argumentList << QVariant::fromValue(speed);
87+ return asyncCallWithArgumentList(QLatin1String("setThrottle"), argumentList);
88+ }
89+
90+ inline QDBusPendingReply<> start()
91+ {
92+ QList<QVariant> argumentList;
93+ return asyncCallWithArgumentList(QLatin1String("start"), argumentList);
94+ }
95+
96+ inline QDBusPendingReply<qulonglong> throttle()
97+ {
98+ QList<QVariant> argumentList;
99+ return asyncCallWithArgumentList(QLatin1String("throttle"), argumentList);
100+ }
101+
102+ inline QDBusPendingReply<qulonglong> totalSize()
103+ {
104+ QList<QVariant> argumentList;
105+ return asyncCallWithArgumentList(QLatin1String("totalSize"), argumentList);
106+ }
107+
108+Q_SIGNALS: // SIGNALS
109+ void canceled(bool success);
110+ void error(const QString &error);
111+ void finished(const QString &path);
112+ void paused(bool success);
113+ void progress(qulonglong received, qulonglong total);
114+ void resumed(bool success);
115+ void started(bool success);
116+};
117+
118+namespace com {
119+ namespace canonical {
120+ namespace applications {
121+ typedef ::DownloadTrackerAdaptor Download;
122+ }
123+ }
124+}
125+#endif
plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.hnew file+28
@@ -0,0 +1,28 @@
1+/*
2+ * Copyright 2013 2013 Canonical Ltd.
3+ *
4+ * This library is free software; you can redistribute it and/or
5+ * modify it under the terms of version 3 of the GNU Lesser General Public
6+ * License as published by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public
14+ * License along with this library; if not, write to the
15+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16+ * Boston, MA 02110-1301, USA.
17+ */
18+
19+#ifndef DOWNLOADER_LIB_APP_METATYPES_H
20+#define DOWNLOADER_LIB_APP_METATYPES_H
21+
22+#include <QMap>
23+
24+typedef QMap<QString, QString> StringMap;
25+
26+Q_DECLARE_METATYPE(StringMap)
27+
28+#endif // METATYPES_H
plugins/Ubuntu/DownloadDaemonListener/plugin.cppnew file+39
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
19+ */
20+
21+
22+#include "plugin.h"
23+#include "DownloadTracker.h"
24+
25+#include <QtQml>
26+#include <QtQml/QQmlContext>
27+
28+
29+void BackendPlugin::registerTypes(const char *uri)
30+{
31+ Q_ASSERT(uri == QLatin1String("Ubuntu.DownloadDaemonListener"));
32+
33+ qmlRegisterType<DownloadTracker>(uri, 0, 1, "DownloadTracker");
34+}
35+
36+void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
37+{
38+ QQmlExtensionPlugin::initializeEngine(engine, uri);
39+}
plugins/Ubuntu/DownloadDaemonListener/plugin.hnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
19+ */
20+
21+
22+#ifndef BACKEND_PLUGIN_H
23+#define BACKEND_PLUGIN_H
24+
25+#include <QQmlEngine>
26+#include <QQmlExtensionPlugin>
27+
28+class BackendPlugin : public QQmlExtensionPlugin
29+{
30+ Q_OBJECT
31+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
32+
33+public:
34+ void registerTypes(const char *uri);
35+ void initializeEngine(QQmlEngine *engine, const char *uri);
36+};
37+#endif // BACKEND_PLUGIN_H
plugins/Ubuntu/DownloadDaemonListener/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Ubuntu.DownloadDaemonListener
2+plugin DownloadDaemonListener
3+typeinfo plugins.qmltypes
plugins/Unity/CMakeLists.txt+15−1
@@ -2,6 +2,7 @@
2include(Plugins)
2include(Plugins)
3
3
4add_subdirectory(Indicators)
4add_subdirectory(Indicators)
5+add_subdirectory(IndicatorsLegacy)
5
6
6# Dependencies
7# Dependencies
7include(FindPkgConfig)
8include(FindPkgConfig)
@@ -17,11 +18,23 @@ include_directories(
17)
18)
18
19
19set(QMLPLUGIN_SRC
20set(QMLPLUGIN_SRC
21+ abstractfilteroption.cpp
20 scope.cpp
22 scope.cpp
21 scopes.cpp
23 scopes.cpp
22 categories.cpp
24 categories.cpp
25+ checkoptionfilter.cpp
26+ filter.cpp
27+ filteroption.cpp
28+ filters.cpp
29+ genericoptionsmodel.cpp
30+ ratingoptionsmodel.cpp
31+ unityoptionsmodel.cpp
23 categoryresults.cpp
32 categoryresults.cpp
24 plugin.cpp
33 plugin.cpp
34+ multirangefilter.cpp
35+ radiooptionfilter.cpp
36+ ratingsfilter.cpp
37+ ratingfilteroption.cpp
25 bottombarvisibilitycommunicatorshell.cpp
38 bottombarvisibilitycommunicatorshell.cpp
26 applicationpreview.cpp
39 applicationpreview.cpp
27 genericpreview.cpp
40 genericpreview.cpp
@@ -30,10 +43,11 @@ set(QMLPLUGIN_SRC
30 preview.cpp
43 preview.cpp
31 previewaction.cpp
44 previewaction.cpp
32 previewinfohint.cpp
45 previewinfohint.cpp
46+ signalslist.cpp
33 socialpreview.cpp
47 socialpreview.cpp
34 socialpreviewcomment.cpp
48 socialpreviewcomment.cpp
35 variantutils.cpp
49 variantutils.cpp
36− )
50+)
37
51
38add_library(Unity-qml MODULE
52add_library(Unity-qml MODULE
39 ${QMLPLUGIN_SRC}
53 ${QMLPLUGIN_SRC}
plugins/Unity/Indicators/CMakeLists.txt+13−11
@@ -3,22 +3,26 @@ include(Plugins)
3
3
4project(IndicatorsQml)
4project(IndicatorsQml)
5
5
6+pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
7+pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
6pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
8pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
9+pkg_check_modules(LIBUPSTART REQUIRED libupstart libnih libnih-dbus dbus-1)
10+
7find_package(Qt5Core REQUIRED)
11find_package(Qt5Core REQUIRED)
8find_package(Qt5Quick REQUIRED)
12find_package(Qt5Quick REQUIRED)
9
13
10add_subdirectory(qml)
14add_subdirectory(qml)
11−add_subdirectory(Messaging)
12−add_subdirectory(Network)
13
15
14include_directories(
16include_directories(
15 ${CMAKE_CURRENT_SOURCE_DIR}
17 ${CMAKE_CURRENT_SOURCE_DIR}
16 ${CMAKE_CURRENT_BINARY_DIR}
18 ${CMAKE_CURRENT_BINARY_DIR}
19+ ${GLIB_INCLUDE_DIRS}
20+ ${GIO_INCLUDE_DIRS}
17 ${QMENUMODEL_INCLUDE_DIRS}
21 ${QMENUMODEL_INCLUDE_DIRS}
22+ ${LIBUPSTART_INCLUDE_DIRS}
18)
23)
19
24
20set(IndicatorsQML_SOURCES
25set(IndicatorsQML_SOURCES
21− flatmenuproxymodel.cpp
22 indicator.cpp
26 indicator.cpp
23 indicators.h
27 indicators.h
24 indicatorsmanager.cpp
28 indicatorsmanager.cpp
@@ -26,24 +30,22 @@ set(IndicatorsQML_SOURCES
26 menucontentactivator.cpp
30 menucontentactivator.cpp
27 modelprinter.cpp
31 modelprinter.cpp
28 plugin.cpp
32 plugin.cpp
33+ rootactionstate.cpp
34+ unitymenumodelcache.cpp
35+ unitymenumodelstack.cpp
29)
36)
30add_definitions(-DUNITYINDICATORS_LIBRARY)
37add_definitions(-DUNITYINDICATORS_LIBRARY)
31
38
32−set(IndicatorsQML_RESOURCES
33− resources/indicators.qrc
34−)
35−
36−qt5_add_resources(IndicatorsQML_RESOURCES_RCC
37− ${IndicatorsQML_RESOURCES}
38−)
39
39
40add_library(IndicatorsQml SHARED
40add_library(IndicatorsQml SHARED
41− ${IndicatorsQML_RESOURCES_RCC}
42 ${IndicatorsQML_SOURCES}
41 ${IndicatorsQML_SOURCES}
43)
42)
44
43
45target_link_libraries(IndicatorsQml
44target_link_libraries(IndicatorsQml
45+ ${GLIB_LIBRARIES}
46+ ${GIO_LIBRARIES}
46 ${QMENUMODEL_LDFLAGS}
47 ${QMENUMODEL_LDFLAGS}
48+ ${LIBUPSTART_LIBRARIES}
47)
49)
48
50
49qt5_use_modules(IndicatorsQml Core Qml Quick)
51qt5_use_modules(IndicatorsQml Core Qml Quick)
plugins/Unity/Indicators/Messaging/qml/CMakeLists.txtdeleted−5
@@ -1,5 +0,0 @@
1−# export_qmlfiles macro
2−include(Plugins)
3−
4−# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.Indicators.Messaging Unity/Indicators/Messaging)
plugins/Unity/Indicators/indicator.cpp+16−1
@@ -22,7 +22,8 @@
22#include <QStringList>
22#include <QStringList>
23
23
24Indicator::Indicator(QObject *parent)
24Indicator::Indicator(QObject *parent)
25− : QObject(parent)
25+ : QObject(parent),
26+ m_position(0)
26{
27{
27}
28}
28
29
@@ -33,6 +34,7 @@ Indicator::~Indicator()
33void Indicator::init(const QString& busName, const QSettings& settings)
34void Indicator::init(const QString& busName, const QSettings& settings)
34{
35{
35 setId(settings.value("Indicator Service/Name").toString());
36 setId(settings.value("Indicator Service/Name").toString());
37+ setPosition(settings.value("Indicator Service/Position", QVariant::fromValue(0)).toInt());
36
38
37 QString actionObjectPath = settings.value("Indicator Service/ObjectPath").toString();
39 QString actionObjectPath = settings.value("Indicator Service/ObjectPath").toString();
38
40
@@ -72,6 +74,19 @@ void Indicator::setId(const QString &identifier)
72 }
74 }
73}
75}
74
76
77+int Indicator::position() const
78+{
79+ return m_position;
80+}
81+
82+void Indicator::setPosition(int position)
83+{
84+ if (position != m_position) {
85+ m_position = position;
86+ Q_EMIT positionChanged(m_position);
87+ }
88+}
89+
75
90
76QVariant Indicator::indicatorProperties() const
91QVariant Indicator::indicatorProperties() const
77{
92{
plugins/Unity/Indicators/indicator.h+5
@@ -30,6 +30,7 @@ class UNITYINDICATORS_EXPORT Indicator : public QObject
30{
30{
31 Q_OBJECT
31 Q_OBJECT
32 Q_PROPERTY(QString identifier READ identifier NOTIFY identifierChanged)
32 Q_PROPERTY(QString identifier READ identifier NOTIFY identifierChanged)
33+ Q_PROPERTY(int position READ position NOTIFY positionChanged)
33 Q_PROPERTY(QVariant indicatorProperties READ indicatorProperties NOTIFY indicatorPropertiesChanged)
34 Q_PROPERTY(QVariant indicatorProperties READ indicatorProperties NOTIFY indicatorPropertiesChanged)
34
35
35public:
36public:
@@ -41,18 +42,22 @@ public:
41 void init(const QString& busName, const QSettings& settings);
42 void init(const QString& busName, const QSettings& settings);
42
43
43 QString identifier() const;
44 QString identifier() const;
45+ int position() const;
44 QVariant indicatorProperties() const;
46 QVariant indicatorProperties() const;
45
47
46Q_SIGNALS:
48Q_SIGNALS:
47 void identifierChanged(const QString &identifier);
49 void identifierChanged(const QString &identifier);
50+ void positionChanged(int position);
48 void indicatorPropertiesChanged(const QVariant &properties);
51 void indicatorPropertiesChanged(const QVariant &properties);
49
52
50protected:
53protected:
51 void setId(const QString &id);
54 void setId(const QString &id);
55+ void setPosition(int position);
52 void setIndicatorProperties(const QVariant &properties);
56 void setIndicatorProperties(const QVariant &properties);
53
57
54private:
58private:
55 QString m_identifier;
59 QString m_identifier;
60+ int m_position;
56 QVariant m_properties;
61 QVariant m_properties;
57};
62};
58
63
plugins/Unity/Indicators/indicators.h+1−1
@@ -73,7 +73,7 @@ public:
73 Q_ENUMS(Roles)
73 Q_ENUMS(Roles)
74 enum Roles {
74 enum Roles {
75 Identifier = 0,
75 Identifier = 0,
76− Priority,
76+ Position,
77 Title,
77 Title,
78 Description,
78 Description,
79 WidgetSource,
79 WidgetSource,
plugins/Unity/Indicators/indicatorsmanager.cpp+40−1
@@ -21,6 +21,9 @@
21#include <QSettings>
21#include <QSettings>
22#include <QDebug>
22#include <QDebug>
23
23
24+#include <upstart.h>
25+#include <nih/alloc.h>
26+
24#include "paths.h"
27#include "paths.h"
25
28
26
29
@@ -31,7 +34,8 @@ public:
31 : m_name(name)
34 : m_name(name)
32 , m_fileInfo(fileInfo)
35 , m_fileInfo(fileInfo)
33 , m_verified (true)
36 , m_verified (true)
34− {}
37+ {
38+ }
35
39
36 QString m_name;
40 QString m_name;
37 QFileInfo m_fileInfo;
41 QFileInfo m_fileInfo;
@@ -43,12 +47,34 @@ public:
43IndicatorsManager::IndicatorsManager(QObject* parent)
47IndicatorsManager::IndicatorsManager(QObject* parent)
44 : QObject(parent)
48 : QObject(parent)
45 , m_loaded(false)
49 , m_loaded(false)
50+ , m_upstart(NULL)
46{
51{
52+ auto upstartsession = qgetenv("UPSTART_SESSION");
53+ if (!upstartsession.isNull()) {
54+ DBusConnection * conn = NULL;
55+ conn = dbus_connection_open(upstartsession.constData(), NULL);
56+ if (conn != NULL) {
57+ m_upstart = nih_dbus_proxy_new(NULL, conn,
58+ NULL,
59+ DBUS_PATH_UPSTART,
60+ NULL, NULL);
61+ dbus_connection_unref(conn);
62+ }
63+ }
64+
65+ if (m_upstart != NULL) {
66+ m_upstart->auto_start = FALSE;
67+ }
47}
68}
48
69
49IndicatorsManager::~IndicatorsManager()
70IndicatorsManager::~IndicatorsManager()
50{
71{
51 unload();
72 unload();
73+
74+ if (m_upstart != NULL) {
75+ nih_unref(m_upstart, NULL);
76+ m_upstart = NULL;
77+ }
52}
78}
53
79
54void IndicatorsManager::load()
80void IndicatorsManager::load()
@@ -208,6 +234,19 @@ void IndicatorsManager::setLoaded(bool loaded)
208 {
234 {
209 m_loaded = loaded;
235 m_loaded = loaded;
210 Q_EMIT loadedChanged(m_loaded);
236 Q_EMIT loadedChanged(m_loaded);
237+
238+ if (m_upstart != NULL) {
239+ int event_sent = 0;
240+ if (m_loaded) {
241+ event_sent = upstart_emit_event_sync(NULL, m_upstart, "indicator-services-start", NULL, 0);
242+ } else {
243+ event_sent = upstart_emit_event_sync(NULL, m_upstart, "indicator-services-end", NULL, 0);
244+ }
245+
246+ if (event_sent != 0) {
247+ qWarning() << "Unable to send indicator event to Upstart";
248+ }
249+ }
211 }
250 }
212}
251}
213
252
plugins/Unity/Indicators/indicatorsmanager.h+3
@@ -28,6 +28,8 @@
28#include <QHash>
28#include <QHash>
29#include <QSharedPointer>
29#include <QSharedPointer>
30
30
31+typedef struct nih_dbus_proxy NihDBusProxy;
32+
31class UNITYINDICATORS_EXPORT IndicatorsManager : public QObject
33class UNITYINDICATORS_EXPORT IndicatorsManager : public QObject
32{
34{
33 Q_OBJECT
35 Q_OBJECT
@@ -69,6 +71,7 @@ private:
69 QHash<QString, IndicatorData*> m_indicatorsData;
71 QHash<QString, IndicatorData*> m_indicatorsData;
70 QSharedPointer<QFileSystemWatcher> m_fsWatcher;
72 QSharedPointer<QFileSystemWatcher> m_fsWatcher;
71 bool m_loaded;
73 bool m_loaded;
74+ NihDBusProxy * m_upstart;
72};
75};
73
76
74#endif // INDICATORS_MANAGER_H
77#endif // INDICATORS_MANAGER_H
plugins/Unity/Indicators/indicatorsmodel.cpp+10−5
@@ -118,8 +118,8 @@ void IndicatorsModel::onIndicatorLoaded(const QString& indicator_name)
118 int pos = 0;
118 int pos = 0;
119 while (pos < count())
119 while (pos < count())
120 {
120 {
121− // keep going while the existing priority is less.
121+ // keep going while the existing position is greater. (put lower position on end)
122− if (indicatorData(indicator, IndicatorsModelRole::Priority).toInt() < data(index(pos), IndicatorsModelRole::Priority).toInt())
122+ if (indicator->position() >= data(index(pos), IndicatorsModelRole::Position).toInt())
123 break;
123 break;
124 pos++;
124 pos++;
125 }
125 }
@@ -200,7 +200,7 @@ QHash<int, QByteArray> IndicatorsModel::roleNames() const
200 if (roles.isEmpty())
200 if (roles.isEmpty())
201 {
201 {
202 roles[IndicatorsModelRole::Identifier] = "identifier";
202 roles[IndicatorsModelRole::Identifier] = "identifier";
203− roles[IndicatorsModelRole::Priority] = "priority";
203+ roles[IndicatorsModelRole::Position] = "position";
204 roles[IndicatorsModelRole::Title] = "title";
204 roles[IndicatorsModelRole::Title] = "title";
205 roles[IndicatorsModelRole::Description] = "description";
205 roles[IndicatorsModelRole::Description] = "description";
206 roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
206 roles[IndicatorsModelRole::WidgetSource] = "widgetSource";
@@ -222,7 +222,7 @@ QVariant IndicatorsModel::defaultData(Indicator::Ptr indicator, int role)
222{
222{
223 switch (role)
223 switch (role)
224 {
224 {
225− case IndicatorsModelRole::Priority:
225+ case IndicatorsModelRole::Position:
226 return 0;
226 return 0;
227 case IndicatorsModelRole::Title:
227 case IndicatorsModelRole::Title:
228 return indicator ? indicator->identifier() : "Unknown";
228 return indicator ? indicator->identifier() : "Unknown";
@@ -257,6 +257,12 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
257 return QVariant(indicator->identifier());
257 return QVariant(indicator->identifier());
258 }
258 }
259 break;
259 break;
260+ case IndicatorsModelRole::Position:
261+ if (indicator)
262+ {
263+ return QVariant(indicator->position());
264+ }
265+ break;
260 case IndicatorsModelRole::IndicatorProperties:
266 case IndicatorsModelRole::IndicatorProperties:
261 if (indicator)
267 if (indicator)
262 {
268 {
@@ -265,7 +271,6 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
265 break;
271 break;
266 case IndicatorsModelRole::IsValid:
272 case IndicatorsModelRole::IsValid:
267 return (indicator ? true : false);
273 return (indicator ? true : false);
268− case IndicatorsModelRole::Priority:
269 case IndicatorsModelRole::Title:
274 case IndicatorsModelRole::Title:
270 case IndicatorsModelRole::Description:
275 case IndicatorsModelRole::Description:
271 case IndicatorsModelRole::WidgetSource:
276 case IndicatorsModelRole::WidgetSource:
plugins/Unity/Indicators/modelprinter.cpp+66−43
@@ -20,6 +20,8 @@
20// self
20// self
21#include "modelprinter.h"
21#include "modelprinter.h"
22
22
23+#include <unitymenumodel.h>
24+
23// Qt
25// Qt
24#include <QTextStream>
26#include <QTextStream>
25
27
@@ -29,7 +31,7 @@ ModelPrinter::ModelPrinter(QObject *parent)
29{
31{
30}
32}
31
33
32−void ModelPrinter::setSourceModel(QAbstractItemModel * sourceModel)
34+void ModelPrinter::setSourceModel(UnityMenuModel * sourceModel)
33{
35{
34 if (m_model != NULL) {
36 if (m_model != NULL) {
35 disconnect(m_model);
37 disconnect(m_model);
@@ -40,75 +42,96 @@ void ModelPrinter::setSourceModel(QAbstractItemModel * sourceModel)
40 Q_EMIT textChanged();
42 Q_EMIT textChanged();
41 }
43 }
42 if (m_model != NULL) {
44 if (m_model != NULL) {
43− connect(m_model, SIGNAL(modelReset()), this, SIGNAL(textChanged()));
44− connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(textChanged()));
45+ connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(textChanged()));
45− connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(textChanged()));
46+ connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(textChanged()));
47+ connect(m_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SIGNAL(textChanged()));
46 }
48 }
47}
49}
48
50
49−QAbstractItemModel* ModelPrinter::sourceModel() const
51+UnityMenuModel* ModelPrinter::sourceModel() const
50{
52{
51 return m_model;
53 return m_model;
52}
54}
53
55
54−QString ModelPrinter::text(const QModelIndex& index) const
56+QString ModelPrinter::text()
55{
57{
56− return recurseString(index, 0);
58+ return getModelDataString(m_model, 0);
57}
59}
58
60
59QString tabify(int level) { QString str;
61QString tabify(int level) { QString str;
60 for (int i = 0; i < level; i++) {
62 for (int i = 0; i < level; i++) {
61− str += " ";
63+ str += " ";
62 }
64 }
63 return str;
65 return str;
64}
66}
65
67
66−QString ModelPrinter::recurseString(const QModelIndex& index, int level) const
68+QString ModelPrinter::getModelDataString(UnityMenuModel* sourceModel, int level)
67{
69{
68− if (!m_model)
70+ if (!sourceModel)
69 return "";
71 return "";
70
72
71 QString str;
73 QString str;
72 QTextStream stream(&str);
74 QTextStream stream(&str);
73
75
76+ int rowCount = sourceModel->rowCount();
77+ for (int row = 0; row < rowCount; row++) {
78+
79+ stream << getRowSring(sourceModel, row, level) << endl;
80+
81+ UnityMenuModel* childMenuModel = qobject_cast<UnityMenuModel*>(sourceModel->submenu(row));
82+ if (childMenuModel) {
83+
84+ if (!m_children.contains(childMenuModel)) {
85+ m_children << childMenuModel;
86+ connect(childMenuModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(textChanged()));
87+ connect(childMenuModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(textChanged()));
88+ connect(childMenuModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SIGNAL(textChanged()));
89+ }
90+ stream << getModelDataString(childMenuModel, level+1);
91+ }
92+ }
93+ return str;
94+}
95+
96+QString ModelPrinter::getRowSring(UnityMenuModel* sourceModel, int row, int depth) const
97+{
98+ QString str;
99+ QTextStream stream(&str);
100+
101+ // Print out this row
74− QHash<int, QByteArray> roleNames = m_model->roleNames();
102+ QHash<int, QByteArray> roleNames = sourceModel->roleNames();
75 QList<int> roles = roleNames.keys();
103 QList<int> roles = roleNames.keys();
76 qSort(roles);
104 qSort(roles);
105+
77 Q_FOREACH(int role, roles) {
106 Q_FOREACH(int role, roles) {
78− QVariant vData = m_model->data(index, role);
107+ const QByteArray& roleName = roleNames[role];
79− if (vData.canConvert(QMetaType::QVariantMap)) {
108+ stream << tabify(depth) << getVariantString(roleName, sourceModel->get(row, roleName));
80− QMapIterator<QString, QVariant> iter(vData.toMap());
81− while (iter.hasNext()) {
82− iter.next();
83− stream << tabify(level)
84− << roleNames[role]
85− << "."
86− << iter.key()
87− << ": "
88− << iter.value().toString()
89− << endl;
90− }
91− }
92− else {
93− stream << tabify(level)
94− << roleNames[role]
95− << ": "
96− << vData.toString()
97− << endl;
98− }
99 }
109 }
110+ return str;
111+}
100
112
101− int rowCount = m_model->rowCount(index);
113+QString ModelPrinter::getVariantString(const QString& roleName, const QVariant vData ) const
102− stream << tabify(level)
114+{
103− << "child count"
115+ QString str;
104− << ": "
116+ QTextStream stream(&str);
105− << rowCount
117+
106− << endl
118+ if (vData.canConvert(QMetaType::QVariantMap)) {
107− << endl;
119+ QMapIterator<QString, QVariant> iter(vData.toMap());
108−
120+ while (iter.hasNext()) {
109− for (int i = 0; i < rowCount; i++) {
121+ iter.next();
110− QModelIndex child = m_model->index(i, 0, index);
122+ stream << roleName
111− str += recurseString(child, level+1);
123+ << "."
124+ << iter.key()
125+ << ": "
126+ << iter.value().toString()
127+ << endl;
128+ }
129+ }
130+ else {
131+ stream << roleName
132+ << ": "
133+ << vData.toString()
134+ << endl;
112 }
135 }
113 return str;
136 return str;
114}
137}
plugins/Unity/Indicators/modelprinter.h+12−7
@@ -21,6 +21,7 @@
21#define MODELPRINTER_H
21#define MODELPRINTER_H
22
22
23#include <QSortFilterProxyModel>
23#include <QSortFilterProxyModel>
24+class UnityMenuModel;
24
25
25// This class acts as a namespace only, with the addition that its enums
26// This class acts as a namespace only, with the addition that its enums
26// are registered to be exposed on the QML side.
27// are registered to be exposed on the QML side.
@@ -28,23 +29,27 @@ class ModelPrinter : public QObject
28{
29{
29 Q_OBJECT
30 Q_OBJECT
30
31
31− Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
32+ Q_PROPERTY(UnityMenuModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
32 Q_PROPERTY(QString text READ text NOTIFY textChanged)
33 Q_PROPERTY(QString text READ text NOTIFY textChanged)
33public:
34public:
34 ModelPrinter(QObject* parent=0);
35 ModelPrinter(QObject* parent=0);
35
36
36− void setSourceModel(QAbstractItemModel* sourceModel);
37+ void setSourceModel(UnityMenuModel* sourceModel);
37− QAbstractItemModel* sourceModel() const;
38+ UnityMenuModel* sourceModel() const;
38
39
39− Q_INVOKABLE QString text(const QModelIndex& index = QModelIndex()) const;
40+ Q_INVOKABLE QString text();
40
41
41Q_SIGNALS:
42Q_SIGNALS:
42 void modelChanged();
43 void modelChanged();
43 void textChanged();
44 void textChanged();
44
45
45private:
46private:
46− QString recurseString(const QModelIndex& index, int level) const;
47+ QString getModelDataString(UnityMenuModel* sourceModel, int level);
47− QAbstractItemModel* m_model;
48+ QString getRowSring(UnityMenuModel* sourceModel, int index, int depth) const;
49+ QString getVariantString(const QString& roleName, const QVariant vData ) const;
50+
51+ UnityMenuModel* m_model;
52+ QList<UnityMenuModel*> m_children;
48};
53};
49
54
50−#endif // MODELPRINTER_H
55+#endif // MODELPRINTER_H
plugins/Unity/Indicators/plugin.cpp+22−12
@@ -1,19 +1,20 @@
1/*
1/*
2− * Copyright (C) 2012 Canonical, Ltd.
2+ * Copyright 2013 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
5+ * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
7 *
7 *
8 * This program is distributed in the hope that it will be useful,
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
11+ * GNU Lesser General Public License for more details.
12 *
12 *
13− * You should have received a copy of the GNU General Public License
13+ * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16+ * Authors:
16− * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ * Nick Dedekind <nick.dedekind@canonical.com>
17 */
18 */
18
19
19// Qt
20// Qt
@@ -23,22 +24,31 @@
23#include "plugin.h"
24#include "plugin.h"
24
25
25// local
26// local
26−#include "flatmenuproxymodel.h"
27+#include "indicators.h"
27#include "indicatorsmanager.h"
28#include "indicatorsmanager.h"
28#include "indicatorsmodel.h"
29#include "indicatorsmodel.h"
29−#include "indicators.h"
30#include "menucontentactivator.h"
30#include "menucontentactivator.h"
31#include "modelprinter.h"
31#include "modelprinter.h"
32+#include "rootactionstate.h"
33+#include "unitymenumodelcache.h"
34+#include "unitymenumodelstack.h"
32
35
33−void IndicatorsPlugin::registerTypes(const char *uri)
36+static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
34−{
37+ Q_UNUSED(engine);
35− Q_INIT_RESOURCE(indicators);
38+ Q_UNUSED(scriptEngine);
39+ return new UnityMenuModelCache;
40+}
36
41
42+void Indicators2Plugin::registerTypes(const char *uri)
43+{
37 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
44 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
38− qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
39 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
45 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
40− qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
41 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
46 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
47+ qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
48+ qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
49+ qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
50+
51+ qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
42
52
43 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
53 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
44 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
54 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
plugins/Unity/Indicators/plugin.h+10−9
@@ -1,27 +1,28 @@
1/*
1/*
2− * Copyright (C) 2012 Canonical, Ltd.
2+ * Copyright 2013 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
5+ * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
6 * the Free Software Foundation; version 3.
7 *
7 *
8 * This program is distributed in the hope that it will be useful,
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
11+ * GNU Lesser General Public License for more details.
12 *
12 *
13− * You should have received a copy of the GNU General Public License
13+ * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16+ * Authors:
16− * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ * Nick Dedekind <nick.dedekind@canonical.com>
17 */
18 */
18
19
19−#ifndef INDICATORS_PLUGIN_H
20+#ifndef INDICATORS2_PLUGIN_H
20−#define INDICATORS_PLUGIN_H
21+#define INDICATORS2_PLUGIN_H
21
22
22#include <QtQml/QQmlExtensionPlugin>
23#include <QtQml/QQmlExtensionPlugin>
23
24
24−class IndicatorsPlugin : public QQmlExtensionPlugin
25+class Indicators2Plugin : public QQmlExtensionPlugin
25{
26{
26 Q_OBJECT
27 Q_OBJECT
27 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
@@ -29,4 +30,4 @@ public:
29 void registerTypes(const char *uri);
30 void registerTypes(const char *uri);
30};
31};
31
32
32−#endif // INDICATORS_PLUGIN_H
33+#endif // INDICATORS2_PLUGIN_H
plugins/Unity/Indicators/qml/BaseMenuItem.qmlnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23+
24+ListItem.Standard {
25+ id: baseMenu
26+
27+ property bool menuActivated: false
28+ property QtObject menu
29+
30+ signal selectMenu()
31+ signal deselectMenu()
32+
33+ signal activate()
34+ signal changeState(var value)
35+
36+ showDivider: false
37+ __foregroundColor: "#e8e1d0" // FIXME not in palette yet
38+
39+ backgroundIndicator: RemoveBackground {
40+ state: baseMenu.swipingState
41+ }
42+}
plugins/Unity/Indicators/qml/ButtonMenuItem.qml+10−8
@@ -15,19 +15,22 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
19 */
19
20
20import QtQuick 2.0
21import QtQuick 2.0
21import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23+import Unity.Indicators 0.1 as Indicators
22
24
23−BasicMenuItem {
25+BaseMenuItem {
24− id: buttonMenu
26+ id: menuItem
25− color: "#221e1b"
27+ objectName: menuAction.name
26 implicitHeight: units.gu(7)
28 implicitHeight: units.gu(7)
29+ enabled: menuAction.active
27
30
28 Button {
31 Button {
29 id: button
32 id: button
30− enabled: menuAction.valid
33+ enabled: menuAction.enabled
31 text: menu ? menu.label : ""
34 text: menu ? menu.label : ""
32 anchors.centerIn: parent
35 anchors.centerIn: parent
33 height: units.gu(4)
36 height: units.gu(4)
@@ -35,13 +38,12 @@ BasicMenuItem {
35 color: "#1b1817"
38 color: "#1b1817"
36
39
37 onClicked: {
40 onClicked: {
38− menuAction.activate()
41+ menuItem.activate();
39 }
42 }
40 }
43 }
41
44
42− MenuAction {
45+ Indicators.MenuAction {
43 id: menuAction
46 id: menuAction
44− actionGroup: buttonMenu.actionGroup
47+ menu: menuItem.menu
45− action: menu ? menu.action : ""
46 }
48 }
47}
49}
plugins/Unity/Indicators/qml/CachedUnityMenuModel.qmlnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import QMenuModel 0.1 as QMenuModel
22+import Unity.Indicators 0.1 as Indicators
23+
24+// Make sure we don't duplicate models.
25+Item {
26+ id: cachedModel
27+ property string busName: ""
28+ property string actionsObjectPath: ""
29+ property string menuObjectPath: ""
30+
31+ readonly property bool ready: busName!=="" && actionsObjectPath!=="" && menuObjectPath!==""
32+
33+ property QtObject model: {
34+ if (!ready) {
35+ return null;
36+ }
37+
38+ var component = Indicators.UnityMenuModelCache.model(menuObjectPath);
39+ if (!component) {
40+ component = modelComponent.createObject(cachedModel);
41+ return component;
42+ }
43+ return component;
44+ }
45+
46+ Component {
47+ id: modelComponent
48+
49+ QMenuModel.UnityMenuModel {
50+ id: unityModel
51+ busName: cachedModel.busName
52+ actions: { "indicator": cachedModel.actionsObjectPath }
53+ menuObjectPath: cachedModel.menuObjectPath
54+
55+ Component.onCompleted: {
56+ Indicators.UnityMenuModelCache.registerModel(cachedModel.menuObjectPath, unityModel);
57+ }
58+ }
59+ }
60+}
plugins/Unity/Indicators/qml/DivMenuItem.qml+1−1
@@ -21,6 +21,6 @@ import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22
22
23Rectangle {
23Rectangle {
24− color: "#181514"
24+ color: "#181514" // FIXME not in palette yet
25 implicitHeight: units.gu(1)
25 implicitHeight: units.gu(1)
26}
26}
plugins/Unity/Indicators/qml/FramedMenuItem.qmlnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import Ubuntu.Components.ListItems 0.1 as ListItem
24+
25+BaseMenuItem {
26+ text: menu && menu.label ? menu.label : ""
27+ implicitHeight: units.gu(7)
28+
29+ icon: menu ? menu.icon : ""
30+ iconFrame: false
31+
32+ HLine {
33+ anchors.top: parent.top
34+ color: "#403b37" // FIXME not in palette yet
35+ }
36+
37+ HLine {
38+ anchors.bottom: parent.bottom
39+ color: "#060606" // FIXME not in palette yet
40+ }
41+}
plugins/Unity/Indicators/qml/IndicatorBase.qml+13−19
@@ -14,46 +14,40 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16 * Authors:
16 * Authors:
17− * Renato Araujo Oliveira Filho <renato@canonical.com>
18 * Nick Dedekind <nick.dedekind@canonical.com>
17 * Nick Dedekind <nick.dedekind@canonical.com>
19 */
18 */
20
19
21import QtQuick 2.0
20import QtQuick 2.0
22−import QMenuModel 0.1
21+import QMenuModel 0.1 as QMenuModel
23import Unity.Indicators 0.1 as Indicators
22import Unity.Indicators 0.1 as Indicators
24
23
25Item {
24Item {
26 id: indicatorItem
25 id: indicatorItem
27
26
27+ // FIXME : should be disabled until bus available when we have desktop indicators
28+ // for now, disable when we dont habe the correct profile.
29+ enabled: menuObjectPaths.hasOwnProperty(device)
30+
28 //const
31 //const
29 property string title
32 property string title
30− property int busType
31 property string busName
33 property string busName
32 property string actionsObjectPath
34 property string actionsObjectPath
33 property var menuObjectPaths: undefined
35 property var menuObjectPaths: undefined
34 readonly property string device: "phone"
36 readonly property string device: "phone"
37+ property string rootMenuType: "com.canonical.indicator.root"
38+ property bool active: false
35
39
36 property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
40 property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
37
41
38 signal actionGroupUpdated()
42 signal actionGroupUpdated()
39 signal modelUpdated()
43 signal modelUpdated()
40
44
41− property var actionGroup: QDBusActionGroup {
45+ property alias menuModel: cachedModel.model
42− busType: indicatorItem.busType
43− busName: indicatorItem.busName
44− objectPath: indicatorItem.actionsObjectPath
45−
46− onActionAppear: indicatorItem.actionGroupUpdated();
47− }
48−
49− property var proxyModel: Indicators.FlatMenuProxyModel {
50− busType: indicatorItem.busType
51− busName: indicatorItem.busName
52− objectPath: indicatorItem.deviceMenuObjectPath
53
46
54− onStatusChanged: indicatorItem.modelUpdated();
47+ CachedUnityMenuModel {
55− onRowsInserted: indicatorItem.modelUpdated();
48+ id: cachedModel
56− onRowsRemoved: indicatorItem.modelUpdated();
49+ busName: active ? indicatorItem.busName : ""
57− onDataChanged: indicatorItem.modelUpdated();
50+ actionsObjectPath: active ? indicatorItem.actionsObjectPath : ""
51+ menuObjectPath: active ? indicatorItem.deviceMenuObjectPath : ""
58 }
52 }
59}
53}
plugins/Unity/Indicators/qml/IndicatorPage.qml+47−78
@@ -20,6 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1 as Components
22import Ubuntu.Components 0.1 as Components
23+import Unity.Indicators 0.1 as Indicators
23
24
24IndicatorBase {
25IndicatorBase {
25 id: main
26 id: main
@@ -27,14 +28,16 @@ IndicatorBase {
27 //const
28 //const
28 property alias emptyText: emptyLabel.text
29 property alias emptyText: emptyLabel.text
29 property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
30 property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
30− property bool __active: false
31+
32+ Indicators.UnityMenuModelStack {
33+ id: menuStack
34+ head: main.menuModel
35+ }
31
36
32 ListView {
37 ListView {
33 id: mainMenu
38 id: mainMenu
39+ model: menuStack.tail ? menuStack.tail : null
34
40
35− property int visibleItems: 0
36−
37− model: proxyModel
38 anchors {
41 anchors {
39 fill: parent
42 fill: parent
40 bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
43 bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
@@ -59,95 +62,65 @@ IndicatorBase {
59
62
60 currentIndex: -1
63 currentIndex: -1
61 delegate: Item {
64 delegate: Item {
62− id: item
65+ id: menuDelegate
63− property bool ready: false
64− property alias empty: factory.empty
65
66
66 anchors {
67 anchors {
67 left: parent.left
68 left: parent.left
68 right: parent.right
69 right: parent.right
69 }
70 }
70− height: div.height + factory.implicitHeight
71+ height: loader.height
71 visible: height > 0
72 visible: height > 0
72
73
73− Component.onCompleted: {
74+ Loader {
74− if (!item.empty) {
75+ id: loader
75− mainMenu.visibleItems += 1;
76+ asynchronous: true
76− }
77− ready = true;
78− }
79− Component.onDestruction: {
80− if (!item.empty) {
81− mainMenu.visibleItems -= 1;
82− }
83− ready = false;
84− }
85
77
86− onEmptyChanged: {
78+ property int modelIndex: index
87− if (!ready) {
88− return;
89− }
90− if (empty) {
91− mainMenu.visibleItems -= 1;
92− } else {
93− mainMenu.visibleItems += 1;
94− }
95− }
96
79
97− ListView.onRemove: {
80+ anchors {
98− if (!highlightFollowsCurrentItem) {
81+ left: parent.left
99− mainMenu.currentIndex = -1;
82+ right: parent.right
100 }
83 }
101− }
102
84
103− Column {
85+ sourceComponent: factory.load(model)
104− id: contents
105−
106− anchors.fill: parent
107−
108− DivMenuItem {
109− id: div
110−
111− anchors.left: parent.left
112− anchors.right: parent.right
113− // only visible if is a root or a section header element and the factory is visible
114− height: {
115− // skipe first item
116− if (item.y == 0) {
117− return 0;
118− }
119− if (hasSection || ((depth == 0) && (!factory.empty))) {
120− return implicitHeight;
121− } else {
122− return 0;
123− }
124− }
125− }
126
86
127− MenuItemFactory {
87+ onLoaded: {
128− id: factory
88+ if (model.type === rootMenuType) {
89+ menuStack.push(mainMenu.model.submenu(index));
90+ }
129
91
130− actionGroup: main.actionGroup
92+ if (item.hasOwnProperty("menuActivated")) {
131− isCurrentItem: item.ListView.isCurrentItem
93+ item.menuActivated = Qt.binding(function() { return ListView.isCurrentItem; });
132− anchors {
94+ item.selectMenu.connect(function() { ListView.view.currentIndex = index });
133− left: parent.left
95+ item.deselectMenu.connect(function() { ListView.view.currentIndex = -1 });
134− right: parent.right
135 }
96 }
136− menu: model
97+ if (item.hasOwnProperty("menu")) {
98+ item.menu = Qt.binding(function() { return model; });
137
99
138− Connections {
100+ item.activate.connect(onActivateMenu);
139− target : factory
101+ item.changeState.connect(onChangeState);
140− onActivated: item.ListView.view.currentIndex = index
141− onDeactivated: item.ListView.view.currentIndex = -1
142 }
102 }
143 }
103 }
104+
105+ function onActivateMenu(value) {
106+ mainMenu.model.activate(index, value);
107+ }
108+
109+ function onChangeState(value) {
110+ mainMenu.model.changeState(index, value);
111+ }
144 }
112 }
145 }
113 }
146 }
114 }
147
115
116+ MenuItemFactory {
117+ id: factory
118+ model: mainMenu.model
119+ }
120+
148 Components.Label {
121 Components.Label {
149 id: emptyLabel
122 id: emptyLabel
150− visible: (mainMenu.visibleItems === 0)
123+ visible: mainMenu.count == 0
151 anchors {
124 anchors {
152 top: parent.top
125 top: parent.top
153 left: parent.left
126 left: parent.left
@@ -167,19 +140,15 @@ IndicatorBase {
167 function start()
140 function start()
168 {
141 {
169 reset()
142 reset()
170− if (!__active) {
143+ if (!active) {
171− proxyModel.start();
144+ active = true;
172− actionGroup.start();
173− __active = true;
174 }
145 }
175 }
146 }
176
147
177 function stop()
148 function stop()
178 {
149 {
179− if (__active) {
150+ if (active) {
180− __active = false;
151+ active = false;
181− proxyModel.stop();
182− actionGroup.stop();
183 }
152 }
184 }
153 }
185
154
plugins/Unity/Indicators/qml/IndicatorWidget.qml+4−39
@@ -23,46 +23,11 @@ import Unity.Indicators 0.1 as Indicators
23IndicatorBase {
23IndicatorBase {
24 id: indicatorWidget
24 id: indicatorWidget
25
25
26−// enabled: false // FIXME : should be disabled until bus available when we have desktop indicators
26+ active: true
27− property var action: undefined
28− property bool started: (busType != 0) && (busName != "") && (deviceMenuObjectPath != "")
29 property int iconSize: height - units.gu(0.5)
27 property int iconSize: height - units.gu(0.5)
30− property string rootMenuType: "com.canonical.indicator.root"
31
28
32− signal actionStateChanged()
29+ property var actionState: Indicators.RootActionState {
33−
30+ menu: menuModel
34− onStartedChanged: {
35− if (started) {
36− proxyModel.start();
37− actionGroup.start();
38− } else {
39− proxyModel.stop();
40− actionGroup.stop();
41− }
42− }
43− onActionChanged: actionStateChanged()
44− onActionGroupUpdated: update_state()
45− onModelUpdated: update_state()
46−
47−
48− function update_state() {
49− var extra = proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Extra);
50− if (extra == undefined) {
51− return;
52− }
53−
54− if (!extra.hasOwnProperty("canonical_type")) {
55− return;
56− }
57−
58− if (extra.canonical_type === rootMenuType) {
59− action = actionGroup.action(proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Action));
60− }
61− }
62−
63− Connections {
64− target: action == undefined ? null : action
65− onStateChanged: actionStateChanged()
66− onValidChanged: actionStateChanged()
31+ onUpdated: indicatorWidget.actionStateChanged()
67 }
32 }
68}
33}
plugins/Unity/Indicators/qml/MenuAction.qml+16−43
@@ -15,6 +15,7 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
19 */
19
20
20import QtQuick 2.0
21import QtQuick 2.0
@@ -26,14 +27,17 @@ import QtQuick 2.0
26
27
27 Example:
28 Example:
28 \qml
29 \qml
29− Button {
30+ BaseMenuItem {
30− id: slide
31+ id: menuItem
31− onClick: { action.activate() }
32+
33+ Switch {
34+ checked: menuAction.state
32− }
35+ }
36+
33− MenuAction {
37+ Indicators.MenuAction {
34− id: action
38+ id: menuAction
35− actionGroup: menuItem.actionGroup
39+ menu: menuItem.menu
36− action: "/ubuntu/sound/enabled"
40+ }
37 }
41 }
38 \endqml
42 \endqml
39*/
43*/
@@ -41,46 +45,15 @@ import QtQuick 2.0
41Item {
45Item {
42 id: menuAction
46 id: menuAction
43
47
44− /*!
45− \preliminary
46− The dbus action name
47− */
48− property string action: ""
49−
50 /*!
48 /*!
51 \preliminary
49 \preliminary
52 The dbus action group object
50 The dbus action group object
53 */
51 */
54− property QtObject actionGroup: null
52+ readonly property string name: menu ? menu.action : ""
55−
56− /*!
57− \preliminary
58− This is a read-only property with the current validity of the action
59− */
60− readonly property bool valid: actionObject ? actionObject.valid : false
61−
62− readonly property var state: actionObject ? actionObject.state : undefined
63−
64− // internal
65− property QtObject actionObject: null
66−
67− function activate(param) {
68− if (valid) {
69− actionObject.activate(param);
70− }
71− }
72
53
73− onActionGroupChanged: updateAction()
54+ property QtObject menu: null
74− onActionChanged: updateAction()
75
55
76− Connections {
56+ readonly property var state: menu ? menu.actionState : undefined
77− target: menuAction.actionGroup != undefined ? menuAction.actionGroup : null
78− onActionAppear: menuAction.updateAction();
79− onActionVanish: menuAction.updateAction();
80− onStatusChanged: menuAction.updateAction();
81− }
82
57
83− function updateAction() {
58+ readonly property bool active: menu ? menu.sensitive : false
84− actionObject = action !== "" && actionGroup ? actionGroup.action(action) : null
85− }
86}
59}
plugins/Unity/Indicators/qml/MenuItemFactory.qml+25−61
@@ -19,22 +19,11 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Unity.Indicators 0.1 as Indicators
21import Unity.Indicators 0.1 as Indicators
22−import Unity.Indicators.Messaging 0.1 as ICMessaging
23−import Unity.Indicators.Network 0.1 as ICNetwork
24
22
25Item {
23Item {
26 id: menuFactory
24 id: menuFactory
27
25
28− property QtObject menu
26+ property var model: null
29− property QtObject listView
30− property QtObject actionGroup
31− property bool isCurrentItem
32− readonly property bool empty: (loader.item !== undefined && loader.status == Loader.Ready) ? loader.item.state === "EMPTY" : true
33−
34− implicitHeight: loader.height
35−
36− signal activated()
37− signal deactivated()
38
27
39 property var _map: {
28 property var _map: {
40 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
29 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
@@ -47,64 +36,39 @@ Item {
47 "com.canonical.indicator.slider" : sliderMenu,
36 "com.canonical.indicator.slider" : sliderMenu,
48 "com.canonical.indicator.switch" : switchMenu,
37 "com.canonical.indicator.switch" : switchMenu,
49
38
50− "com.canonical.indicator.messages.messageitem" : messageItem,
39+ "com.canonical.unity.slider" : sliderMenu,
51− "com.canonical.indicator.messages.snapdecision" : snapDecision,
40+ "com.canonical.unity.switch" : switchMenu,
52− "com.canonical.indicator.messages.sourceitem" : groupedMessage,
53−
54− "unity.widget.systemsettings.tablet.sectiontitle" : wifiSection,
55− "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
56− "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
57 }
41 }
58
42
43+ Component {
44+ id: sliderMenu;
59− Component { id: sliderMenu; Indicators.SliderMenuItem {} }
45+ Indicators.SliderMenuItem {
60− Component { id: switchMenu; Indicators.SwitchMenuItem {} }
46+ Component.onCompleted: {
47+ model.loadExtendedAttributes(modelIndex, {'min-value': 'double',
48+ 'max-value': 'double',
49+ 'min-icon': 'icon',
50+ 'max-icon': 'icon'});
51+ }
52+ }
53+ }
61 Component { id: buttonMenu; Indicators.ButtonMenuItem {} }
54 Component { id: buttonMenu; Indicators.ButtonMenuItem {} }
62 Component { id: divMenu; Indicators.DivMenuItem {} }
55 Component { id: divMenu; Indicators.DivMenuItem {} }
63 Component { id: sectionMenu; Indicators.SectionMenuItem {} }
56 Component { id: sectionMenu; Indicators.SectionMenuItem {} }
64 Component { id: progressMenu; Indicators.ProgressMenuItem {} }
57 Component { id: progressMenu; Indicators.ProgressMenuItem {} }
65− Component { id: messageItem; ICMessaging.MessageMenuItem {} }
58+ Component { id: standardMenu; Indicators.StandardMenuItem {} }
66− Component { id: snapDecision; ICMessaging.SnapDecision {} }
67− Component { id: groupedMessage; ICMessaging.GroupedMessage {} }
68− Component { id: wifiSection; ICNetwork.WifiSection {} }
69− Component { id: accessPoint; ICNetwork.AccessPoint {} }
70− Component { id: indicatorMenu; Indicators.MenuItem {} }
59+ Component { id: switchMenu; Indicators.SwitchMenuItem {} }
71−
72− Loader {
73− id: loader
74− asynchronous: true
75−
76− anchors {
77− left: parent.left
78− right: parent.right
79− }
80
60
81− sourceComponent: {
61+ function load(modelData) {
82− if (!menuFactory.menu || !menuFactory.menu.extra) {
62+ if (modelData.type !== undefined) {
63+ var component = _map[modelData.type];
64+ if (component !== undefined) {
83− return undefined;
65+ return component;
84 }
66 }
85−
86− var widgetType = menuFactory.menu.extra.canonical_type;
87− if (widgetType) {
88− return _map[widgetType];
89− } else {
67+ } else {
90− if (widgetType === "com.canonical.indicator.root") {
68+ if (modelData.isSeparator) {
91− return undefined;
69+ return divMenu;
92− // Try discovery the item based on the basic properties
93− } else if (menu.hasSection) {
94− return sectionMenu;
95− } else {
96− return indicatorMenu;
97− }
98 }
70 }
99 }
71 }
100−
72+ return standardMenu;
101− onLoaded: {
102− item.menuActivated = Qt.binding(function() { return isCurrentItem; });
103− item.actionGroup = Qt.binding(function() { return menuFactory.actionGroup; });
104− item.menu = Qt.binding(function() { return menuFactory.menu; });
105−
106− item.activateMenu.connect(function() { menuFactory.activated(); });
107− item.deactivateMenu.connect(function() { menuFactory.deactivated(); });
108− }
109 }
73 }
110}
74}
plugins/Unity/Indicators/qml/ProgressMenuItem.qml+16−36
@@ -19,47 +19,27 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
22
23
23−MenuItem {
24+FramedMenuItem {
24− id: progressMenu
25+ id: menuItem
25− property alias value : progressBar.value
26+ objectName: menuAction.name
27+ enabled: menuAction.active
26
28
27− // TODO: Replace this with the official ProgressBar component as soon as
28− // it is available. For now, this rebuilds the Mockup as close as possible.
29− UbuntuShape {
30− id: progressBar
31− anchors {
32− right: parent.right
33− rightMargin: units.gu(2)
34− left: parent.left
35− leftMargin: units.gu(2)
36− }
37− height: units.gu(4)
38− anchors.verticalCenter: parent.verticalCenter
39− color: "transparent"
40−
41− property int minimumValue: 0
42− property int maximumValue: 100
43− property int value: 50
29+ property int value : menuAction.state
44
30
45− UbuntuShape {
31+ control: Label {
46− anchors.fill: parent
32+ id: progress
47− anchors.rightMargin: parent.width - (parent.width * parent.value / parent.maximumValue)
33+ anchors.verticalCenter: parent.verticalCenter
48− color: "#c94212"
34+ anchors.right: parent.right
49− }
50
35
51− Label {
52− anchors.centerIn: parent
53− text: parent.value + " %"
36+ text: menuItem.value + " %"
54− fontSize: "medium"
37+ fontSize: "medium"
55− color: "#e8e1d0"
38+ color: "#e8e1d0"
56− }
57 }
39 }
58
40
59− MenuActionBinding {
41+ Indicators.MenuAction {
60− actionGroup: progressMenu.actionGroup
42+ id: menuAction
61− action: menu ? menu.action : ""
43+ menu: menuItem.menu
62− target: progressBar
63− property: "value"
64 }
44 }
65}
45}
plugins/Unity/Indicators/qml/SectionMenuItem.qml+3−6
@@ -21,17 +21,14 @@ import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
22import Ubuntu.Components.ListItems 0.1 as ListItem
23
23
24−BasicMenuItem {
24+BaseMenuItem {
25 property string label: menu && menu.label ? menu.label : ""
25 property string label: menu && menu.label ? menu.label : ""
26 property bool busy: false
26 property bool busy: false
27− property int count: menu && menu.linkSection ? menu.linkSection.count : 0
28
27
29− color: "#221e1b"
30− implicitHeight: label !== "" ? __header.height : 0
28+ implicitHeight: label !== "" ? header.height : 0
31− state: count === 0 ? "EMPTY" : ""
32
29
33 ListItem.Header {
30 ListItem.Header {
34− id: __header
31+ id: header
35
32
36 text: label
33 text: label
37 height: units.gu(4)
34 height: units.gu(4)
plugins/Unity/Indicators/qml/SliderMenuItem.qml+87−31
@@ -15,50 +15,106 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
19 */
19
20
20import QtQuick 2.0
21import QtQuick 2.0
21−import Ubuntu.Components 0.1
22+import Ubuntu.Components 0.1 as Components
23+import Unity.Indicators 0.1 as Indicators
22
24
23−MenuItem {
25+FramedMenuItem {
24− id: _sliderMenu
26+ id: menuItem
27+ objectName: menuAction.name
28+ enabled: menuAction.active
25
29
26 property alias minimumValue: slider.minimumValue
30 property alias minimumValue: slider.minimumValue
27 property alias maximumValue: slider.maximumValue
31 property alias maximumValue: slider.maximumValue
28− property alias value: slider.value
32+ readonly property double value: menu ? menuAction.state : 0.0
29−
33+
30− control: Slider {
34+ property QtObject d: QtObject {
31− id: slider
35+ property bool enableValueConnection: true
32− enabled: menuAction.valid
36+ }
33− width: _sliderMenu.text ? units.gu(20) : _sliderMenu.width - units.gu(4)
37+
34− anchors.verticalCenter: parent.verticalCenter
38+ onValueChanged: {
39+ // TODO: look into adding a component to manage bi-directional bindings.
40+ var oldEnable = d.enableValueConnection
41+ d.enableValueConnection = false;
42+
43+ // Can't rely on binding. Slider value is assigned by user slide.
44+ slider.value = value;
45+
46+ d.enableValueConnection = oldEnable;
47+ }
48+
49+ control: Item {
50+ id: row
51+ width: sliderMenu.text ? units.gu(20) : menuItem.width - (2 * menuItem.__contentsMargins)
52+ height: slider.height
53+
54+ Image {
55+ id: leftImage
56+ visible: source != ""
57+ anchors.left: row.left
58+ anchors.verticalCenter: row.verticalCenter
59+ height: units.gu(4)
60+ width: height
61+ source: menu.ext.minIcon
62+ }
63+
64+ Components.Slider {
65+ id: slider
66+ anchors {
67+ left: leftImage.visible ? leftImage.right : row.left
68+ right: rightImage.visible ? rightImage.left : row.right
69+ leftMargin: leftImage.visible ? units.gu(0.5) : 0
70+ rightMargin: rightImage.visible ? units.gu(0.5) : 0
71+ }
35− live: false
72+ live: false
73+
74+ Component.onCompleted: {
75+ value = menuItem.value
76+ }
77+
36− // FIXME: The interval should be [0.0 - 1.0]. Unfortunately, when
78+ // FIXME: The interval should be [0.0 - 1.0]. Unfortunately, when
37− // reaching the boundaries (0.0 or 1.0), the value is converted
79+ // reaching the boundaries (0.0 or 1.0), the value is converted
38− // to an integer when automatically wrapped in a variant when
80+ // to an integer when automatically wrapped in a variant when
39− // passed to QStateAction::updateState(…). The server chokes on
81+ // passed to QStateAction::updateState(…). The server chokes on
40− // those values, complaining that they’re not of the right type…
82+ // those values, complaining that they’re not of the right type…
41− minimumValue: menu.extra.canonical_min ? menu.extra.canonical_min * 1.000001 : 0.0000001
83+ minimumValue: menu.ext.minValue ? menu.ext.minValue * 1.000001 : 0.0000001
42− maximumValue: {
84+ maximumValue: {
43− var maximum = menu.extra.canonical_max ? menu.extra.canonical_max * 1.000001 : 0.9999999
85+ var maximum = menu.ext.maxValue ? menu.ext.maxValue * 1.000001 : 0.9999999
44− if (maximum <= minimumValue) {
86+ if (maximum <= minimumValue) {
45− return minimumValue + 1;
87+ return minimumValue + 1;
88+ }
89+ return maximum;
90+ }
91+
92+ // FIXME - to be deprecated in Ubuntu.Components.
93+ // Use this to disable the label, since there is not way to do it on the component.
94+ function formatValue(v) {
95+ return "";
96+ }
97+
98+ Connections {
99+ target: d.enableValueConnection ? slider : null
100+ onValueChanged: {
101+ menuItem.changeState(slider.value);
102+ }
46 }
103 }
47− return maximum;
48 }
104 }
49
105
50− // FIXME - to be deprecated in Ubuntu.Components.
106+ Image {
51− // Use this to disable the label, since there is not way to do it on the component.
107+ id: rightImage
52− function formatValue(v) {
108+ anchors.right: row.right
53− return "";
109+ anchors.verticalCenter: row.verticalCenter
110+ height: units.gu(4)
111+ width: height
112+ source: menu.ext.maxIcon
54 }
113 }
55 }
114 }
56
115
57− MenuActionBinding {
116+ Indicators.MenuAction {
58 id: menuAction
117 id: menuAction
59− actionGroup: _sliderMenu.actionGroup
118+ menu: menuItem.menu
60− action: menu ? menu.action : ""
61− target: slider
62− property: "value"
63 }
119 }
64}
120}
plugins/Unity/Indicators/qml/StandardMenuItem.qmlnew file+76
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1 as Components
22+import Unity.Indicators 0.1 as Indicators
23+
24+FramedMenuItem {
25+ id: menuItem
26+ objectName: menuAction.name
27+ enabled: menuAction.active
28+
29+ readonly property bool checkable: menu ? (menu.isCheck || menu.isRadio) : false
30+ readonly property bool checked: checkable ? menu.isToggled : false
31+
32+ // FIXME : need a radio button from sdk
33+ // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211866
34+ onCheckableChanged: {
35+ if (menu && checkable) {
36+ icon = checkComponent.createObject(menuItem);
37+ }
38+ }
39+
40+ onCheckedChanged: {
41+ // Can't rely on binding. Checked is assigned on click.
42+ if (icon) {
43+ icon.checked = checked;
44+ }
45+ }
46+
47+ onClicked: {
48+ if (checkable && icon) {
49+ icon.clicked();
50+ } else {
51+ menuItem.activate();
52+ }
53+ }
54+
55+ property var checkComponent: Component {
56+ Components.CheckBox {
57+ anchors.verticalCenter: parent.verticalCenter
58+ anchors.left: parent.left
59+
60+ Component.onCompleted: {
61+ checked = menuItem.checked;
62+ }
63+
64+ // FIXME : should use Checkbox.toggled signal
65+ // lp:~nick-dedekind/ubuntu-ui-toolkit/checkbox.toggled
66+ onClicked: {
67+ menuItem.activate();
68+ }
69+ }
70+ }
71+
72+ Indicators.MenuAction {
73+ id: menuAction
74+ menu: menuItem.menu
75+ }
76+}
plugins/Unity/Indicators/qml/SwitchMenuItem.qml+24−9
@@ -15,29 +15,44 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
19 */
19
20
20import QtQuick 2.0
21import QtQuick 2.0
21import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23+import Unity.Indicators 0.1 as Indicators
22
24
23−MenuItem {
25+FramedMenuItem {
24− id: switchMenu
26+ id: menuItem
27+ objectName: menuAction.name
28+ enabled: menuAction.enabled
25
29
30+ readonly property bool checked: menu ? menu.isToggled : false
31+
32+ onCheckedChanged: {
33+ // Can't rely on binding. Checked is assigned on click.
26− property alias checked: switcher.checked
34+ switcher.checked = checked;
35+ }
27
36
28 control: Switch {
37 control: Switch {
29 id: switcher
38 id: switcher
30− enabled: menuAction.valid
39+
40+ Component.onCompleted: {
41+ checked = menuItem.checked;
42+ }
31
43
32 anchors.verticalCenter: parent.verticalCenter
44 anchors.verticalCenter: parent.verticalCenter
33 anchors.right: parent.right
45 anchors.right: parent.right
46+
47+ // FIXME : should use Checkbox.toggled signal
48+ // lp:~nick-dedekind/ubuntu-ui-toolkit/checkbox.toggled
49+ onClicked: {
50+ menuItem.activate();
51+ }
34 }
52 }
35
53
36− MenuActionBinding {
54+ Indicators.MenuAction {
37 id: menuAction
55 id: menuAction
38− actionGroup: switchMenu.actionGroup
56+ menu: menuItem.menu
39− action: menu ? menu.action : ""
40− target: switcher
41− property: "checked"
42 }
57 }
43}
58}
plugins/Unity/Indicators/qml/qmldir+5−2
@@ -2,20 +2,23 @@ module Unity.Indicators
2plugin IndicatorsQml
2plugin IndicatorsQml
3typeinfo plugin.qmltypes
3typeinfo plugin.qmltypes
4
4
5−BasicMenuItem 0.1 BasicMenuItem.qml
5+BaseMenuItem 0.1 BaseMenuItem.qml
6ButtonMenuItem 0.1 ButtonMenuItem.qml
6ButtonMenuItem 0.1 ButtonMenuItem.qml
7+CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
7DivMenuItem 0.1 DivMenuItem.qml
8DivMenuItem 0.1 DivMenuItem.qml
9+FramedMenuItem 0.1 FramedMenuItem.qml
8HLine 0.1 HLine.qml
10HLine 0.1 HLine.qml
9IndicatorBase 0.1 IndicatorBase.qml
11IndicatorBase 0.1 IndicatorBase.qml
10IndicatorPage 0.1 IndicatorPage.qml
12IndicatorPage 0.1 IndicatorPage.qml
11IndicatorWidget 0.1 IndicatorWidget.qml
13IndicatorWidget 0.1 IndicatorWidget.qml
12−MenuItem 0.1 MenuItem.qml
13MenuAction 0.1 MenuAction.qml
14MenuAction 0.1 MenuAction.qml
14MenuActionBinding 0.1 MenuActionBinding.qml
15MenuActionBinding 0.1 MenuActionBinding.qml
15MenuItemFactory 0.1 MenuItemFactory.qml
16MenuItemFactory 0.1 MenuItemFactory.qml
16ProgressMenuItem 0.1 ProgressMenuItem.qml
17ProgressMenuItem 0.1 ProgressMenuItem.qml
17SectionMenuItem 0.1 SectionMenuItem.qml
18SectionMenuItem 0.1 SectionMenuItem.qml
18SliderMenuItem 0.1 SliderMenuItem.qml
19SliderMenuItem 0.1 SliderMenuItem.qml
20+StandardMenuItem 0.1 StandardMenuItem.qml
19SwitchMenuItem 0.1 SwitchMenuItem.qml
21SwitchMenuItem 0.1 SwitchMenuItem.qml
20
22
23+
21internal RemoveBackground RemoveBackground.qml
24internal RemoveBackground RemoveBackground.qml
plugins/Unity/Indicators/rootactionstate.cppnew file+249
@@ -0,0 +1,249 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "rootactionstate.h"
21+#include "indicators.h"
22+
23+#include <unitymenumodel.h>
24+#include <QVariant>
25+#include <QIcon>
26+
27+extern "C" {
28+#include <glib.h>
29+#include <gio/gio.h>
30+}
31+
32+RootActionState::RootActionState(QObject *parent)
33+ : ActionStateParser(parent),
34+ m_menu(NULL)
35+{
36+}
37+
38+RootActionState::~RootActionState()
39+{
40+}
41+
42+UnityMenuModel* RootActionState::menu() const
43+{
44+ return m_menu;
45+}
46+
47+void RootActionState::setMenu(UnityMenuModel* menu)
48+{
49+ if (m_menu != menu) {
50+ if (m_menu) {
51+ m_menu->disconnect(this);
52+ }
53+ m_menu = menu;
54+
55+ if (m_menu) {
56+ connect(m_menu, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(onModelRowsAdded(const QModelIndex&, int, int)));
57+ connect(m_menu, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(onModelRowsRemoved(const QModelIndex&, int, int)));
58+ connect(m_menu, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)), SLOT(onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
59+
60+ m_menu->setActionStateParser(this);
61+ }
62+ updateActionState();
63+ Q_EMIT menuChanged();
64+ }
65+}
66+
67+void RootActionState::onModelRowsAdded(const QModelIndex& parent, int start, int end)
68+{
69+ Q_UNUSED(parent);
70+ if (start == 0 && end >= 0) {
71+ updateActionState();
72+ }
73+}
74+
75+void RootActionState::onModelRowsRemoved(const QModelIndex& parent, int start, int end)
76+{
77+ Q_UNUSED(parent);
78+ if (start == 0 && end >= 0) {
79+ updateActionState();
80+ }
81+}
82+
83+void RootActionState::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
84+{
85+ Q_UNUSED(roles);
86+ if (!topLeft.isValid() || !bottomRight.isValid()) {
87+ return;
88+ }
89+
90+ if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
91+ updateActionState();
92+ }
93+}
94+
95+void RootActionState::updateActionState()
96+{
97+ if (m_menu && m_menu->rowCount() > 0) {
98+ m_cachedState = m_menu->get(0, "actionState").toMap();
99+ } else {
100+ m_cachedState.clear();
101+ }
102+ Q_EMIT updated();
103+}
104+
105+
106+bool RootActionState::isValid() const
107+{
108+ return m_menu && m_menu->rowCount() > 0;
109+}
110+
111+QString RootActionState::label() const
112+{
113+ if (!isValid()) return QString();
114+
115+ return m_cachedState.value("label", QVariant::fromValue(QString())).toString();
116+}
117+
118+QString RootActionState::icon() const
119+{
120+ if (!isValid()) return QString();
121+
122+ return m_cachedState.value("icon", QVariant::fromValue(QString())).toString();
123+}
124+
125+QString RootActionState::accessibleName() const
126+{
127+ if (!isValid()) return QString();
128+
129+ return m_cachedState.value("accessible-name", QVariant::fromValue(QString())).toString();
130+}
131+
132+bool RootActionState::isVisible() const
133+{
134+ if (!isValid()) return false;
135+
136+ return m_cachedState.value("visible", QVariant::fromValue(true)).toBool();
137+}
138+
139+static QString iconUri(GIcon *icon)
140+{
141+ QString uri;
142+
143+ if (G_IS_THEMED_ICON (icon)) {
144+
145+ const gchar* const* iconNames = g_themed_icon_get_names (G_THEMED_ICON (icon));
146+ guint index = 0;
147+ while(iconNames[index] != NULL) {
148+ if (QIcon::hasThemeIcon(iconNames[index])) {
149+ uri = QString("image://theme/%1").arg(iconNames[index]);
150+ break;
151+ }
152+ index++;
153+ }
154+ }
155+ else if (G_IS_FILE_ICON (icon)) {
156+ GFile *file;
157+
158+ file = g_file_icon_get_file (G_FILE_ICON (icon));
159+ if (g_file_is_native (file)) {
160+ gchar *fileuri;
161+
162+ fileuri = g_file_get_path (file);
163+ uri = QString(fileuri);
164+
165+ g_free (fileuri);
166+ }
167+ }
168+ else if (G_IS_BYTES_ICON (icon)) {
169+ gsize size;
170+ gconstpointer data;
171+ gchar *base64;
172+
173+ data = g_bytes_get_data (g_bytes_icon_get_bytes (G_BYTES_ICON (icon)), &size);
174+ base64 = g_base64_encode ((const guchar *) data, size);
175+
176+ uri = QString("data://");
177+ uri.append (base64);
178+
179+ g_free (base64);
180+ }
181+
182+ return uri;
183+}
184+
185+QVariant RootActionState::toQVariant(GVariant* state) const
186+{
187+ if (!state) {
188+ return QVariant();
189+ }
190+
191+ if (g_variant_is_of_type(state, G_VARIANT_TYPE_VARDICT)) {
192+ GVariantIter iter;
193+ GVariant *vvalue;
194+ gchar *key;
195+ QVariantMap qmap;
196+
197+ g_variant_iter_init (&iter, state);
198+ while (g_variant_iter_loop (&iter, "{sv}", &key, &vvalue))
199+ {
200+ QString str = QString::fromUtf8(key);
201+ if (str == "icon") {
202+ // FIXME - should be sending a url.
203+ GIcon *icon = g_icon_deserialize (vvalue);
204+ if (icon) {
205+ qmap.insert(str, iconUri(icon));
206+ g_object_unref (icon);
207+ }
208+ else {
209+ qmap.insert(str, QVariant(""));
210+ }
211+ } else {
212+ qmap.insert(str, ActionStateParser::toQVariant(vvalue));
213+ }
214+ }
215+
216+ return QVariant::fromValue(qmap);
217+
218+ } else if (g_variant_is_of_type (state, G_VARIANT_TYPE ("(sssb)"))) {
219+ QVariantMap qmap;
220+
221+ char* label;
222+ char* icon;
223+ char* accessible_name;
224+ gboolean visible;
225+ GIcon *gicon;
226+
227+ g_variant_get(state, "(sssb)", &label,
228+ &icon,
229+ &accessible_name,
230+ &visible);
231+
232+ qmap["label"] = label ? QString::fromUtf8(label) : "";
233+ qmap["accessible-name"] = accessible_name ? QString::fromUtf8(accessible_name) : "";
234+ qmap["visible"] = visible;
235+
236+ gicon = g_icon_new_for_string (icon, NULL);
237+ if (gicon) {
238+ qmap["icon"] = iconUri(gicon);
239+ g_object_unref (gicon);
240+ }
241+
242+ if (label) g_free(label);
243+ if (icon) g_free(icon);
244+ if (accessible_name) g_free(accessible_name);
245+
246+ return QVariant::fromValue(qmap);
247+ }
248+ return ActionStateParser::toQVariant(state);
249+}
plugins/Unity/Indicators/rootactionstate.hnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef ROOTACTIONSTATE_H
21+#define ROOTACTIONSTATE_H
22+
23+#include "unityindicatorsglobal.h"
24+
25+#include <actionstateparser.h>
26+
27+class UnityMenuModel;
28+
29+class UNITYINDICATORS_EXPORT RootActionState : public ActionStateParser
30+{
31+ Q_OBJECT
32+ Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
33+
34+ Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
35+ Q_PROPERTY(QString label READ label NOTIFY labelChanged)
36+ Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
37+ Q_PROPERTY(QString accessibleName READ accessibleName NOTIFY accessibleNameChanged)
38+ Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged)
39+public:
40+ RootActionState(QObject *parent = 0);
41+ virtual ~RootActionState();
42+
43+ UnityMenuModel* menu() const;
44+ void setMenu(UnityMenuModel* menu);
45+
46+ int index() const;
47+ void setIndex(int index);
48+
49+ bool isValid() const;
50+ QString label() const;
51+ QString icon() const;
52+ QString accessibleName() const;
53+ bool isVisible() const;
54+
55+ // from ActionStateParser
56+ virtual QVariant toQVariant(GVariant* state) const;
57+
58+Q_SIGNALS:
59+ void updated();
60+
61+ void menuChanged();
62+ void indexChanged();
63+
64+ void validChanged();
65+ void labelChanged();
66+ void iconChanged();
67+ void accessibleNameChanged();
68+ void visibleChanged();
69+
70+private Q_SLOTS:
71+ void onModelRowsAdded(const QModelIndex& parent, int start, int end);
72+ void onModelRowsRemoved(const QModelIndex& parent, int start, int end);
73+ void onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>&);
74+
75+private:
76+ void updateActionState();
77+
78+ UnityMenuModel* m_menu;
79+ QVariantMap m_cachedState;
80+};
81+
82+#endif // ROOTACTIONSTATE_H
plugins/Unity/Indicators/unitymenumodelcache.cppnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "unitymenumodelcache.h"
21+#include <unitymenumodel.h>
22+
23+UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
24+ : QObject(parent)
25+{
26+}
27+
28+UnityMenuModelCache::~UnityMenuModelCache()
29+{
30+}
31+
32+
33+UnityMenuModel* UnityMenuModelCache::model(const QString& path) const
34+{
35+ return m_menuModels.value(path, NULL);
36+}
37+
38+void UnityMenuModelCache::registerModel(const QString& path, UnityMenuModel* menuModel)
39+{
40+ menuModel->setParent(this);
41+ m_menuModels[path] = menuModel;
42+}
plugins/Unity/Indicators/unitymenumodelcache.hnew file+44
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef UNITYMENUMODELCACHE_H
21+#define UNITYMENUMODELCACHE_H
22+
23+#include "unityindicatorsglobal.h"
24+
25+#include <QObject>
26+#include <QHash>
27+
28+class UnityMenuModel;
29+
30+class UNITYINDICATORS_EXPORT UnityMenuModelCache : public QObject
31+{
32+ Q_OBJECT
33+public:
34+ UnityMenuModelCache(QObject*parent=NULL);
35+ ~UnityMenuModelCache();
36+
37+ Q_INVOKABLE UnityMenuModel* model(const QString& path) const;
38+ Q_INVOKABLE void registerModel(const QString& path, UnityMenuModel* menuModel);
39+
40+private:
41+ QHash<QString, UnityMenuModel*> m_menuModels;
42+};
43+
44+#endif // UNITYMENUMODELCACHE_H
plugins/Unity/Indicators/unitymenumodelstack.cppnew file+69
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "unitymenumodelstack.h"
21+
22+UnityMenuModelStack::UnityMenuModelStack(QObject* parent)
23+ : QObject(parent)
24+{
25+}
26+
27+UnityMenuModelStack::~UnityMenuModelStack()
28+{
29+}
30+
31+UnityMenuModel* UnityMenuModelStack::head() const
32+{
33+ return !m_menuModels.isEmpty() ? m_menuModels.first() : NULL;
34+}
35+
36+void UnityMenuModelStack::setHead(UnityMenuModel* model)
37+{
38+ if (head() != model) {
39+ m_menuModels.clear();
40+ push(model);
41+ Q_EMIT headChanged(model);
42+ }
43+}
44+
45+UnityMenuModel* UnityMenuModelStack::tail() const
46+{
47+ return !m_menuModels.isEmpty() ? m_menuModels.last() : NULL;
48+}
49+
50+void UnityMenuModelStack::push(UnityMenuModel* model)
51+{
52+ m_menuModels << model;
53+ Q_EMIT tailChanged(model);
54+}
55+
56+UnityMenuModel* UnityMenuModelStack::pop()
57+{
58+ if (m_menuModels.isEmpty()) {
59+ return NULL;
60+ }
61+ UnityMenuModel* model = m_menuModels.takeLast();
62+
63+ Q_EMIT tailChanged(tail());
64+ if (m_menuModels.isEmpty()) {
65+ Q_EMIT headChanged(NULL);
66+ }
67+
68+ return model;
69+}
plugins/Unity/Indicators/unitymenumodelstack.hnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef UNITYMENUMODELSTACK_H
21+#define UNITYMENUMODELSTACK_H
22+
23+#include "unityindicatorsglobal.h"
24+
25+#include <QObject>
26+#include <QList>
27+
28+class UnityMenuModel;
29+
30+// A LIFO queue for storing the current submenu of a UnityMenuModel.
31+// The root menu model is set as the head, and each subsiquent submenu that is
32+// opened can be pushed onto the queue.
33+// The tail is set to the last item on the queue
34+// Popping the queue will remove the last entry, and the tail be updated to the last item.
35+class UNITYINDICATORS_EXPORT UnityMenuModelStack : public QObject
36+{
37+ Q_OBJECT
38+ Q_PROPERTY(UnityMenuModel* head READ head WRITE setHead NOTIFY headChanged)
39+ Q_PROPERTY(UnityMenuModel* tail READ tail NOTIFY tailChanged)
40+public:
41+ UnityMenuModelStack(QObject*parent=NULL);
42+ ~UnityMenuModelStack();
43+
44+ UnityMenuModel* head() const;
45+ void setHead(UnityMenuModel* model);
46+
47+ UnityMenuModel* tail() const;
48+
49+ Q_INVOKABLE void push(UnityMenuModel* model);
50+ Q_INVOKABLE UnityMenuModel* pop();
51+
52+Q_SIGNALS:
53+ void headChanged(UnityMenuModel* head);
54+ void tailChanged(UnityMenuModel* tail);
55+
56+private:
57+ QList<UnityMenuModel*> m_menuModels;
58+};
59+
60+#endif // UNITYMENUMODELSTACK_H
plugins/Unity/IndicatorsLegacy/CMakeLists.txtnew file+49
@@ -0,0 +1,49 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+project(IndicatorsLegacyQml)
5+
6+pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
7+find_package(Qt5Core REQUIRED)
8+find_package(Qt5Quick REQUIRED)
9+
10+add_subdirectory(qml)
11+add_subdirectory(Messaging)
12+add_subdirectory(Network)
13+
14+include_directories(
15+ ${CMAKE_CURRENT_SOURCE_DIR}
16+ ${CMAKE_CURRENT_BINARY_DIR}
17+ ${QMENUMODEL_INCLUDE_DIRS}
18+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators
19+)
20+
21+set(IndicatorsLegacyQML_SOURCES
22+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
23+ flatmenuproxymodel.cpp
24+ modelprinter.cpp
25+ plugin.cpp
26+)
27+add_definitions(-DUNITYINDICATORS_LIBRARY)
28+
29+set(IndicatorsLegacyQML_RESOURCES
30+ resources/indicators.qrc
31+)
32+
33+qt5_add_resources(IndicatorsLegacyQML_RESOURCES_RCC
34+ ${IndicatorsLegacyQML_RESOURCES}
35+)
36+
37+add_library(IndicatorsLegacyQml SHARED
38+ ${IndicatorsLegacyQML_RESOURCES_RCC}
39+ ${IndicatorsLegacyQML_SOURCES}
40+)
41+
42+target_link_libraries(IndicatorsLegacyQml
43+ ${QMENUMODEL_LDFLAGS}
44+)
45+
46+qt5_use_modules(IndicatorsLegacyQml Core Qml Quick)
47+
48+# export the qmltypes and plugin files
49+export_qmlplugin(Unity.IndicatorsLegacy 0.1 Unity/IndicatorsLegacy TARGETS IndicatorsLegacyQml)
plugins/Unity/Indicators/Messaging/CMakeLists.txt → plugins/Unity/IndicatorsLegacy/Messaging/CMakeLists.txtrenamed

The content is the same.

plugins/Unity/Indicators/Messaging/qml/ActionButton.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/ActionButton.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Button {
25Button {
26 id: button
26 id: button
plugins/Unity/Indicators/Messaging/qml/ActionTextField.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/ActionTextField.qmlrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/Messaging/qml/CMakeLists.txtnew file+5
@@ -0,0 +1,5 @@
1+# export_qmlfiles macro
2+include(Plugins)
3+
4+# export the qmldir, *.qml files.
5+export_qmlfiles(Unity.IndicatorsLegacy.Messaging Unity/IndicatorsLegacy/Messaging)
plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/GroupedMessage.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Indicators.BasicMenuItem {
25Indicators.BasicMenuItem {
26 id: groupedMessage
26 id: groupedMessage
plugins/Unity/Indicators/Messaging/qml/HeroMessage.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessage.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Indicators.BasicMenuItem {
25Indicators.BasicMenuItem {
26 id: heroMessage
26 id: heroMessage
plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessageHeader.qmlrenamed

The content is the same.

plugins/Unity/Indicators/Messaging/qml/MessageMenuItem.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/MessageMenuItem.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Indicators.BasicMenuItem {
25Indicators.BasicMenuItem {
26 property variant actionsDescription: menu ? menu.extra.canonical_message_actions : undefined
26 property variant actionsDescription: menu ? menu.extra.canonical_message_actions : undefined
plugins/Unity/Indicators/Messaging/qml/QuickReply.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/QuickReply.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Item {
25Item {
26 property alias actionGroup: actionTextField.actionGroup
26 property alias actionGroup: actionTextField.actionGroup
plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/SimpleTextMessage.qmlrenamed

The content is the same.

plugins/Unity/Indicators/Messaging/qml/SnapDecision.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/SnapDecision.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24import "utils.js" as Utils
24import "utils.js" as Utils
25
25
26HeroMessage {
26HeroMessage {
plugins/Unity/Indicators/Messaging/qml/TextMessage.qml → plugins/Unity/IndicatorsLegacy/Messaging/qml/TextMessage.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25SimpleTextMessage {
25SimpleTextMessage {
26 id: simpleMessage
26 id: simpleMessage
plugins/Unity/Indicators/Messaging/qml/qmldir → plugins/Unity/IndicatorsLegacy/Messaging/qml/qmldirrenamed+1−1
@@ -1,4 +1,4 @@
1−module Unity.Indicators.Messaging
1+module Unity.IndicatorsLegacy.Messaging
2
2
3ActionButton 0.1 ActionButton.qml
3ActionButton 0.1 ActionButton.qml
4ActionTextField 0.1 ActionTextField.qml
4ActionTextField 0.1 ActionTextField.qml
plugins/Unity/Indicators/Messaging/qml/utils.js → plugins/Unity/IndicatorsLegacy/Messaging/qml/utils.jsrenamed

The content is the same.

plugins/Unity/Indicators/Network/CMakeLists.txt → plugins/Unity/IndicatorsLegacy/Network/CMakeLists.txtrenamed+1−1
@@ -36,7 +36,7 @@ if(LIBNM_GLIB_FOUND AND LIBNM_UTIL_FOUND AND GLIB_FOUND)
36 )
36 )
37
37
38 # export the qmltypes and plugin files
38 # export the qmltypes and plugin files
39− export_qmlplugin(Unity.Indicators.Network 0.1 Unity/Indicators/Network TARGETS IndicatorsNetworkQml)
39+ export_qmlplugin(Unity.IndicatorsLegacy.Network 0.1 Unity/IndicatorsLegacy/Network TARGETS IndicatorsNetworkQml)
40
40
41else()
41else()
42 message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
42 message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
plugins/Unity/Indicators/Network/networkagent.cpp → plugins/Unity/IndicatorsLegacy/Network/networkagent.cpprenamed

The content is the same.

plugins/Unity/Indicators/Network/networkagent.h → plugins/Unity/IndicatorsLegacy/Network/networkagent.hrenamed

The content is the same.

plugins/Unity/Indicators/Network/plugin.cpp → plugins/Unity/IndicatorsLegacy/Network/plugin.cpprenamed

The content is the same.

plugins/Unity/Indicators/Network/plugin.h → plugins/Unity/IndicatorsLegacy/Network/plugin.hrenamed

The content is the same.

plugins/Unity/Indicators/Network/qml/AccessPoint.qml → plugins/Unity/IndicatorsLegacy/Network/qml/AccessPoint.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
22import Ubuntu.Components.ListItems 0.1 as ListItem
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Indicators.MenuItem {
25Indicators.MenuItem {
26 id: accessPoint
26 id: accessPoint
plugins/Unity/IndicatorsLegacy/Network/qml/CMakeLists.txtnew file+5
@@ -0,0 +1,5 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+# export the qmldir, *.qml files.
5+export_qmlfiles(Unity.IndicatorsLegacy.Network Unity/IndicatorsLegacy/Network)
plugins/Unity/Indicators/Network/qml/PasswordPage.qml → plugins/Unity/IndicatorsLegacy/Network/qml/PasswordPage.qmlrenamed+1−1
@@ -20,7 +20,7 @@
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
22import Ubuntu.Components.ListItems 0.1 as ListItem
23−import Unity.Indicators 0.1 as Indicators
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24
24
25Page {
25Page {
26 id: pagePassword
26 id: pagePassword
plugins/Unity/Indicators/Network/qml/PasswordTextField.qml → plugins/Unity/IndicatorsLegacy/Network/qml/PasswordTextField.qmlrenamed

The content is the same.

plugins/Unity/Indicators/Network/qml/WifiSection.qml → plugins/Unity/IndicatorsLegacy/Network/qml/WifiSection.qmlrenamed+1−1
@@ -19,7 +19,7 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import Unity.Indicators 0.1 as Indicators
22+import Unity.IndicatorsLegacy 0.1 as Indicators
23
23
24Indicators.SectionMenuItem {
24Indicators.SectionMenuItem {
25 id: wifiSectionMenu
25 id: wifiSectionMenu
plugins/Unity/Indicators/Network/qml/qmldir → plugins/Unity/IndicatorsLegacy/Network/qml/qmldirrenamed+1−1
@@ -1,4 +1,4 @@
1−module Unity.Indicators.Network
1+module Unity.IndicatorsLegacy.Network
2plugin IndicatorsNetworkQml
2plugin IndicatorsNetworkQml
3typeinfo plugin.qmltypes
3typeinfo plugin.qmltypes
4
4
plugins/Unity/Indicators/Network/secret-agent.c → plugins/Unity/IndicatorsLegacy/Network/secret-agent.crenamed

The content is the same.

plugins/Unity/Indicators/Network/secret-agent.h → plugins/Unity/IndicatorsLegacy/Network/secret-agent.hrenamed

The content is the same.

plugins/Unity/Indicators/flatmenuproxymodel.cpp → plugins/Unity/IndicatorsLegacy/flatmenuproxymodel.cpprenamed

The content is the same.

plugins/Unity/Indicators/flatmenuproxymodel.h → plugins/Unity/IndicatorsLegacy/flatmenuproxymodel.hrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/modelprinter.cppnew file+114
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+// self
21+#include "modelprinter.h"
22+
23+// Qt
24+#include <QTextStream>
25+
26+ModelPrinter::ModelPrinter(QObject *parent)
27+ : QObject(parent)
28+ , m_model(NULL)
29+{
30+}
31+
32+void ModelPrinter::setSourceModel(QAbstractItemModel * sourceModel)
33+{
34+ if (m_model != NULL) {
35+ disconnect(m_model);
36+ }
37+ if (m_model != sourceModel) {
38+ m_model = sourceModel;
39+ Q_EMIT modelChanged();
40+ Q_EMIT textChanged();
41+ }
42+ if (m_model != NULL) {
43+ connect(m_model, SIGNAL(modelReset()), this, SIGNAL(textChanged()));
44+ connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(textChanged()));
45+ connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(textChanged()));
46+ }
47+}
48+
49+QAbstractItemModel* ModelPrinter::sourceModel() const
50+{
51+ return m_model;
52+}
53+
54+QString ModelPrinter::text(const QModelIndex& index) const
55+{
56+ return recurseString(index, 0);
57+}
58+
59+QString tabify(int level) { QString str;
60+ for (int i = 0; i < level; i++) {
61+ str += " ";
62+ }
63+ return str;
64+}
65+
66+QString ModelPrinter::recurseString(const QModelIndex& index, int level) const
67+{
68+ if (!m_model)
69+ return "";
70+
71+ QString str;
72+ QTextStream stream(&str);
73+
74+ QHash<int, QByteArray> roleNames = m_model->roleNames();
75+ QList<int> roles = roleNames.keys();
76+ qSort(roles);
77+ Q_FOREACH(int role, roles) {
78+ QVariant vData = m_model->data(index, role);
79+ if (vData.canConvert(QMetaType::QVariantMap)) {
80+ QMapIterator<QString, QVariant> iter(vData.toMap());
81+ while (iter.hasNext()) {
82+ iter.next();
83+ stream << tabify(level)
84+ << roleNames[role]
85+ << "."
86+ << iter.key()
87+ << ": "
88+ << iter.value().toString()
89+ << endl;
90+ }
91+ }
92+ else {
93+ stream << tabify(level)
94+ << roleNames[role]
95+ << ": "
96+ << vData.toString()
97+ << endl;
98+ }
99+ }
100+
101+ int rowCount = m_model->rowCount(index);
102+ stream << tabify(level)
103+ << "child count"
104+ << ": "
105+ << rowCount
106+ << endl
107+ << endl;
108+
109+ for (int i = 0; i < rowCount; i++) {
110+ QModelIndex child = m_model->index(i, 0, index);
111+ str += recurseString(child, level+1);
112+ }
113+ return str;
114+}
plugins/Unity/IndicatorsLegacy/modelprinter.hnew file+50
@@ -0,0 +1,50 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef MODELPRINTER_H
21+#define MODELPRINTER_H
22+
23+#include <QSortFilterProxyModel>
24+
25+// This class acts as a namespace only, with the addition that its enums
26+// are registered to be exposed on the QML side.
27+class ModelPrinter : public QObject
28+{
29+ Q_OBJECT
30+
31+ Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
32+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
33+public:
34+ ModelPrinter(QObject* parent=0);
35+
36+ void setSourceModel(QAbstractItemModel* sourceModel);
37+ QAbstractItemModel* sourceModel() const;
38+
39+ Q_INVOKABLE QString text(const QModelIndex& index = QModelIndex()) const;
40+
41+Q_SIGNALS:
42+ void modelChanged();
43+ void textChanged();
44+
45+private:
46+ QString recurseString(const QModelIndex& index, int level) const;
47+ QAbstractItemModel* m_model;
48+};
49+
50+#endif // MODELPRINTER_H
plugins/Unity/IndicatorsLegacy/plugin.cppnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+// Qt
20+#include <QtQml>
21+
22+// self
23+#include "plugin.h"
24+
25+// local
26+#include "flatmenuproxymodel.h"
27+#include "indicators.h"
28+#include "modelprinter.h"
29+
30+void IndicatorsPlugin::registerTypes(const char *uri)
31+{
32+ Q_INIT_RESOURCE(indicators);
33+
34+ qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
35+ qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
36+
37+ qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
38+ qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
39+ qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
40+ qmlRegisterUncreatableType<IndicatorsModelRole>(uri, 0, 1, "IndicatorsModelRole", "Can't create IndicatorsModelRole class");
41+ qmlRegisterUncreatableType<FlatMenuProxyModelRole>(uri, 0, 1, "FlatMenuProxyModelRole", "Can't create FlatMenuProxyModelRole class");
42+}
plugins/Unity/IndicatorsLegacy/plugin.hnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef INDICATORS_PLUGIN_H
20+#define INDICATORS_PLUGIN_H
21+
22+#include <QtQml/QQmlExtensionPlugin>
23+
24+class IndicatorsPlugin : public QQmlExtensionPlugin
25+{
26+ Q_OBJECT
27+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28+public:
29+ void registerTypes(const char *uri);
30+};
31+
32+#endif // INDICATORS_PLUGIN_H
plugins/Unity/Indicators/qml/BasicMenuItem.qml → plugins/Unity/IndicatorsLegacy/qml/BasicMenuItem.qmlrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/qml/ButtonMenuItem.qmlnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+BasicMenuItem {
24+ id: buttonMenu
25+ color: "#221e1b"
26+ implicitHeight: units.gu(7)
27+
28+ Button {
29+ id: button
30+ enabled: menuAction.valid
31+ text: menu ? menu.label : ""
32+ anchors.centerIn: parent
33+ height: units.gu(4)
34+ width: units.gu(16)
35+ color: "#1b1817"
36+
37+ onClicked: {
38+ menuAction.activate()
39+ }
40+ }
41+
42+ MenuAction {
43+ id: menuAction
44+ actionGroup: buttonMenu.actionGroup
45+ action: menu ? menu.action : ""
46+ }
47+}
plugins/Unity/Indicators/Network/qml/CMakeLists.txt → plugins/Unity/IndicatorsLegacy/qml/CMakeLists.txtrenamed+1−1
@@ -2,4 +2,4 @@
2include(Plugins)
2include(Plugins)
3
3
4# export the qmldir, *.qml files.
4# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.Indicators.Network Unity/Indicators/Network)
5+export_qmlfiles(Unity.IndicatorsLegacy Unity/IndicatorsLegacy)
plugins/Unity/IndicatorsLegacy/qml/DivMenuItem.qmlnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Olivier Tilloy <olivier.tilloy@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Rectangle {
24+ color: "#181514"
25+ implicitHeight: units.gu(1)
26+}
plugins/Unity/IndicatorsLegacy/qml/HLine.qmlnew file+29
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Rectangle {
24+ height: units.dp(1)
25+ anchors {
26+ left: parent.left
27+ right: parent.right
28+ }
29+}
plugins/Unity/IndicatorsLegacy/qml/IndicatorBase.qmlnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import QMenuModel 0.1
23+import Unity.IndicatorsLegacy 0.1 as Indicators
24+
25+Item {
26+ id: indicatorItem
27+
28+ //const
29+ property string title
30+ property int busType
31+ property string busName
32+ property string actionsObjectPath
33+ property var menuObjectPaths: undefined
34+ readonly property string device: "phone"
35+
36+ property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
37+
38+ signal actionGroupUpdated()
39+ signal modelUpdated()
40+
41+ property var actionGroup: QDBusActionGroup {
42+ busType: indicatorItem.busType
43+ busName: indicatorItem.busName
44+ objectPath: indicatorItem.actionsObjectPath
45+
46+ onActionAppear: indicatorItem.actionGroupUpdated();
47+ }
48+
49+ property var proxyModel: Indicators.FlatMenuProxyModel {
50+ busType: indicatorItem.busType
51+ busName: indicatorItem.busName
52+ objectPath: indicatorItem.deviceMenuObjectPath
53+
54+ onStatusChanged: indicatorItem.modelUpdated();
55+ onRowsInserted: indicatorItem.modelUpdated();
56+ onRowsRemoved: indicatorItem.modelUpdated();
57+ onDataChanged: indicatorItem.modelUpdated();
58+ }
59+}
plugins/Unity/IndicatorsLegacy/qml/IndicatorPage.qmlnew file+191
@@ -0,0 +1,191 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1 as Components
23+
24+IndicatorBase {
25+ id: main
26+
27+ //const
28+ property alias emptyText: emptyLabel.text
29+ property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
30+ property bool __active: false
31+
32+ ListView {
33+ id: mainMenu
34+
35+ property int visibleItems: 0
36+
37+ model: proxyModel
38+ anchors {
39+ fill: parent
40+ bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
41+
42+ Behavior on bottomMargin {
43+ NumberAnimation {
44+ duration: 175
45+ easing.type: Easing.OutQuad
46+ }
47+ }
48+ // TODO - does ever frame.
49+ onBottomMarginChanged: {
50+ mainMenu.positionViewAtIndex(mainMenu.currentIndex, ListView.End)
51+ }
52+ }
53+
54+ // Ensure all delegates are cached in order to improve smoothness of scrolling
55+ cacheBuffer: 10000
56+
57+ // Only allow flicking if the content doesn't fit on the page
58+ interactive: contentHeight > height
59+
60+ currentIndex: -1
61+ delegate: Item {
62+ id: item
63+ property bool ready: false
64+ property alias empty: factory.empty
65+
66+ anchors {
67+ left: parent.left
68+ right: parent.right
69+ }
70+ height: div.height + factory.implicitHeight
71+ visible: height > 0
72+
73+ Component.onCompleted: {
74+ if (!item.empty) {
75+ mainMenu.visibleItems += 1;
76+ }
77+ ready = true;
78+ }
79+ Component.onDestruction: {
80+ if (!item.empty) {
81+ mainMenu.visibleItems -= 1;
82+ }
83+ ready = false;
84+ }
85+
86+ onEmptyChanged: {
87+ if (!ready) {
88+ return;
89+ }
90+ if (empty) {
91+ mainMenu.visibleItems -= 1;
92+ } else {
93+ mainMenu.visibleItems += 1;
94+ }
95+ }
96+
97+ ListView.onRemove: {
98+ if (!highlightFollowsCurrentItem) {
99+ mainMenu.currentIndex = -1;
100+ }
101+ }
102+
103+ Column {
104+ id: contents
105+
106+ anchors.fill: parent
107+
108+ DivMenuItem {
109+ id: div
110+
111+ anchors.left: parent.left
112+ anchors.right: parent.right
113+ // only visible if is a root or a section header element and the factory is visible
114+ height: {
115+ // skipe first item
116+ if (item.y == 0) {
117+ return 0;
118+ }
119+ if (hasSection || ((depth == 0) && (!factory.empty))) {
120+ return implicitHeight;
121+ } else {
122+ return 0;
123+ }
124+ }
125+ }
126+
127+ MenuItemFactory {
128+ id: factory
129+
130+ actionGroup: main.actionGroup
131+ isCurrentItem: item.ListView.isCurrentItem
132+ anchors {
133+ left: parent.left
134+ right: parent.right
135+ }
136+ menu: model
137+
138+ Connections {
139+ target : factory
140+ onActivated: item.ListView.view.currentIndex = index
141+ onDeactivated: item.ListView.view.currentIndex = -1
142+ }
143+ }
144+ }
145+ }
146+ }
147+
148+ Components.Label {
149+ id: emptyLabel
150+ visible: (mainMenu.visibleItems === 0)
151+ anchors {
152+ top: parent.top
153+ left: parent.left
154+ right: parent.right
155+ topMargin: units.gu(2)
156+ }
157+ wrapMode: Text.WordWrap
158+ horizontalAlignment: Text.AlignHCenter
159+
160+ //style
161+ color: "#e8e1d0"
162+ fontSize: "medium"
163+
164+ text: "Empty!"
165+ }
166+
167+ function start()
168+ {
169+ reset()
170+ if (!__active) {
171+ proxyModel.start();
172+ actionGroup.start();
173+ __active = true;
174+ }
175+ }
176+
177+ function stop()
178+ {
179+ if (__active) {
180+ __active = false;
181+ proxyModel.stop();
182+ actionGroup.stop();
183+ }
184+ }
185+
186+ function reset()
187+ {
188+ mainMenu.currentIndex = -1;
189+ mainMenu.positionViewAtBeginning();
190+ }
191+}
plugins/Unity/IndicatorsLegacy/qml/IndicatorWidget.qmlnew file+68
@@ -0,0 +1,68 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.IndicatorsLegacy 0.1 as Indicators
22+
23+IndicatorBase {
24+ id: indicatorWidget
25+
26+// enabled: false // FIXME : should be disabled until bus available when we have desktop indicators
27+ property var action: undefined
28+ property bool started: (busType != 0) && (busName != "") && (deviceMenuObjectPath != "")
29+ property int iconSize: height - units.gu(0.5)
30+ property string rootMenuType: "com.canonical.indicator.root"
31+
32+ signal actionStateChanged()
33+
34+ onStartedChanged: {
35+ if (started) {
36+ proxyModel.start();
37+ actionGroup.start();
38+ } else {
39+ proxyModel.stop();
40+ actionGroup.stop();
41+ }
42+ }
43+ onActionChanged: actionStateChanged()
44+ onActionGroupUpdated: update_state()
45+ onModelUpdated: update_state()
46+
47+
48+ function update_state() {
49+ var extra = proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Extra);
50+ if (extra == undefined) {
51+ return;
52+ }
53+
54+ if (!extra.hasOwnProperty("canonical_type")) {
55+ return;
56+ }
57+
58+ if (extra.canonical_type === rootMenuType) {
59+ action = actionGroup.action(proxyModel.data(0, Indicators.FlatMenuProxyModelRole.Action));
60+ }
61+ }
62+
63+ Connections {
64+ target: action == undefined ? null : action
65+ onStateChanged: actionStateChanged()
66+ onValidChanged: actionStateChanged()
67+ }
68+}
plugins/Unity/IndicatorsLegacy/qml/MenuAction.qmlnew file+86
@@ -0,0 +1,86 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+
22+/*!
23+ \qmltype MenuAction
24+ \inqmlmodule Indicators 0.1
25+ \brief Helper class to connect to a qmenumodel action
26+
27+ Example:
28+ \qml
29+ Button {
30+ id: slide
31+ onClick: { action.activate() }
32+ }
33+ MenuAction {
34+ id: action
35+ actionGroup: menuItem.actionGroup
36+ action: "/ubuntu/sound/enabled"
37+ }
38+ \endqml
39+*/
40+
41+Item {
42+ id: menuAction
43+
44+ /*!
45+ \preliminary
46+ The dbus action name
47+ */
48+ property string action: ""
49+
50+ /*!
51+ \preliminary
52+ The dbus action group object
53+ */
54+ property QtObject actionGroup: null
55+
56+ /*!
57+ \preliminary
58+ This is a read-only property with the current validity of the action
59+ */
60+ readonly property bool valid: actionObject ? actionObject.valid : false
61+
62+ readonly property var state: actionObject ? actionObject.state : undefined
63+
64+ // internal
65+ property QtObject actionObject: null
66+
67+ function activate(param) {
68+ if (valid) {
69+ actionObject.activate(param);
70+ }
71+ }
72+
73+ onActionGroupChanged: updateAction()
74+ onActionChanged: updateAction()
75+
76+ Connections {
77+ target: menuAction.actionGroup != undefined ? menuAction.actionGroup : null
78+ onActionAppear: menuAction.updateAction();
79+ onActionVanish: menuAction.updateAction();
80+ onStatusChanged: menuAction.updateAction();
81+ }
82+
83+ function updateAction() {
84+ actionObject = action !== "" && actionGroup ? actionGroup.action(action) : null
85+ }
86+}
plugins/Unity/Indicators/qml/MenuActionBinding.qml → plugins/Unity/IndicatorsLegacy/qml/MenuActionBinding.qmlrenamed

The content is the same.

plugins/Unity/Indicators/qml/MenuItem.qml → plugins/Unity/IndicatorsLegacy/qml/MenuItem.qmlrenamed

The content is the same.

plugins/Unity/IndicatorsLegacy/qml/MenuItemFactory.qmlnew file+110
@@ -0,0 +1,110 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.IndicatorsLegacy 0.1 as Indicators
22+import Unity.IndicatorsLegacy.Messaging 0.1 as ICMessaging
23+import Unity.IndicatorsLegacy.Network 0.1 as ICNetwork
24+
25+Item {
26+ id: menuFactory
27+
28+ property QtObject menu
29+ property QtObject listView
30+ property QtObject actionGroup
31+ property bool isCurrentItem
32+ readonly property bool empty: (loader.item !== undefined && loader.status == Loader.Ready) ? loader.item.state === "EMPTY" : true
33+
34+ implicitHeight: loader.height
35+
36+ signal activated()
37+ signal deactivated()
38+
39+ property var _map: {
40+ "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
41+ "unity.widgets.systemsettings.tablet.switch" : switchMenu,
42+
43+ "com.canonical.indicator.button" : buttonMenu,
44+ "com.canonical.indicator.div" : divMenu,
45+ "com.canonical.indicator.section" : sectionMenu,
46+ "com.canonical.indicator.progress" : progressMenu,
47+ "com.canonical.indicator.slider" : sliderMenu,
48+ "com.canonical.indicator.switch" : switchMenu,
49+
50+ "com.canonical.indicator.messages.messageitem" : messageItem,
51+ "com.canonical.indicator.messages.snapdecision" : snapDecision,
52+ "com.canonical.indicator.messages.sourceitem" : groupedMessage,
53+
54+ "unity.widget.systemsettings.tablet.sectiontitle" : wifiSection,
55+ "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
56+ "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
57+ }
58+
59+ Component { id: sliderMenu; Indicators.SliderMenuItem {} }
60+ Component { id: switchMenu; Indicators.SwitchMenuItem {} }
61+ Component { id: buttonMenu; Indicators.ButtonMenuItem {} }
62+ Component { id: divMenu; Indicators.DivMenuItem {} }
63+ Component { id: sectionMenu; Indicators.SectionMenuItem {} }
64+ Component { id: progressMenu; Indicators.ProgressMenuItem {} }
65+ Component { id: messageItem; ICMessaging.MessageMenuItem {} }
66+ Component { id: snapDecision; ICMessaging.SnapDecision {} }
67+ Component { id: groupedMessage; ICMessaging.GroupedMessage {} }
68+ Component { id: wifiSection; ICNetwork.WifiSection {} }
69+ Component { id: accessPoint; ICNetwork.AccessPoint {} }
70+ Component { id: indicatorMenu; Indicators.MenuItem {} }
71+
72+ Loader {
73+ id: loader
74+ asynchronous: true
75+
76+ anchors {
77+ left: parent.left
78+ right: parent.right
79+ }
80+
81+ sourceComponent: {
82+ if (!menuFactory.menu || !menuFactory.menu.extra) {
83+ return undefined;
84+ }
85+
86+ var widgetType = menuFactory.menu.extra.canonical_type;
87+ if (widgetType) {
88+ return _map[widgetType];
89+ } else {
90+ if (widgetType === "com.canonical.indicator.root") {
91+ return undefined;
92+ // Try discovery the item based on the basic properties
93+ } else if (menu.hasSection) {
94+ return sectionMenu;
95+ } else {
96+ return indicatorMenu;
97+ }
98+ }
99+ }
100+
101+ onLoaded: {
102+ item.menuActivated = Qt.binding(function() { return isCurrentItem; });
103+ item.actionGroup = Qt.binding(function() { return menuFactory.actionGroup; });
104+ item.menu = Qt.binding(function() { return menuFactory.menu; });
105+
106+ item.activateMenu.connect(function() { menuFactory.activated(); });
107+ item.deactivateMenu.connect(function() { menuFactory.deactivated(); });
108+ }
109+ }
110+}
plugins/Unity/IndicatorsLegacy/qml/ProgressMenuItem.qmlnew file+65
@@ -0,0 +1,65 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Michael Zanetti <michael.zanetti@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+MenuItem {
24+ id: progressMenu
25+ property alias value : progressBar.value
26+
27+ // TODO: Replace this with the official ProgressBar component as soon as
28+ // it is available. For now, this rebuilds the Mockup as close as possible.
29+ UbuntuShape {
30+ id: progressBar
31+ anchors {
32+ right: parent.right
33+ rightMargin: units.gu(2)
34+ left: parent.left
35+ leftMargin: units.gu(2)
36+ }
37+ height: units.gu(4)
38+ anchors.verticalCenter: parent.verticalCenter
39+ color: "transparent"
40+
41+ property int minimumValue: 0
42+ property int maximumValue: 100
43+ property int value: 50
44+
45+ UbuntuShape {
46+ anchors.fill: parent
47+ anchors.rightMargin: parent.width - (parent.width * parent.value / parent.maximumValue)
48+ color: "#c94212"
49+ }
50+
51+ Label {
52+ anchors.centerIn: parent
53+ text: parent.value + " %"
54+ fontSize: "medium"
55+ color: "#e8e1d0"
56+ }
57+ }
58+
59+ MenuActionBinding {
60+ actionGroup: progressMenu.actionGroup
61+ action: menu ? menu.action : ""
62+ target: progressBar
63+ property: "value"
64+ }
65+}
plugins/Unity/IndicatorsLegacy/qml/RemoveBackground.qmlnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Rectangle {
21+ anchors.fill: parent
22+ color: "#333130"
23+ Label {
24+ id: backgroundText
25+
26+ anchors.fill: parent
27+ verticalAlignment: Text.AlignVCenter
28+ text: "Clear"
29+ fontSize: "medium"
30+ color: "#e8e1d0"
31+ font.bold: true
32+ }
33+
34+ states: [
35+ State {
36+ name: "SwipingRight"
37+ PropertyChanges {
38+ target: backgroundText
39+ anchors.rightMargin: units.gu(3)
40+ anchors.leftMargin: 0
41+ horizontalAlignment: Text.AlignRight
42+
43+ }
44+ },
45+ State {
46+ name: "SwipingLeft"
47+ PropertyChanges {
48+ target: backgroundText
49+ anchors.rightMargin: 0
50+ anchors.leftMargin: units.gu(3)
51+ horizontalAlignment: Text.AlignLeft
52+ }
53+ }
54+ ]
55+}
plugins/Unity/IndicatorsLegacy/qml/SectionMenuItem.qmlnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23+
24+BasicMenuItem {
25+ property string label: menu && menu.label ? menu.label : ""
26+ property bool busy: false
27+ property int count: menu && menu.linkSection ? menu.linkSection.count : 0
28+
29+ color: "#221e1b"
30+ implicitHeight: label !== "" ? __header.height : 0
31+ state: count === 0 ? "EMPTY" : ""
32+
33+ ListItem.Header {
34+ id: __header
35+
36+ text: label
37+ height: units.gu(4)
38+ anchors {
39+ left: parent.left
40+ right: parent.right
41+ top: parent.top
42+ }
43+ visible: text != ""
44+
45+ ActivityIndicator {
46+ id: indicator
47+ running: busy
48+ anchors {
49+ margins: units.gu(0.5)
50+ right: parent.right
51+ }
52+ height: parent.height - (anchors.margins * 2)
53+ width: height
54+ anchors.verticalCenter: parent.verticalCenter
55+ }
56+ }
57+}
plugins/Unity/IndicatorsLegacy/qml/SliderMenuItem.qmlnew file+64
@@ -0,0 +1,64 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+MenuItem {
24+ id: _sliderMenu
25+
26+ property alias minimumValue: slider.minimumValue
27+ property alias maximumValue: slider.maximumValue
28+ property alias value: slider.value
29+
30+ control: Slider {
31+ id: slider
32+ enabled: menuAction.valid
33+ width: _sliderMenu.text ? units.gu(20) : _sliderMenu.width - units.gu(4)
34+ anchors.verticalCenter: parent.verticalCenter
35+ live: false
36+ // FIXME: The interval should be [0.0 - 1.0]. Unfortunately, when
37+ // reaching the boundaries (0.0 or 1.0), the value is converted
38+ // to an integer when automatically wrapped in a variant when
39+ // passed to QStateAction::updateState(…). The server chokes on
40+ // those values, complaining that they’re not of the right type…
41+ minimumValue: menu.extra.canonical_min ? menu.extra.canonical_min * 1.000001 : 0.0000001
42+ maximumValue: {
43+ var maximum = menu.extra.canonical_max ? menu.extra.canonical_max * 1.000001 : 0.9999999
44+ if (maximum <= minimumValue) {
45+ return minimumValue + 1;
46+ }
47+ return maximum;
48+ }
49+
50+ // FIXME - to be deprecated in Ubuntu.Components.
51+ // Use this to disable the label, since there is not way to do it on the component.
52+ function formatValue(v) {
53+ return "";
54+ }
55+ }
56+
57+ MenuActionBinding {
58+ id: menuAction
59+ actionGroup: _sliderMenu.actionGroup
60+ action: menu ? menu.action : ""
61+ target: slider
62+ property: "value"
63+ }
64+}
plugins/Unity/IndicatorsLegacy/qml/SwitchMenuItem.qmlnew file+43
@@ -0,0 +1,43 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+MenuItem {
24+ id: switchMenu
25+
26+ property alias checked: switcher.checked
27+
28+ control: Switch {
29+ id: switcher
30+ enabled: menuAction.valid
31+
32+ anchors.verticalCenter: parent.verticalCenter
33+ anchors.right: parent.right
34+ }
35+
36+ MenuActionBinding {
37+ id: menuAction
38+ actionGroup: switchMenu.actionGroup
39+ action: menu ? menu.action : ""
40+ target: switcher
41+ property: "checked"
42+ }
43+}
plugins/Unity/IndicatorsLegacy/qml/qmldirnew file+21
@@ -0,0 +1,21 @@
1+module Unity.IndicatorsLegacy
2+plugin IndicatorsLegacyQml
3+typeinfo plugin.qmltypes
4+
5+BasicMenuItem 0.1 BasicMenuItem.qml
6+ButtonMenuItem 0.1 ButtonMenuItem.qml
7+DivMenuItem 0.1 DivMenuItem.qml
8+HLine 0.1 HLine.qml
9+IndicatorBase 0.1 IndicatorBase.qml
10+IndicatorPage 0.1 IndicatorPage.qml
11+IndicatorWidget 0.1 IndicatorWidget.qml
12+MenuItem 0.1 MenuItem.qml
13+MenuAction 0.1 MenuAction.qml
14+MenuActionBinding 0.1 MenuActionBinding.qml
15+MenuItemFactory 0.1 MenuItemFactory.qml
16+ProgressMenuItem 0.1 ProgressMenuItem.qml
17+SectionMenuItem 0.1 SectionMenuItem.qml
18+SliderMenuItem 0.1 SliderMenuItem.qml
19+SwitchMenuItem 0.1 SwitchMenuItem.qml
20+
21+internal RemoveBackground RemoveBackground.qml
plugins/Unity/Indicators/resources/artwork/messaging/default_app.svg → plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/default_app.svgrenamed

The content is the same.

plugins/Unity/Indicators/resources/artwork/messaging/default_contact.png → plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/default_contact.pngrenamed

Binary file not shown.

plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.png → plugins/Unity/IndicatorsLegacy/resources/artwork/messaging/message_sms01_54px.pngrenamed

Binary file not shown.

plugins/Unity/Indicators/resources/indicators.qrc → plugins/Unity/IndicatorsLegacy/resources/indicators.qrcrenamed

The content is the same.

plugins/Unity/abstractfilteroption.cppnew file+25
@@ -0,0 +1,25 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "abstractfilteroption.h"
21+
22+AbstractFilterOption::AbstractFilterOption(QObject *parent)
23+ : QObject(parent)
24+{
25+}
plugins/Unity/abstractfilteroption.hnew file+58
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef ABSTRACTFILTEROPTION_H
21+#define ABSTRACTFILTEROPTION_H
22+
23+// Qt
24+#include <QObject>
25+#include <QMetaType>
26+
27+class Q_DECL_EXPORT AbstractFilterOption : public QObject
28+{
29+ Q_OBJECT
30+
31+ Q_PROPERTY(QString id READ id NOTIFY idChanged)
32+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
33+ Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
34+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
35+
36+public:
37+ /* getters */
38+ virtual QString id() const = 0;
39+ virtual QString name() const = 0;
40+ virtual QString iconHint() const = 0;
41+ virtual bool active() const = 0;
42+
43+ /* setters */
44+ virtual void setActive(bool active) = 0;
45+
46+protected:
47+ AbstractFilterOption(QObject *parent);
48+
49+Q_SIGNALS:
50+ void idChanged(const QString &);
51+ void nameChanged(const QString &);
52+ void iconHintChanged(const QString &);
53+ void activeChanged(bool);
54+};
55+
56+Q_DECLARE_METATYPE(AbstractFilterOption*)
57+
58+#endif // ABSTRACTFILTEROPTION_H
plugins/Unity/categories.cpp+66
@@ -104,6 +104,25 @@ Categories::onCountChanged()
104 }
104 }
105}
105}
106
106
107+void Categories::onRowCountChanged()
108+{
109+ QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
110+ // find the corresponding category index
111+ for (auto iter = m_overriddenCategories.begin(); iter != m_overriddenCategories.end(); ++iter) {
112+ if (iter.value() == model) {
113+ for (int i = 0; i < rowCount(); i++) {
114+ auto id = data(index(i), RoleCategoryId).toString();
115+ if (id != iter.key()) continue;
116+ QVector<int> roles;
117+ roles.append(RoleCount);
118+ QModelIndex changedIndex = index(i);
119+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
120+ break;
121+ }
122+ }
123+ }
124+}
125+
107void
126void
108Categories::onEmitCountChanged()
127Categories::onEmitCountChanged()
109{
128{
@@ -123,6 +142,41 @@ Categories::roleNames() const
123 return m_roles;
142 return m_roles;
124}
143}
125
144
145+void Categories::onOverrideModelDestroyed()
146+{
147+ QObject* model = sender();
148+ auto iter = m_overriddenCategories.begin();
149+ while (iter != m_overriddenCategories.end()) {
150+ if (iter.value() == model) {
151+ iter = m_overriddenCategories.erase(iter);
152+ continue;
153+ }
154+ ++iter;
155+ }
156+}
157+
158+void Categories::overrideResults(const QString& categoryId, QAbstractItemModel* model)
159+{
160+ m_overriddenCategories[categoryId] = model;
161+ // watch the model
162+ connect(model, &QObject::destroyed, this, &Categories::onOverrideModelDestroyed);
163+ connect(model, &QAbstractItemModel::rowsInserted, this, &Categories::onRowCountChanged);
164+ connect(model, &QAbstractItemModel::rowsRemoved, this, &Categories::onRowCountChanged);
165+ connect(model, &QAbstractItemModel::modelReset, this, &Categories::onRowCountChanged);
166+
167+ // emit the dataChanged signal if the category is already in the model
168+ for (int i = 0; i < rowCount(); i++) {
169+ auto id = data(index(i), RoleCategoryId).toString();
170+ if (id != categoryId) continue;
171+ QVector<int> roles;
172+ roles.append(RoleCount);
173+ roles.append(RoleResults);
174+ QModelIndex changedIndex = index(i);
175+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
176+ break;
177+ }
178+}
179+
126QVariant
180QVariant
127Categories::data(const QModelIndex& index, int role) const
181Categories::data(const QModelIndex& index, int role) const
128{
182{
@@ -147,8 +201,20 @@ Categories::data(const QModelIndex& index, int role) const
147 case RoleHints:
201 case RoleHints:
148 return DeeListModel::data(index, CategoryColumn::HINTS);
202 return DeeListModel::data(index, CategoryColumn::HINTS);
149 case RoleResults:
203 case RoleResults:
204+ if (m_overriddenCategories.size() > 0)
205+ {
206+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
207+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
208+ return QVariant::fromValue(m_overriddenCategories[id]);
209+ }
150 return QVariant::fromValue(getResults(index.row()));
210 return QVariant::fromValue(getResults(index.row()));
151 case RoleCount:
211 case RoleCount:
212+ if (m_overriddenCategories.size() > 0)
213+ {
214+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
215+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
216+ return QVariant::fromValue(m_overriddenCategories[id]->rowCount());
217+ }
152 return QVariant::fromValue(getResults(index.row())->rowCount());
218 return QVariant::fromValue(getResults(index.row())->rowCount());
153 case RoleCategoryIndex:
219 case RoleCategoryIndex:
154 return QVariant::fromValue(index.row());
220 return QVariant::fromValue(index.row());
plugins/Unity/categories.h+5
@@ -53,6 +53,8 @@ public:
53 RoleCategoryIndex
53 RoleCategoryIndex
54 };
54 };
55
55
56+ Q_INVOKABLE void overrideResults(const QString& categoryId, QAbstractItemModel* model);
57+
56 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
58 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
57
59
58 QHash<int, QByteArray> roleNames() const;
60 QHash<int, QByteArray> roleNames() const;
@@ -62,7 +64,9 @@ public:
62
64
63private Q_SLOTS:
65private Q_SLOTS:
64 void onCountChanged();
66 void onCountChanged();
67+ void onRowCountChanged();
65 void onEmitCountChanged();
68 void onEmitCountChanged();
69+ void onOverrideModelDestroyed();
66
70
67private:
71private:
68 void onCategoriesModelChanged(unity::glib::Object<DeeModel> model);
72 void onCategoriesModelChanged(unity::glib::Object<DeeModel> model);
@@ -73,6 +77,7 @@ private:
73 QTimer m_timer;
77 QTimer m_timer;
74 QSet<int> m_updatedCategories;
78 QSet<int> m_updatedCategories;
75 QHash<int, QByteArray> m_roles;
79 QHash<int, QByteArray> m_roles;
80+ QMap<QString, QAbstractItemModel*> m_overriddenCategories;
76 mutable QMap<int, DeeListModel*> m_results;
81 mutable QMap<int, DeeListModel*> m_results;
77 sigc::connection m_categoriesChangedConnection;
82 sigc::connection m_categoriesChangedConnection;
78};
83};
plugins/Unity/checkoptionfilter.cppnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2011 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// Self
21+#include "checkoptionfilter.h"
22+
23+// local
24+#include "unityoptionsmodel.h"
25+
26+CheckOptionFilter::CheckOptionFilter(QObject *parent) :
27+ Filter(parent),
28+ m_unityCheckOptionFilter(nullptr),
29+ m_options(nullptr)
30+{
31+}
32+
33+GenericOptionsModel* CheckOptionFilter::options() const
34+{
35+ return m_options;
36+}
37+
38+void CheckOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
39+{
40+ Filter::setUnityFilter(filter);
41+ m_unityCheckOptionFilter = std::dynamic_pointer_cast<unity::dash::CheckOptionFilter>(m_unityFilter);
42+ onOptionsChanged(m_unityCheckOptionFilter->options);
43+}
44+
45+void CheckOptionFilter::onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions options)
46+{
47+ if (m_options != nullptr) {
48+ m_signals.disconnectAll();
49+ delete m_options;
50+ m_options = nullptr;
51+ }
52+
53+ m_options = new UnityOptionsModel(this, options,
54+ m_unityCheckOptionFilter->option_added,
55+ m_unityCheckOptionFilter->option_removed);
56+
57+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
58+
59+ /* Property change signals */
60+ m_signals << m_unityCheckOptionFilter->options.changed.connect(sigc::mem_fun(this, &CheckOptionFilter::onOptionsChanged));
61+
62+ Q_EMIT optionsChanged();
63+}
plugins/Unity/checkoptionfilter.hnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright (C) 2011 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef CHECKOPTIONFILTER_H
21+#define CHECKOPTIONFILTER_H
22+
23+// Qt
24+#include <QObject>
25+#include <QMetaType>
26+
27+// libunity-core
28+#include <UnityCore/CheckOptionFilter.h>
29+
30+// Local
31+#include "filter.h"
32+#include "signalslist.h"
33+
34+class Q_DECL_EXPORT CheckOptionFilter : public Filter
35+{
36+ Q_OBJECT
37+
38+public:
39+ explicit CheckOptionFilter(QObject *parent = nullptr);
40+
41+ /* getters */
42+ GenericOptionsModel* options() const override;
43+
44+protected:
45+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
46+
47+private:
48+ void onOptionsChanged(unity::dash::CheckOptionFilter::CheckOptions filter);
49+
50+ unity::dash::CheckOptionFilter::Ptr m_unityCheckOptionFilter;
51+ SignalsList m_signals;
52+ GenericOptionsModel* m_options;
53+};
54+
55+Q_DECLARE_METATYPE(CheckOptionFilter*)
56+
57+#endif // CHECKOPTIONFILTER_H
plugins/Unity/filter.cppnew file+129
@@ -0,0 +1,129 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// Self
22+#include "filter.h"
23+
24+// local
25+#include "ratingsfilter.h"
26+#include "radiooptionfilter.h"
27+#include "checkoptionfilter.h"
28+#include "multirangefilter.h"
29+
30+// libunity-core
31+#include <UnityCore/Filter.h>
32+#include <UnityCore/RatingsFilter.h>
33+#include <UnityCore/RadioOptionFilter.h>
34+#include <UnityCore/CheckOptionFilter.h>
35+#include <UnityCore/MultiRangeFilter.h>
36+
37+// Qt
38+#include <QDebug>
39+
40+Filter::Filter(QObject *parent) :
41+ QObject(parent)
42+{
43+}
44+
45+QString Filter::id() const
46+{
47+ if (!m_unityFilter)
48+ return QString::Null();
49+ return QString::fromStdString(m_unityFilter->id());
50+}
51+
52+QString Filter::name() const
53+{
54+ if (!m_unityFilter)
55+ return QString::Null();
56+ return QString::fromStdString(m_unityFilter->name());
57+}
58+
59+QString Filter::iconHint() const
60+{
61+ if (!m_unityFilter)
62+ return QString::Null();
63+ return QString::fromStdString(m_unityFilter->icon_hint());
64+}
65+
66+QString Filter::rendererName() const
67+{
68+ if (!m_unityFilter)
69+ return QString::Null();
70+ return QString::fromStdString(m_unityFilter->renderer_name());
71+}
72+
73+bool Filter::visible() const
74+{
75+ if (!m_unityFilter)
76+ return false;
77+ return m_unityFilter->visible();
78+}
79+
80+bool Filter::collapsed() const
81+{
82+ if (!m_unityFilter)
83+ return false;
84+ return m_unityFilter->collapsed();
85+}
86+
87+bool Filter::filtering() const
88+{
89+ if (!m_unityFilter)
90+ return false;
91+ return m_unityFilter->filtering();
92+}
93+
94+void Filter::clear()
95+{
96+ if (m_unityFilter)
97+ m_unityFilter->Clear();
98+}
99+
100+void Filter::setUnityFilter(unity::dash::Filter::Ptr unityFilter)
101+{
102+ m_unityFilter = unityFilter;
103+}
104+
105+Filter* Filter::newFromUnityFilter(unity::dash::Filter::Ptr unityFilter)
106+{
107+ Filter* filter;
108+
109+ if (typeid(*unityFilter) == typeid(unity::dash::RatingsFilter)) {
110+ filter = new RatingsFilter;
111+ } else if (typeid(*unityFilter) == typeid(unity::dash::CheckOptionFilter)) {
112+ filter = new CheckOptionFilter;
113+ } else if (typeid(*unityFilter) == typeid(unity::dash::RadioOptionFilter)) {
114+ filter = new RadioOptionFilter;
115+ } else if (typeid(*unityFilter) == typeid(unity::dash::MultiRangeFilter)) {
116+ filter = new MultiRangeFilter;
117+ } else {
118+ qWarning() << "Filter of unknown type: " << typeid(*unityFilter).name();
119+ return nullptr;
120+ }
121+
122+ filter->setUnityFilter(unityFilter);
123+ return filter;
124+}
125+
126+bool Filter::hasUnityFilter(unity::dash::Filter::Ptr unityFilter) const
127+{
128+ return m_unityFilter == unityFilter;
129+}
plugins/Unity/filter.hnew file+74
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef FILTER_H
22+#define FILTER_H
23+
24+// Qt
25+#include <QObject>
26+#include <QMetaType>
27+
28+// libunity-core
29+#include <UnityCore/Filter.h>
30+
31+class GenericOptionsModel;
32+
33+class Q_DECL_EXPORT Filter : public QObject
34+{
35+ Q_OBJECT
36+
37+ Q_PROPERTY(QString id READ id CONSTANT)
38+ Q_PROPERTY(QString name READ name CONSTANT)
39+ Q_PROPERTY(QString iconHint READ iconHint CONSTANT)
40+ Q_PROPERTY(QString rendererName READ rendererName CONSTANT)
41+ Q_PROPERTY(bool visible READ visible CONSTANT)
42+ Q_PROPERTY(bool collapsed READ collapsed CONSTANT)
43+ Q_PROPERTY(bool filtering READ filtering CONSTANT)
44+ Q_PROPERTY(GenericOptionsModel* options READ options NOTIFY optionsChanged)
45+
46+public:
47+ explicit Filter(QObject *parent = nullptr);
48+
49+ /* getters */
50+ QString id() const;
51+ QString name() const;
52+ QString iconHint() const;
53+ QString rendererName() const;
54+ bool visible() const;
55+ bool collapsed() const;
56+ bool filtering() const;
57+ virtual GenericOptionsModel* options() const = 0;
58+
59+ Q_INVOKABLE void clear();
60+
61+ static Filter* newFromUnityFilter(unity::dash::Filter::Ptr unityFilter);
62+ bool hasUnityFilter(unity::dash::Filter::Ptr unityFilter) const;
63+
64+Q_SIGNALS:
65+ void optionsChanged();
66+
67+protected:
68+ unity::dash::Filter::Ptr m_unityFilter;
69+ virtual void setUnityFilter(unity::dash::Filter::Ptr unityFilter);
70+};
71+
72+Q_DECLARE_METATYPE(Filter*)
73+
74+#endif // FILTER_H
plugins/Unity/filteroption.cppnew file+91
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// Self
22+#include "filteroption.h"
23+
24+// libunity-core
25+#include <UnityCore/Filter.h>
26+
27+FilterOption::FilterOption(unity::dash::FilterOption::Ptr unityFilterOption, QObject *parent) :
28+ AbstractFilterOption(parent), m_unityFilterOption(nullptr)
29+{
30+ setUnityFilterOption(unityFilterOption);
31+}
32+
33+QString FilterOption::id() const
34+{
35+ return QString::fromStdString(m_unityFilterOption->id());
36+}
37+
38+QString FilterOption::name() const
39+{
40+ return QString::fromStdString(m_unityFilterOption->name());
41+}
42+
43+QString FilterOption::iconHint() const
44+{
45+ return QString::fromStdString(m_unityFilterOption->icon_hint());
46+}
47+
48+bool FilterOption::active() const
49+{
50+ return m_unityFilterOption->active();
51+}
52+
53+void FilterOption::setActive(bool active)
54+{
55+ m_unityFilterOption->active = active;
56+}
57+
58+void FilterOption::setUnityFilterOption(unity::dash::FilterOption::Ptr unityFilterOption)
59+{
60+ if (m_unityFilterOption != nullptr) {
61+ m_signals.disconnectAll();
62+ }
63+
64+ m_unityFilterOption = unityFilterOption;
65+
66+ /* Property change signals */
67+ m_signals << m_unityFilterOption->id.changed.connect(sigc::mem_fun(this, &FilterOption::onIdChanged))
68+ << m_unityFilterOption->name.changed.connect(sigc::mem_fun(this, &FilterOption::onNameChanged))
69+ << m_unityFilterOption->icon_hint.changed.connect(sigc::mem_fun(this, &FilterOption::onIconHintChanged))
70+ << m_unityFilterOption->active.changed.connect(sigc::mem_fun(this, &FilterOption::onActiveChanged));
71+}
72+
73+void FilterOption::onIdChanged(const std::string &id)
74+{
75+ Q_EMIT idChanged(QString::fromStdString(id));
76+}
77+
78+void FilterOption::onNameChanged(const std::string &name)
79+{
80+ Q_EMIT nameChanged(QString::fromStdString(name));
81+}
82+
83+void FilterOption::onIconHintChanged(const std::string &iconHint)
84+{
85+ Q_EMIT iconHintChanged(QString::fromStdString(iconHint));
86+}
87+
88+void FilterOption::onActiveChanged(bool active)
89+{
90+ Q_EMIT activeChanged(active);
91+}
plugins/Unity/filteroption.hnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef FILTEROPTION_H
22+#define FILTEROPTION_H
23+
24+// Local
25+#include "abstractfilteroption.h"
26+#include "signalslist.h"
27+
28+// libunity-core
29+#include <UnityCore/Filter.h>
30+
31+class Q_DECL_EXPORT FilterOption : public AbstractFilterOption
32+{
33+ Q_OBJECT
34+
35+public:
36+ explicit FilterOption(unity::dash::FilterOption::Ptr unityFilterOption, QObject *parent = nullptr);
37+
38+ /* getters */
39+ QString id() const override;
40+ QString name() const override;
41+ QString iconHint() const override;
42+ bool active() const override;
43+
44+ /* setters */
45+ void setActive(bool active) override;
46+
47+private:
48+ void onIdChanged(const std::string &id);
49+ void onNameChanged(const std::string &name);
50+ void onIconHintChanged(const std::string &iconHint);
51+ void onActiveChanged(bool active);
52+
53+ void setUnityFilterOption(unity::dash::FilterOption::Ptr unityFilterOption);
54+ SignalsList m_signals;
55+
56+ unity::dash::FilterOption::Ptr m_unityFilterOption;
57+};
58+
59+Q_DECLARE_METATYPE(FilterOption*)
60+
61+#endif // FILTEROPTION_H
plugins/Unity/filters.cppnew file+161
@@ -0,0 +1,161 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// Self
22+#include "filters.h"
23+
24+// Local
25+#include "filter.h"
26+
27+// Qt
28+#include <QDebug>
29+
30+Filters::Filters(unity::dash::Filters::Ptr unityFilters, QObject *parent) :
31+ QAbstractListModel(parent), m_unityFilters(unityFilters)
32+{
33+ for (unsigned int i=0; i<m_unityFilters->count(); i++) {
34+ unity::dash::Filter::Ptr unityFilter = m_unityFilters->FilterAtIndex(i);
35+ addFilter(unityFilter, i);
36+ }
37+ m_unityFilters->filter_added.connect(sigc::mem_fun(this, &Filters::onFilterAdded));
38+ m_unityFilters->filter_changed.connect(sigc::mem_fun(this, &Filters::onFilterChanged));
39+ m_unityFilters->filter_removed.connect(sigc::mem_fun(this, &Filters::onFilterRemoved));
40+}
41+
42+Filters::~Filters()
43+{
44+ while (!m_filters.isEmpty()) {
45+ delete m_filters.takeFirst();
46+ }
47+}
48+
49+int Filters::rowCount(const QModelIndex& parent) const
50+{
51+ Q_UNUSED(parent)
52+
53+ return m_unityFilters->count();
54+}
55+
56+QVariant Filters::data(const QModelIndex& index, int role) const
57+{
58+ if (!index.isValid()) {
59+ return QVariant();
60+ }
61+
62+ Filter* filter = m_filters.at(index.row());
63+ switch (role)
64+ {
65+ case Filters::RoleId:
66+ return filter->id();
67+ case Filters::RoleName:
68+ case Qt::DisplayRole:
69+ return filter->name();
70+ case Filters::RoleIconHint:
71+ return filter->iconHint();
72+ case Filters::RoleRendererName:
73+ return filter->rendererName();
74+ case Filters::RoleVisible:
75+ return filter->visible();
76+ case Filters::RoleCollapsed:
77+ return filter->collapsed();
78+ case Filters::RoleFiltering:
79+ return filter->filtering();
80+ default:
81+ break;
82+ }
83+ return QVariant();
84+}
85+
86+QHash<int, QByteArray> Filters::roleNames() const
87+{
88+ QHash<int, QByteArray> roles;
89+ roles[Filters::RoleId] = "id";
90+ roles[Filters::RoleName] = "name";
91+ roles[Filters::RoleIconHint] = "iconHint";
92+ roles[Filters::RoleRendererName] = "rendererName";
93+ roles[Filters::RoleVisible] = "visible";
94+ roles[Filters::RoleCollapsed] = "collapsed";
95+ roles[Filters::RoleFiltering] = "filtering";
96+ return roles;
97+}
98+
99+Filter* Filters::getFilter(const QString& id) const
100+{
101+ Q_FOREACH (Filter* filter, m_filters) {
102+ if (filter->id() == id) {
103+ return filter;
104+ }
105+ }
106+ return nullptr;
107+}
108+
109+void Filters::onFilterAdded(unity::dash::Filter::Ptr unityFilter)
110+{
111+ if (unityFilter == nullptr) {
112+ return;
113+ }
114+
115+ int index = m_filters.count();
116+ addFilter(unityFilter, index);
117+}
118+
119+void Filters::onFilterChanged(unity::dash::Filter::Ptr unityFilter)
120+{
121+ if (unityFilter == nullptr) {
122+ return;
123+ }
124+
125+ QModelIndex filterIndex = index(indexForFilter(unityFilter));
126+ Q_EMIT dataChanged(filterIndex, filterIndex);
127+}
128+
129+void Filters::onFilterRemoved(unity::dash::Filter::Ptr unityFilter)
130+{
131+ removeFilter(indexForFilter(unityFilter));
132+}
133+
134+void Filters::addFilter(unity::dash::Filter::Ptr unityFilter, int index)
135+{
136+ beginInsertRows(QModelIndex(), index, index);
137+ Filter* filter = Filter::newFromUnityFilter(unityFilter);
138+ if (filter != nullptr) {
139+ m_filters.insert(index, filter);
140+ }
141+ endInsertRows();
142+}
143+
144+void Filters::removeFilter(int index)
145+{
146+ beginRemoveRows(QModelIndex(), index, index);
147+ Filter* filter = m_filters.takeAt(index);
148+ delete filter;
149+ endRemoveRows();
150+}
151+
152+int Filters::indexForFilter(unity::dash::Filter::Ptr unityFilter)
153+{
154+ for (int index=0; index<m_filters.count(); index++) {
155+ if (m_filters[index]->hasUnityFilter(unityFilter)) {
156+ return index;
157+ }
158+ }
159+ qWarning() << "Filter" << QString::fromStdString(unityFilter->name()) << "not found in local cache.";
160+ return -1;
161+}
plugins/Unity/filters.hnew file+76
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef FILTERS_H
22+#define FILTERS_H
23+
24+// Qt
25+#include <QAbstractListModel>
26+#include <QList>
27+
28+// libunity-core
29+#include <UnityCore/Filters.h>
30+#include <UnityCore/Filter.h>
31+
32+class Filter;
33+
34+class Filters : public QAbstractListModel
35+{
36+ Q_OBJECT
37+
38+ Q_ENUMS(Roles)
39+
40+public:
41+ explicit Filters(unity::dash::Filters::Ptr unityFilters, QObject *parent = nullptr);
42+ ~Filters();
43+
44+ enum Roles {
45+ RoleId = Qt::UserRole,
46+ RoleName,
47+ RoleIconHint,
48+ RoleRendererName,
49+ RoleVisible,
50+ RoleCollapsed,
51+ RoleFiltering
52+ };
53+
54+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
55+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
56+ QHash<int, QByteArray> roleNames() const override;
57+
58+ Filter* getFilter(const QString& id) const;
59+
60+private:
61+ void onFilterAdded(unity::dash::Filter::Ptr unityFilter);
62+ void onFilterChanged(unity::dash::Filter::Ptr unityFilter);
63+ void onFilterRemoved(unity::dash::Filter::Ptr unityFilter);
64+
65+ void addFilter(unity::dash::Filter::Ptr unityFilter, int index);
66+ void removeFilter(int index);
67+
68+ int indexForFilter(unity::dash::Filter::Ptr unityFilter);
69+
70+ unity::dash::Filters::Ptr m_unityFilters;
71+ QList<Filter*> m_filters;
72+};
73+
74+Q_DECLARE_METATYPE(Filters*)
75+
76+#endif // FILTERS_H
plugins/Unity/genericoptionsmodel.cppnew file+152
@@ -0,0 +1,152 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "genericoptionsmodel.h"
22+
23+// local
24+#include "abstractfilteroption.h"
25+
26+GenericOptionsModel::GenericOptionsModel(QObject *parent)
27+ : QAbstractListModel(parent)
28+{
29+}
30+
31+GenericOptionsModel::~GenericOptionsModel()
32+{
33+ Q_FOREACH(auto opt, m_options)
34+ {
35+ opt->deleteLater();
36+ }
37+}
38+
39+QHash<int, QByteArray> GenericOptionsModel::roleNames() const
40+{
41+ QHash<int, QByteArray> roles;
42+ roles[GenericOptionsModel::RoleId] = "id";
43+ roles[GenericOptionsModel::RoleName] = "name";
44+ roles[GenericOptionsModel::RoleIconHint] = "iconHint";
45+ roles[GenericOptionsModel::RoleActive] = "active";
46+ return roles;
47+}
48+
49+QVariant GenericOptionsModel::data(const QModelIndex& index, int role) const
50+{
51+ if (!index.isValid()) {
52+ return QVariant();
53+ }
54+
55+ auto filterOption = m_options[index.row()];
56+ switch (role)
57+ {
58+ case GenericOptionsModel::RoleId:
59+ return filterOption->id();
60+ case GenericOptionsModel::RoleName:
61+ case Qt::DisplayRole:
62+ return filterOption->name();
63+ case GenericOptionsModel::RoleIconHint:
64+ return filterOption->iconHint();
65+ case GenericOptionsModel::RoleActive:
66+ return filterOption->active();
67+ default:
68+ break;
69+ }
70+
71+ return QVariant();
72+}
73+
74+int GenericOptionsModel::rowCount(const QModelIndex& /* parent */) const
75+{
76+ return m_options.size ();
77+}
78+
79+AbstractFilterOption* GenericOptionsModel::getRawOption(QVector<AbstractFilterOption *>::size_type idx) const
80+{
81+ if (idx < m_options.size())
82+ {
83+ return m_options[idx];
84+ }
85+ return nullptr;
86+}
87+
88+void GenericOptionsModel::ensureTheOnlyActive(AbstractFilterOption *activeOption)
89+{
90+ if (activeOption->active()) {
91+ // disable all other options
92+ Q_FOREACH(auto opt, m_options) {
93+ if (opt != activeOption && opt->active()) {
94+ opt->setActive(false);
95+ }
96+ }
97+ }
98+}
99+
100+void GenericOptionsModel::addOption(AbstractFilterOption *option, int index)
101+{
102+ m_options.insert(index, option);
103+
104+ connect(option, SIGNAL(idChanged(const QString &)), this, SLOT(onOptionChanged()));
105+ connect(option, SIGNAL(nameChanged(const QString &)), this, SLOT(onOptionChanged()));
106+ connect(option, SIGNAL(iconHintChanged(const QString &)), this, SLOT(onOptionChanged()));
107+ connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onOptionChanged()));
108+ connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged()));
109+}
110+
111+void GenericOptionsModel::removeOption(int index)
112+{
113+ m_options[index]->deleteLater();
114+ m_options.remove(index);
115+}
116+
117+int GenericOptionsModel::indexOf(const QString &option_id)
118+{
119+ int row = 0;
120+ Q_FOREACH(auto opt, m_options)
121+ {
122+ if (opt->id() == option_id)
123+ {
124+ return row;
125+ }
126+ ++row;
127+ }
128+ return -1;
129+}
130+
131+void GenericOptionsModel::onOptionChanged()
132+{
133+ AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
134+ if (option)
135+ {
136+ int idx = indexOf(option->id());
137+ if (idx >= 0)
138+ {
139+ QModelIndex optionIndex = index(idx);
140+ Q_EMIT dataChanged(optionIndex, optionIndex);
141+ }
142+ }
143+}
144+
145+void GenericOptionsModel::onActiveChanged()
146+{
147+ AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
148+ if (option)
149+ {
150+ Q_EMIT activeChanged(option);
151+ }
152+}
plugins/Unity/genericoptionsmodel.hnew file+74
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef GENERICOPTIONSMODEL_H
21+#define GENERICOPTIONSMODEL_H
22+
23+// Qt
24+#include <QObject>
25+#include <QAbstractListModel>
26+#include <QHash>
27+#include <QVector>
28+
29+class AbstractFilterOption;
30+
31+class Q_DECL_EXPORT GenericOptionsModel : public QAbstractListModel
32+{
33+ Q_OBJECT
34+
35+ Q_ENUMS(Roles)
36+
37+public:
38+ GenericOptionsModel(QObject *parent = nullptr);
39+ ~GenericOptionsModel();
40+
41+ enum Roles {
42+ RoleId = Qt::UserRole,
43+ RoleName,
44+ RoleIconHint,
45+ RoleActive
46+ };
47+
48+ QHash<int, QByteArray> roleNames() const override;
49+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
50+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
51+
52+ AbstractFilterOption* getRawOption(QVector<AbstractFilterOption *>::size_type idx) const;
53+
54+public Q_SLOTS:
55+ virtual void ensureTheOnlyActive(AbstractFilterOption *activeOption);
56+
57+Q_SIGNALS:
58+ void activeChanged(AbstractFilterOption *option);
59+
60+protected Q_SLOTS:
61+ void onOptionChanged();
62+ void onActiveChanged();
63+
64+protected:
65+ void addOption(AbstractFilterOption *option, int index);
66+ void removeOption(int index);
67+ int indexOf(const QString &option_id);
68+
69+ QVector<AbstractFilterOption *> m_options;
70+};
71+
72+Q_DECLARE_METATYPE(GenericOptionsModel*)
73+
74+#endif // GENERICOPTIONSMODEL_H
plugins/Unity/multirangefilter.cppnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// Self
22+#include "multirangefilter.h"
23+
24+// local
25+#include "unityoptionsmodel.h"
26+
27+MultiRangeFilter::MultiRangeFilter(QObject *parent) :
28+ Filter(parent), m_unityMultiRangeFilter(nullptr), m_options(nullptr)
29+{
30+}
31+
32+GenericOptionsModel* MultiRangeFilter::options() const
33+{
34+ return m_options;
35+}
36+
37+void MultiRangeFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
38+{
39+ Filter::setUnityFilter(filter);
40+ m_unityMultiRangeFilter = std::dynamic_pointer_cast<unity::dash::MultiRangeFilter>(m_unityFilter);
41+
42+ onOptionsChanged(m_unityMultiRangeFilter->options);
43+}
44+
45+void MultiRangeFilter::onOptionsChanged(unity::dash::MultiRangeFilter::Options options)
46+{
47+ if (m_options != nullptr) {
48+ m_signals.disconnectAll();
49+ delete m_options;
50+ m_options = nullptr;
51+ }
52+
53+ m_options = new UnityOptionsModel(this, options,
54+ m_unityMultiRangeFilter->option_added,
55+ m_unityMultiRangeFilter->option_removed);
56+
57+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
58+
59+ /* Property change signals */
60+ m_signals << m_unityMultiRangeFilter->options.changed.connect(sigc::mem_fun(this, &MultiRangeFilter::onOptionsChanged));
61+
62+ Q_EMIT optionsChanged();
63+}
plugins/Unity/multirangefilter.hnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef MULTIRANGEFILTER_H
22+#define MULTIRANGEFILTER_H
23+
24+// Qt
25+#include <QObject>
26+#include <QMetaType>
27+
28+// libunity-core
29+#include <UnityCore/MultiRangeFilter.h>
30+
31+// Local
32+#include "filter.h"
33+#include "signalslist.h"
34+
35+class GenericOptionsModel;
36+
37+class Q_DECL_EXPORT MultiRangeFilter : public Filter
38+{
39+ Q_OBJECT
40+
41+public:
42+ explicit MultiRangeFilter(QObject *parent = nullptr);
43+
44+ /* getters */
45+ GenericOptionsModel* options() const override;
46+
47+protected:
48+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
49+
50+private:
51+ unity::dash::MultiRangeFilter::Ptr m_unityMultiRangeFilter;
52+ SignalsList m_signals;
53+ GenericOptionsModel* m_options;
54+
55+ void onOptionsChanged(unity::dash::MultiRangeFilter::Options);
56+};
57+
58+Q_DECLARE_METATYPE(MultiRangeFilter*)
59+
60+#endif // MULTIRANGEFILTER_H
plugins/Unity/preview.cpp+7
@@ -94,6 +94,11 @@ QVariant Preview::infoHints()
94 return QVariant::fromValue(m_infoHints);
94 return QVariant::fromValue(m_infoHints);
95}
95}
96
96
97+QVariantMap Preview::infoHintsHash() const
98+{
99+ return m_infoHintsHash;
100+}
101+
97QString Preview::image() const
102QString Preview::image() const
98{
103{
99 if (m_unityPreview) {
104 if (m_unityPreview) {
@@ -145,6 +150,7 @@ void Preview::setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview)
145
150
146 qDeleteAll(m_infoHints);
151 qDeleteAll(m_infoHints);
147 m_infoHints.clear();
152 m_infoHints.clear();
153+ m_infoHintsHash.clear();
148 qDeleteAll(m_actions);
154 qDeleteAll(m_actions);
149 m_actions.clear();
155 m_actions.clear();
150
156
@@ -152,6 +158,7 @@ void Preview::setUnityPreviewBase(unity::dash::Preview::Ptr unityPreview)
152 auto hint = new PreviewInfoHint(this);
158 auto hint = new PreviewInfoHint(this);
153 hint->setUnityInfoHint(unityInfoHint);
159 hint->setUnityInfoHint(unityInfoHint);
154 m_infoHints.append(hint);
160 m_infoHints.append(hint);
161+ m_infoHintsHash[hint->id()] = QVariant::fromValue(hint);
155 }
162 }
156
163
157 for (auto unityAction: m_unityPreview->GetActions()) {
164 for (auto unityAction: m_unityPreview->GetActions()) {
plugins/Unity/preview.h+4
@@ -25,6 +25,7 @@
25#include <QString>
25#include <QString>
26#include <QMetaType>
26#include <QMetaType>
27#include <QList>
27#include <QList>
28+#include <QVariantMap>
28
29
29// libunity-core
30// libunity-core
30#include <UnityCore/Preview.h>
31#include <UnityCore/Preview.h>
@@ -42,6 +43,7 @@ class Q_DECL_EXPORT Preview : public QObject
42 Q_PROPERTY(QString description READ description NOTIFY previewChanged)
43 Q_PROPERTY(QString description READ description NOTIFY previewChanged)
43 Q_PROPERTY(QVariant actions READ actions NOTIFY previewChanged)
44 Q_PROPERTY(QVariant actions READ actions NOTIFY previewChanged)
44 Q_PROPERTY(QVariant infoHints READ infoHints NOTIFY previewChanged)
45 Q_PROPERTY(QVariant infoHints READ infoHints NOTIFY previewChanged)
46+ Q_PROPERTY(QVariantMap infoMap READ infoHintsHash NOTIFY previewChanged)
45 Q_PROPERTY(QString image READ image NOTIFY previewChanged)
47 Q_PROPERTY(QString image READ image NOTIFY previewChanged)
46 Q_PROPERTY(QString imageSourceUri READ imageSourceUri NOTIFY previewChanged)
48 Q_PROPERTY(QString imageSourceUri READ imageSourceUri NOTIFY previewChanged)
47
49
@@ -55,6 +57,7 @@ public:
55 QString description() const;
57 QString description() const;
56 QVariant actions();
58 QVariant actions();
57 QVariant infoHints();
59 QVariant infoHints();
60+ QVariantMap infoHintsHash() const;
58 QString image() const;
61 QString image() const;
59 QString imageSourceUri() const;
62 QString imageSourceUri() const;
60
63
@@ -73,6 +76,7 @@ private:
73
76
74 QList<QObject *> m_actions;
77 QList<QObject *> m_actions;
75 QList<QObject *> m_infoHints;
78 QList<QObject *> m_infoHints;
79+ QVariantMap m_infoHintsHash;
76};
80};
77
81
78Q_DECLARE_METATYPE(Preview *)
82Q_DECLARE_METATYPE(Preview *)
plugins/Unity/radiooptionfilter.cppnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// Self
22+#include "radiooptionfilter.h"
23+
24+// local
25+#include "unityoptionsmodel.h"
26+
27+RadioOptionFilter::RadioOptionFilter(QObject *parent) :
28+ Filter(parent), m_unityRadioOptionFilter(nullptr), m_options(nullptr)
29+{
30+}
31+
32+GenericOptionsModel* RadioOptionFilter::options() const
33+{
34+ return m_options;
35+}
36+
37+void RadioOptionFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
38+{
39+ Filter::setUnityFilter(filter);
40+ m_unityRadioOptionFilter = std::dynamic_pointer_cast<unity::dash::RadioOptionFilter>(m_unityFilter);
41+
42+ onOptionsChanged(m_unityRadioOptionFilter->options);
43+}
44+
45+void RadioOptionFilter::onOptionsChanged(unity::dash::RadioOptionFilter::RadioOptions)
46+{
47+ if (m_options != nullptr) {
48+ m_signals.disconnectAll();
49+ delete m_options;
50+ m_options = nullptr;
51+ }
52+ m_options = new UnityOptionsModel(this, m_unityRadioOptionFilter->options,
53+ m_unityRadioOptionFilter->option_added,
54+ m_unityRadioOptionFilter->option_removed);
55+
56+ m_signals << m_unityRadioOptionFilter->options.changed.connect(sigc::mem_fun(this, &RadioOptionFilter::onOptionsChanged));
57+
58+ Q_EMIT optionsChanged();
59+}
plugins/Unity/radiooptionfilter.hnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef RADIOOPTIONFILTER_H
22+#define RADIOOPTIONFILTER_H
23+
24+// Qt
25+#include <QObject>
26+#include <QMetaType>
27+
28+// libunity-core
29+#include <UnityCore/RadioOptionFilter.h>
30+
31+// Local
32+#include "filter.h"
33+#include "filteroption.h"
34+#include "signalslist.h"
35+
36+class Q_DECL_EXPORT RadioOptionFilter : public Filter
37+{
38+ Q_OBJECT
39+
40+public:
41+ explicit RadioOptionFilter(QObject *parent = nullptr);
42+
43+ /* getters */
44+ GenericOptionsModel* options() const override;
45+
46+protected:
47+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
48+
49+private:
50+ unity::dash::RadioOptionFilter::Ptr m_unityRadioOptionFilter;
51+ GenericOptionsModel* m_options;
52+ SignalsList m_signals;
53+
54+ void onOptionsChanged(unity::dash::RadioOptionFilter::RadioOptions);
55+};
56+
57+Q_DECLARE_METATYPE(RadioOptionFilter*)
58+
59+#endif // RADIOOPTIONFILTER_H
plugins/Unity/ratingfilteroption.cppnew file+62
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "ratingfilteroption.h"
22+
23+RatingFilterOption::RatingFilterOption(const QString &id, float value, QObject *parent) :
24+ AbstractFilterOption(parent),
25+ m_active(false),
26+ m_id(id),
27+ m_value(value)
28+{
29+}
30+
31+QString RatingFilterOption::id() const
32+{
33+ return m_id;
34+}
35+
36+QString RatingFilterOption::name() const
37+{
38+ return QString::Null();
39+}
40+
41+QString RatingFilterOption::iconHint() const
42+{
43+ return QString::Null();
44+}
45+
46+float RatingFilterOption::value() const
47+{
48+ return m_value;
49+}
50+
51+bool RatingFilterOption::active() const
52+{
53+ return m_active;
54+}
55+
56+void RatingFilterOption::setActive(bool active)
57+{
58+ if (active != m_active) {
59+ m_active = active;
60+ Q_EMIT activeChanged(m_active);
61+ }
62+}
plugins/Unity/ratingfilteroption.hnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef RATINGFILTEROPTION_H
21+#define RATINGFILTEROPTION_H
22+
23+// local
24+#include "abstractfilteroption.h"
25+
26+class Q_DECL_EXPORT RatingFilterOption : public AbstractFilterOption
27+{
28+ Q_OBJECT
29+
30+ Q_PROPERTY(float value READ value CONSTANT)
31+
32+public:
33+ explicit RatingFilterOption(const QString &id, float ratingValue, QObject *parent = nullptr);
34+
35+ /* getters */
36+ QString id() const override;
37+ QString name() const override;
38+ QString iconHint() const override;
39+ bool active() const override;
40+ float value() const;
41+
42+ /* setters */
43+ void setActive(bool active) override;
44+
45+private:
46+ bool m_active;
47+ QString m_id;
48+ float m_value;
49+};
50+
51+Q_DECLARE_METATYPE(RatingFilterOption*)
52+
53+#endif // RATINGFILTEROPTION_H
plugins/Unity/ratingoptionsmodel.cppnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "ratingoptionsmodel.h"
22+
23+// local
24+#include "ratingfilteroption.h"
25+
26+RatingOptionsModel::RatingOptionsModel(QObject *parent) :
27+ GenericOptionsModel(parent)
28+{
29+ for (int i=1; i<=5; i++) {
30+ auto opt = new RatingFilterOption(QString::number(i), i*0.2f, this);
31+ addOption(opt, i-1);
32+ }
33+}
plugins/Unity/ratingoptionsmodel.hnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef RATINGOPTIONSMODEL_H
21+#define RATINGOPTIONSMODEL_H
22+
23+#include "genericoptionsmodel.h"
24+
25+class RatingOptionsModel : public GenericOptionsModel
26+{
27+ Q_OBJECT
28+
29+public:
30+ RatingOptionsModel(QObject *parent);
31+};
32+
33+#endif // RATINGOPTIONSMODEL_H
plugins/Unity/ratingsfilter.cppnew file+72
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// Self
22+#include "ratingsfilter.h"
23+
24+// local
25+#include "ratingfilteroption.h"
26+#include "ratingoptionsmodel.h"
27+
28+RatingsFilter::RatingsFilter(QObject *parent) :
29+ Filter(parent),
30+ m_unityRatingsFilter(nullptr),
31+ m_options(nullptr)
32+{
33+}
34+
35+GenericOptionsModel* RatingsFilter::options() const
36+{
37+ return m_options;
38+}
39+
40+float RatingsFilter::rating() const
41+{
42+ if (m_unityRatingsFilter)
43+ {
44+ return m_unityRatingsFilter->rating;
45+ }
46+ return 0.0f;
47+}
48+
49+void RatingsFilter::setUnityFilter(unity::dash::Filter::Ptr filter)
50+{
51+ Filter::setUnityFilter(filter);
52+ m_unityRatingsFilter = std::dynamic_pointer_cast<unity::dash::RatingsFilter>(m_unityFilter);
53+
54+ delete m_options;
55+
56+ m_options = new RatingOptionsModel(this);
57+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), m_options, SLOT(ensureTheOnlyActive(AbstractFilterOption *)));
58+ connect(m_options, SIGNAL(activeChanged(AbstractFilterOption *)), this, SLOT(onActiveChanged(AbstractFilterOption *)));
59+
60+ Q_EMIT optionsChanged();
61+}
62+
63+void RatingsFilter::onActiveChanged(AbstractFilterOption *option)
64+{
65+ RatingFilterOption *ratingOption = dynamic_cast<RatingFilterOption*>(option);
66+ if (ratingOption != nullptr)
67+ {
68+ const float val = ratingOption->active() ? ratingOption->value() : 0.0f;
69+ m_unityRatingsFilter->rating = val;
70+ Q_EMIT ratingChanged(val);
71+ }
72+}
plugins/Unity/ratingsfilter.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2011, 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Florian Boucault <florian.boucault@canonical.com>
6+ * Pawel Stolowski <pawel.stolowski@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+#ifndef RATINGSFILTER_H
22+#define RATINGSFILTER_H
23+
24+// Qt
25+#include <QObject>
26+#include <QMetaType>
27+
28+// libunity-core
29+#include <UnityCore/RatingsFilter.h>
30+
31+// Local
32+#include "filter.h"
33+
34+class GenericOptionsModel;
35+class AbstractFilterOption;
36+
37+class Q_DECL_EXPORT RatingsFilter : public Filter
38+{
39+ Q_OBJECT
40+
41+ Q_PROPERTY(float rating READ rating NOTIFY ratingChanged)
42+
43+public:
44+ explicit RatingsFilter(QObject *parent = nullptr);
45+
46+ /* getters */
47+ GenericOptionsModel* options() const override;
48+ float rating() const;
49+
50+Q_SIGNALS:
51+ void ratingChanged(float);
52+
53+protected:
54+ void setUnityFilter(unity::dash::Filter::Ptr filter) override;
55+
56+protected Q_SLOTS:
57+ void onActiveChanged(AbstractFilterOption *option);
58+
59+private:
60+ unity::dash::RatingsFilter::Ptr m_unityRatingsFilter;
61+ GenericOptionsModel *m_options;
62+};
63+
64+Q_DECLARE_METATYPE(RatingsFilter*)
65+
66+#endif // RATINGSFILTER_H
plugins/Unity/scope.cpp+27−9
@@ -35,6 +35,7 @@
35#include <UnityCore/Variant.h>
35#include <UnityCore/Variant.h>
36
36
37#include <libintl.h>
37#include <libintl.h>
38+#include <glib.h>
38
39
39Scope::Scope(QObject *parent) : QObject(parent)
40Scope::Scope(QObject *parent) : QObject(parent)
40 , m_formFactor("phone")
41 , m_formFactor("phone")
@@ -102,6 +103,11 @@ QString Scope::formFactor() const
102 return m_formFactor;
103 return m_formFactor;
103}
104}
104
105
106+Filters* Scope::filters() const
107+{
108+ return m_filters.get();
109+}
110+
105void Scope::setSearchQuery(const QString& search_query)
111void Scope::setSearchQuery(const QString& search_query)
106{
112{
107 /* Checking for m_searchQuery.isNull() which returns true only when the string
113 /* Checking for m_searchQuery.isNull() which returns true only when the string
@@ -209,18 +215,11 @@ void Scope::onPreviewReady(unity::dash::LocalResult const& /* result */, unity::
209
215
210void Scope::fallbackActivate(const QString& uri)
216void Scope::fallbackActivate(const QString& uri)
211{
217{
212− /* FIXME: stripping all content before the first column because for some
213− reason the scopes give uri with junk content at their beginning.
214− */
215− QString tweakedUri = uri;
216− int firstColumnAt = tweakedUri.indexOf(":");
217− tweakedUri.remove(0, firstColumnAt+1);
218−
219 /* Tries various methods to trigger a sensible action for the given 'uri'.
218 /* Tries various methods to trigger a sensible action for the given 'uri'.
220 If it has no understanding of the given scheme it falls back on asking
219 If it has no understanding of the given scheme it falls back on asking
221 Qt to open the uri.
220 Qt to open the uri.
222 */
221 */
223− QUrl url(tweakedUri);
222+ QUrl url(uri);
224 if (url.scheme() == "file") {
223 if (url.scheme() == "file") {
225 /* Override the files place's default URI handler: we want the file
224 /* Override the files place's default URI handler: we want the file
226 manager to handle opening folders, not the dash.
225 manager to handle opening folders, not the dash.
@@ -231,7 +230,25 @@ void Scope::fallbackActivate(const QString& uri)
231 return;
230 return;
232 }
231 }
233 if (url.scheme() == "application") {
232 if (url.scheme() == "application") {
234− // TODO: implement application handling
233+ // get the full path to the desktop file
234+ QString path(url.path().isEmpty() ? url.authority() : url.path());
235+ if (path.startsWith("/")) {
236+ Q_EMIT activateApplication(path);
237+ } else {
238+ // TODO: use the new desktop file finder/parser when it's ready
239+ gchar* full_path = nullptr;
240+ GKeyFile* key_file = g_key_file_new();
241+ QString apps_path = "applications/" + path;
242+ if (g_key_file_load_from_data_dirs(key_file, apps_path.toLocal8Bit().constData(), &full_path,
243+ G_KEY_FILE_NONE, nullptr)) {
244+ path = full_path;
245+ Q_EMIT activateApplication(path);
246+ } else {
247+ qWarning() << "Unable to activate " << path;
248+ }
249+ g_key_file_free(key_file);
250+ g_free(full_path);
251+ }
235 return;
252 return;
236 }
253 }
237
254
@@ -246,6 +263,7 @@ void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
246 m_unityScope = scope;
263 m_unityScope = scope;
247
264
248 m_categories->setUnityScope(m_unityScope);
265 m_categories->setUnityScope(m_unityScope);
266+ m_filters.reset(new Filters(m_unityScope->filters, this));
249
267
250 m_unityScope->form_factor = m_formFactor.toStdString();
268 m_unityScope->form_factor = m_formFactor.toStdString();
251 /* Property change signals */
269 /* Property change signals */
plugins/Unity/scope.h+7
@@ -30,6 +30,7 @@
30#include <UnityCore/Results.h>
30#include <UnityCore/Results.h>
31
31
32#include "categories.h"
32#include "categories.h"
33+#include "filters.h"
33
34
34class Preview;
35class Preview;
35
36
@@ -46,6 +47,7 @@ class Scope : public QObject
46 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
47 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
47 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
48 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
48 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
49 Q_PROPERTY(Categories* categories READ categories NOTIFY categoriesChanged)
50+ Q_PROPERTY(Filters* filters READ filters NOTIFY filtersChanged)
49
51
50 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
52 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
51 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
53 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
@@ -64,6 +66,7 @@ public:
64 QString shortcut() const;
66 QString shortcut() const;
65 bool connected() const;
67 bool connected() const;
66 Categories* categories() const;
68 Categories* categories() const;
69+ Filters* filters() const;
67 QString searchQuery() const;
70 QString searchQuery() const;
68 QString noResultsHint() const;
71 QString noResultsHint() const;
69 QString formFactor() const;
72 QString formFactor() const;
@@ -98,6 +101,7 @@ Q_SIGNALS:
98 void searchQueryChanged();
101 void searchQueryChanged();
99 void noResultsHintChanged();
102 void noResultsHintChanged();
100 void formFactorChanged();
103 void formFactorChanged();
104+ void filtersChanged();
101
105
102 // signals triggered by activate(..) or preview(..) requests.
106 // signals triggered by activate(..) or preview(..) requests.
103 void previewReady(Preview *preview);
107 void previewReady(Preview *preview);
@@ -105,6 +109,8 @@ Q_SIGNALS:
105 void hideDash();
109 void hideDash();
106 void gotoUri(const QString &uri);
110 void gotoUri(const QString &uri);
107
111
112+ void activateApplication(const QString &desktop);
113+
108private Q_SLOTS:
114private Q_SLOTS:
109 void synchronizeStates();
115 void synchronizeStates();
110 void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
116 void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
@@ -121,6 +127,7 @@ private:
121
127
122 unity::dash::Scope::Ptr m_unityScope;
128 unity::dash::Scope::Ptr m_unityScope;
123 std::unique_ptr<Categories> m_categories;
129 std::unique_ptr<Categories> m_categories;
130+ std::unique_ptr<Filters> m_filters;
124 QString m_searchQuery;
131 QString m_searchQuery;
125 QString m_noResultsHint;
132 QString m_noResultsHint;
126 QString m_formFactor;
133 QString m_formFactor;
plugins/Unity/signalslist.cppnew file+39
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include "signalslist.h"
21+
22+void SignalsList::append(const sigc::connection &c)
23+{
24+ m_signals.append(c);
25+}
26+
27+void SignalsList::disconnectAll()
28+{
29+ Q_FOREACH(auto sig, m_signals) {
30+ sig.disconnect();
31+ }
32+ m_signals.clear();
33+}
34+
35+SignalsList& SignalsList::operator<<(const sigc::connection &c)
36+{
37+ append(c);
38+ return *this;
39+}
plugins/Unity/signalslist.hnew file+38
@@ -0,0 +1,38 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef SIGNALSLIST_H
21+#define SIGNALSLIST_H
22+
23+#include <QList>
24+#include <sigc++/sigc++.h>
25+
26+class Q_DECL_EXPORT SignalsList
27+{
28+public:
29+ void append(const sigc::connection &c);
30+ void disconnectAll();
31+
32+ SignalsList& operator<<(const sigc::connection &c);
33+
34+private:
35+ QList<sigc::connection> m_signals;
36+};
37+
38+#endif // SIGNALSLIST_H
plugins/Unity/unityoptionsmodel.cppnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// self
21+#include "unityoptionsmodel.h"
22+
23+// local
24+#include "filteroption.h"
25+
26+UnityOptionsModel::UnityOptionsModel(QObject *parent,
27+ const std::vector<unity::dash::FilterOption::Ptr> options,
28+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
29+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved) :
30+ GenericOptionsModel(parent)
31+{
32+ setOptions(options, optionAdded, optionRemoved);
33+}
34+
35+void UnityOptionsModel::setOptions(const std::vector<unity::dash::FilterOption::Ptr> options,
36+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
37+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved)
38+{
39+ for (unsigned int i=0; i<options.size(); i++)
40+ {
41+ addOption(new FilterOption(options[i], this), i);
42+ }
43+ optionAdded.connect(sigc::mem_fun(this, &UnityOptionsModel::onOptionAdded));
44+ optionRemoved.connect(sigc::mem_fun(this, &UnityOptionsModel::onOptionRemoved));
45+}
46+
47+void UnityOptionsModel::onOptionAdded(unity::dash::FilterOption::Ptr option)
48+{
49+ int index = m_options.count();
50+ if (index >= 0)
51+ {
52+ beginInsertRows(QModelIndex(), index, index);
53+ addOption(new FilterOption(option, this), index);
54+ endInsertRows();
55+ }
56+}
57+
58+void UnityOptionsModel::onOptionRemoved(unity::dash::FilterOption::Ptr option)
59+{
60+ auto index = indexOf(QString::fromStdString(option->id));
61+ if (index >= 0)
62+ {
63+ beginRemoveRows(QModelIndex(), index, index);
64+ removeOption(index);
65+ endRemoveRows();
66+ }
67+}
plugins/Unity/unityoptionsmodel.hnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef UNITYOPTIONSMODEL_H
21+#define UNITYOPTIONSMODEL_H
22+
23+#include "genericoptionsmodel.h"
24+
25+// libunity-core
26+#include <UnityCore/Filter.h>
27+
28+#include <sigc++/signal.h>
29+
30+class UnityOptionsModel : public GenericOptionsModel
31+{
32+ Q_OBJECT
33+
34+public:
35+ UnityOptionsModel(QObject *parent,
36+ const std::vector<unity::dash::FilterOption::Ptr> options,
37+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
38+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved);
39+
40+private:
41+ void setOptions(const std::vector<unity::dash::FilterOption::Ptr> options,
42+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionAdded,
43+ sigc::signal<void, unity::dash::FilterOption::Ptr> optionRemoved);
44+
45+ void onOptionAdded(unity::dash::FilterOption::Ptr option);
46+ void onOptionRemoved(unity::dash::FilterOption::Ptr option);
47+};
48+
49+#endif // UNITYOPTIONSMODEL_H
plugins/Utils/qsortfilterproxymodelqml.cpp+1−1
@@ -52,7 +52,6 @@ QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
52 connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
52 connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
53 connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
53 connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
54 Q_EMIT totalCountChanged();
54 Q_EMIT totalCountChanged();
55− Q_EMIT countChanged();
56 Q_EMIT modelChanged();
55 Q_EMIT modelChanged();
57 }
56 }
58}
57}
@@ -95,6 +94,7 @@ QSortFilterProxyModelQML::setInvertMatch(bool invertMatch)
95 if (invertMatch != m_invertMatch) {
94 if (invertMatch != m_invertMatch) {
96 m_invertMatch = invertMatch;
95 m_invertMatch = invertMatch;
97 Q_EMIT invertMatchChanged(invertMatch);
96 Q_EMIT invertMatchChanged(invertMatch);
97+ invalidateFilter();
98 }
98 }
99}
99}
100
100
po/ar.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 23:26+0000\n"
11"PO-Revision-Date: 2013-06-26 23:26+0000\n"
12"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
12"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
13"Language-Team: Arabic <ar@li.org>\n"
13"Language-Team: Arabic <ar@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
18+"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr "يوتيوب"
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "عمليات البحث الأخيرة"
92msgstr "عمليات البحث الأخيرة"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr "البرامج المُشغّلة"
130msgstr "البرامج المُشغّلة"
@@ -153,15 +189,15 @@ msgstr "الشائع على الإنترنت"
153msgid "Videos"
189msgid "Videos"
154msgstr "فيديوهات"
190msgstr "فيديوهات"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr "أخرجه:"
194msgstr "أخرجه:"
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr "النجوم:"
198msgstr "النجوم:"
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr "المؤلف:"
202msgstr "المؤلف:"
167
203
po/az.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 23:48+0000\n"
11"PO-Revision-Date: 2013-06-26 23:48+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
13"Language-Team: Azerbaijani <az@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Son axtarışlar"
91msgstr "Son axtarışlar"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Videolar"
189msgstr "Videolar"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/bg.po+40−5
@@ -7,7 +7,7 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 00:06+0000\n"
11"PO-Revision-Date: 2013-06-27 00:06+0000\n"
12"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
12"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
13"<miroslav.hadzhiev@gmail.com>\n"
13"<miroslav.hadzhiev@gmail.com>\n"
@@ -15,7 +15,8 @@ msgstr ""
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18+"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
19"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
20
21
21#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -90,6 +91,40 @@ msgstr "YouTube"
90msgid "Recent searches"
91msgid "Recent searches"
91msgstr "Скорошни търсения"
92msgstr "Скорошни търсения"
92
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
93#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
94msgid "Running apps"
129msgid "Running apps"
95msgstr ""
130msgstr ""
@@ -154,15 +189,15 @@ msgstr ""
154msgid "Videos"
189msgid "Videos"
155msgstr "Видеоклипове"
190msgstr "Видеоклипове"
156
191
157−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
158msgid "Directed by:"
193msgid "Directed by:"
159msgstr ""
194msgstr ""
160
195
161−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
162msgid "Starring:"
197msgid "Starring:"
163msgstr ""
198msgstr ""
164
199
165−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
166msgid "Author:"
201msgid "Author:"
167msgstr "Автор:"
202msgstr "Автор:"
168
203
po/ca.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 00:24+0000\n"
11"PO-Revision-Date: 2013-06-27 00:24+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Catalan <ca@li.org>\n"
13"Language-Team: Catalan <ca@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Cerques recents"
91msgstr "Cerques recents"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Aplications actives"
129msgstr "Aplications actives"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Vídeos"
189msgstr "Vídeos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/de.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 00:37+0000\n"
11"PO-Revision-Date: 2013-06-27 00:37+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: German <de@li.org>\n"
13"Language-Team: German <de@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Letzte Suchbegriffe"
91msgstr "Letzte Suchbegriffe"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Aktive Anwendungen"
129msgstr "Aktive Anwendungen"
@@ -153,15 +188,15 @@ msgstr "Online Beliebt"
153msgid "Videos"
188msgid "Videos"
154msgstr "Videos"
189msgstr "Videos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "Regie:"
193msgstr "Regie:"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr "Darsteller:"
197msgstr "Darsteller:"
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "Autor:"
201msgstr "Autor:"
167
202
po/el.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 00:53+0000\n"
11"PO-Revision-Date: 2013-06-27 00:53+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Greek <el@li.org>\n"
13"Language-Team: Greek <el@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Πρόσφατες αναζητήσεις"
91msgstr "Πρόσφατες αναζητήσεις"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Βίντεο"
189msgstr "Βίντεο"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/en_AU.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 01:13+0000\n"
11"PO-Revision-Date: 2013-06-27 01:13+0000\n"
12"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
12"Last-Translator: Jackson Doak <Doak.jackson@gmail.com>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
13"Language-Team: English (Australia) <en_AU@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:26+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Recent searches"
91msgstr "Recent searches"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Running apps"
129msgstr "Running apps"
@@ -153,15 +188,15 @@ msgstr "Popular Online"
153msgid "Videos"
188msgid "Videos"
154msgstr "Videos"
189msgstr "Videos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "Directed by:"
193msgstr "Directed by:"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr "Starring:"
197msgstr "Starring:"
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "Author:"
201msgstr "Author:"
167
202
po/en_GB.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 08:53+0000\n"
11"PO-Revision-Date: 2013-06-27 08:53+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
13"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:26+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Recent searches"
91msgstr "Recent searches"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Running apps"
129msgstr "Running apps"
@@ -153,15 +188,15 @@ msgstr "Popular Online"
153msgid "Videos"
188msgid "Videos"
154msgstr "Videos"
189msgstr "Videos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "Directed by:"
193msgstr "Directed by:"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr "Starring:"
197msgstr "Starring:"
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "Author:"
201msgstr "Author:"
167
202
po/eo.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Esperanto <eo@li.org>\n"
13"Language-Team: Esperanto <eo@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/es.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-07-08 07:25+0000\n"
11"PO-Revision-Date: 2013-07-08 07:25+0000\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
12"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Búsquedas recientes"
91msgstr "Búsquedas recientes"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Aplicaciones en ejecución"
129msgstr "Aplicaciones en ejecución"
@@ -153,15 +188,15 @@ msgstr "Populares en línea"
153msgid "Videos"
188msgid "Videos"
154msgstr "Vídeos"
189msgstr "Vídeos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "Dirigida por:"
193msgstr "Dirigida por:"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr "Protagonistas:"
197msgstr "Protagonistas:"
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "Autor:"
201msgstr "Autor:"
167
202
po/fi.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-08-12 17:45+0000\n"
11"PO-Revision-Date: 2013-08-12 17:45+0000\n"
12"Last-Translator: Aleksi Kinnunen <Unknown>\n"
12"Last-Translator: Aleksi Kinnunen <Unknown>\n"
13"Language-Team: Finnish <fi@li.org>\n"
13"Language-Team: Finnish <fi@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-13 06:08+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Viimeisimmät haut"
91msgstr "Viimeisimmät haut"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Käynnissä olevat sovellukset"
129msgstr "Käynnissä olevat sovellukset"
@@ -153,15 +188,15 @@ msgstr "Suosittua verkossa"
153msgid "Videos"
188msgid "Videos"
154msgstr "Videot"
189msgstr "Videot"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "Ohjannut:"
193msgstr "Ohjannut:"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr "Pääosissa:"
197msgstr "Pääosissa:"
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "Tekijä:"
201msgstr "Tekijä:"
167
202
po/fo.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 02:57+0000\n"
11"PO-Revision-Date: 2013-06-27 02:57+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Faroese <fo@li.org>\n"
13"Language-Team: Faroese <fo@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Sjónbond"
189msgstr "Sjónbond"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/fr.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 03:21+0000\n"
11"PO-Revision-Date: 2013-06-27 03:21+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: French <fr@li.org>\n"
13"Language-Team: French <fr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n > 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Vidéos"
189msgstr "Vidéos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/gl.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 03:38+0000\n"
11"PO-Revision-Date: 2013-06-27 03:38+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Galician <gl@li.org>\n"
13"Language-Team: Galician <gl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Buscas recentes"
91msgstr "Buscas recentes"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Aplicativos en execución"
129msgstr "Aplicativos en execución"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Vídeos"
189msgstr "Vídeos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/he.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 03:54+0000\n"
11"PO-Revision-Date: 2013-06-27 03:54+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Hebrew <he@li.org>\n"
13"Language-Team: Hebrew <he@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "חיפושים אחרונים"
91msgstr "חיפושים אחרונים"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "סרטונים"
189msgstr "סרטונים"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/hr.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 04:14+0000\n"
11"PO-Revision-Date: 2013-06-27 04:14+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Croatian <hr@li.org>\n"
13"Language-Team: Croatian <hr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr ""
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Nedavne pretrage"
92msgstr "Nedavne pretrage"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr ""
130msgstr ""
@@ -153,15 +189,15 @@ msgstr ""
153msgid "Videos"
189msgid "Videos"
154msgstr "Video"
190msgstr "Video"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr ""
194msgstr ""
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr ""
198msgstr ""
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr ""
202msgstr ""
167
203
po/hu.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 04:28+0000\n"
11"PO-Revision-Date: 2013-06-27 04:28+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Legutóbbi keresések"
91msgstr "Legutóbbi keresések"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Futó alkalmazások"
129msgstr "Futó alkalmazások"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Videók"
189msgstr "Videók"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/hy.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 04:43+0000\n"
11"PO-Revision-Date: 2013-06-27 04:43+0000\n"
12"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
12"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
13"Language-Team: Armenian <hy@li.org>\n"
13"Language-Team: Armenian <hy@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Վերջին որոնումներ"
91msgstr "Վերջին որոնումներ"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Բացած ծրագրեր"
129msgstr "Բացած ծրագրեր"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Վիդեոներ"
189msgstr "Վիդեոներ"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/id.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
11"PO-Revision-Date: 2013-06-26 22:35+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Indonesian <id@li.org>\n"
13"Language-Team: Indonesian <id@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/it.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 05:14+0000\n"
11"PO-Revision-Date: 2013-06-27 05:14+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Italian <it@li.org>\n"
13"Language-Team: Italian <it@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Ricerche recenti"
91msgstr "Ricerche recenti"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Video"
189msgstr "Video"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/ja.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/kn.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 05:43+0000\n"
11"PO-Revision-Date: 2013-06-27 05:43+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Kannada <kn@li.org>\n"
13"Language-Team: Kannada <kn@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು"
91msgstr "ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "ವೀಡಿಯೋಗಳು"
189msgstr "ವೀಡಿಯೋಗಳು"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/ko.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 05:59+0000\n"
11"PO-Revision-Date: 2013-06-27 05:59+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Korean <ko@li.org>\n"
13"Language-Team: Korean <ko@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "요즈음 찿은 것들"
91msgstr "요즈음 찿은 것들"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "돌아가고 있는 앱"
129msgstr "돌아가고 있는 앱"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/ky.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 06:17+0000\n"
11"PO-Revision-Date: 2013-06-27 06:17+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
13"Language-Team: Kirghiz <ky@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Соңку издөөлөр"
91msgstr "Соңку издөөлөр"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Видеолор"
189msgstr "Видеолор"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/lv.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 06:31+0000\n"
11"PO-Revision-Date: 2013-06-27 06:31+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Latvian <lv@li.org>\n"
13"Language-Team: Latvian <lv@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Nesen veiktās meklēšanas"
91msgstr "Nesen veiktās meklēšanas"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Video"
189msgstr "Video"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/my.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 06:47+0000\n"
11"PO-Revision-Date: 2013-06-27 06:47+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Burmese <my@li.org>\n"
13"Language-Team: Burmese <my@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "မကြာသေးခင်က ရှာဖွေခြင်း"
91msgstr "မကြာသေးခင်က ရှာဖွေခြင်း"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "ဗီဒီယိုများ"
189msgstr "ဗီဒီယိုများ"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/nb.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 07:02+0000\n"
11"PO-Revision-Date: 2013-06-27 07:02+0000\n"
12"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
12"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
13"Language-Team: Norwegian Bokmal <nb@li.org>\n"
13"Language-Team: Norwegian Bokmal <nb@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Siste søk"
91msgstr "Siste søk"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Videoer"
189msgstr "Videoer"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/nl.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 07:19+0000\n"
11"PO-Revision-Date: 2013-06-27 07:19+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Dutch <nl@li.org>\n"
13"Language-Team: Dutch <nl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:05+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Recente zoekopdrachten"
91msgstr "Recente zoekopdrachten"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Video's"
189msgstr "Video's"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/pl.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 08:52+0000\n"
11"PO-Revision-Date: 2013-06-27 08:52+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Polish <pl@li.org>\n"
13"Language-Team: Polish <pl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
18+"|| n%100>=20) ? 1 : 2;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr "YouTube"
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Ostatnie wyszukiwania"
92msgstr "Ostatnie wyszukiwania"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr "Uruchomione aplikacje"
130msgstr "Uruchomione aplikacje"
@@ -153,15 +189,15 @@ msgstr "Popularne w sieci"
153msgid "Videos"
189msgid "Videos"
154msgstr "Filmy"
190msgstr "Filmy"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr "Reżyseria:"
194msgstr "Reżyseria:"
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr "Obsada:"
198msgstr "Obsada:"
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr "Autor:"
202msgstr "Autor:"
167
203
po/pt_BR.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 07:39+0000\n"
11"PO-Revision-Date: 2013-06-27 07:39+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
13"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n > 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:26+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Pesquisas recentes"
91msgstr "Pesquisas recentes"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "Vídeos"
189msgstr "Vídeos"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/ro.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 07:53+0000\n"
11"PO-Revision-Date: 2013-06-27 07:53+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Romanian <ro@li.org>\n"
13"Language-Team: Romanian <ro@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
18+"== 0) && (n != 0))) ? 2: 1));\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr ""
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Căutări recente"
92msgstr "Căutări recente"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr ""
130msgstr ""
@@ -153,15 +189,15 @@ msgstr ""
153msgid "Videos"
189msgid "Videos"
154msgstr "Video"
190msgstr "Video"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr ""
194msgstr ""
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr ""
198msgstr ""
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr ""
202msgstr ""
167
203
po/ru.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-28 06:40+0000\n"
11"PO-Revision-Date: 2013-06-28 06:40+0000\n"
12"Last-Translator: Eugene Marshal <Unknown>\n"
12"Last-Translator: Eugene Marshal <Unknown>\n"
13"Language-Team: Russian <ru@li.org>\n"
13"Language-Team: Russian <ru@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr "YouTube"
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Последние поисковые запросы"
92msgstr "Последние поисковые запросы"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr "Запущенные приложения"
130msgstr "Запущенные приложения"
@@ -153,15 +189,15 @@ msgstr ""
153msgid "Videos"
189msgid "Videos"
154msgstr "Видео"
190msgstr "Видео"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr "Режиссёр"
194msgstr "Режиссёр"
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr "В главных ролях"
198msgstr "В главных ролях"
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr "Автор:"
202msgstr "Автор:"
167
203
po/si.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Sinhalese <si@li.org>\n"
13"Language-Team: Sinhalese <si@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/sl.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-07-02 12:59+0000\n"
11"PO-Revision-Date: 2013-07-02 12:59+0000\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
18+"n%100==4 ? 3 : 0);\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr "YouTube"
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Nedavna iskanja"
92msgstr "Nedavna iskanja"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr ""
130msgstr ""
@@ -153,15 +189,15 @@ msgstr "Priljubljeno na spletu"
153msgid "Videos"
189msgid "Videos"
154msgstr "Videi"
190msgstr "Videi"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr ""
194msgstr ""
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr ""
198msgstr ""
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr ""
202msgstr ""
167
203
po/sr.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 09:19+0000\n"
11"PO-Revision-Date: 2013-06-27 09:19+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Serbian <sr@li.org>\n"
13"Language-Team: Serbian <sr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr ""
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Скорашње претраге"
92msgstr "Скорашње претраге"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr ""
130msgstr ""
@@ -153,15 +189,15 @@ msgstr ""
153msgid "Videos"
189msgid "Videos"
154msgstr "Видео"
190msgstr "Видео"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr ""
194msgstr ""
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr ""
198msgstr ""
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr ""
202msgstr ""
167
203
po/sv.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
11"PO-Revision-Date: 2013-06-26 22:36+0000\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Language-Team: Swedish <sv@li.org>\n"
13"Language-Team: Swedish <sv@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/te.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 09:57+0000\n"
11"PO-Revision-Date: 2013-06-27 09:57+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Telugu <te@li.org>\n"
13"Language-Team: Telugu <te@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/tr.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 10:08+0000\n"
11"PO-Revision-Date: 2013-06-27 10:08+0000\n"
12"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
12"Last-Translator: Adar Cem EREN <adarcemeren34@gmail.com>\n"
13"Language-Team: Turkish <tr@li.org>\n"
13"Language-Team: Turkish <tr@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "Son Arananlar"
91msgstr "Son Arananlar"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "Çalışan uygulamalar"
129msgstr "Çalışan uygulamalar"
@@ -153,15 +188,15 @@ msgstr "Genellikle Çevrimiçi"
153msgid "Videos"
188msgid "Videos"
154msgstr "Videolar"
189msgstr "Videolar"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "Yönetmen"
193msgstr "Yönetmen"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "Yazar:"
201msgstr "Yazar:"
167
202
po/ug.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 11:02+0000\n"
11"PO-Revision-Date: 2013-06-27 11:02+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
13"Language-Team: Uyghur <ug@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:25+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "يېقىنقى ئىزدەشلەر"
91msgstr "يېقىنقى ئىزدەشلەر"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "ئىجرا بولۇۋاتقان ئەپلەر"
129msgstr "ئىجرا بولۇۋاتقان ئەپلەر"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "سىنلار"
189msgstr "سىنلار"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "ئاپتور:"
201msgstr "ئاپتور:"
167
202
po/uk.po+41−5
@@ -7,14 +7,16 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-07-21 05:47+0000\n"
11"PO-Revision-Date: 2013-07-21 05:47+0000\n"
12"Last-Translator: Ярослав Смук <Smuk.Slavko@yandex.ua>\n"
12"Last-Translator: Ярослав Смук <Smuk.Slavko@yandex.ua>\n"
13"Language-Team: Ukrainian <uk@li.org>\n"
13"Language-Team: Ukrainian <uk@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
19+"X-Launchpad-Export-Date: 2013-08-14 06:26+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
20"X-Generator: Launchpad (build 16723)\n"
19
21
20#: Applications/applications.js:23
22#: Applications/applications.js:23
@@ -89,6 +91,40 @@ msgstr "YouTube"
89msgid "Recent searches"
91msgid "Recent searches"
90msgstr "Нещодавні пошуки"
92msgstr "Нещодавні пошуки"
91
93
94+#. TRANSLATORS: Number of persons who rated this app
95+#: Dash/Apps/AppInfo.qml:72
96+#, qt-format
97+msgid "(%1)"
98+msgstr ""
99+
100+#. TRANSLATORS: Number of persons who wrote reviews for this app
101+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
102+#, qt-format
103+msgid "%1 review"
104+msgid_plural "%1 reviews"
105+msgstr[0] ""
106+msgstr[1] ""
107+
108+#: Dash/Apps/AppPreview.qml:181
109+msgid "Rate this"
110+msgstr ""
111+
112+#: Dash/Apps/AppReviews.qml:72
113+msgid "Add a review"
114+msgstr ""
115+
116+#: Dash/Apps/AppReviews.qml:84
117+msgid "Review"
118+msgstr ""
119+
120+#: Dash/Apps/AppReviews.qml:118
121+msgid "Send"
122+msgstr ""
123+
124+#: Dash/Apps/AppReviews.qml:136
125+msgid "Comments:"
126+msgstr ""
127+
92#: Dash/DashApps.qml:65
128#: Dash/DashApps.qml:65
93msgid "Running apps"
129msgid "Running apps"
94msgstr "Запущені програми"
130msgstr "Запущені програми"
@@ -153,15 +189,15 @@ msgstr "Популярне у мережі"
153msgid "Videos"
189msgid "Videos"
154msgstr "Відео"
190msgstr "Відео"
155
191
156−#: Dash/Video/VideoPreview.qml:98
192+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
193msgid "Directed by:"
158msgstr "Режисер:"
194msgstr "Режисер:"
159
195
160−#: Dash/Video/VideoPreview.qml:121
196+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
197msgid "Starring:"
162msgstr "Актори:"
198msgstr "Актори:"
163
199
164−#: Dash/Video/VideoPreview.qml:144
200+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
201msgid "Author:"
166msgstr "Автор:"
202msgstr "Автор:"
167
203
po/unity8.pot+39−4
@@ -8,7 +8,7 @@ msgid ""
8msgstr ""
8msgstr ""
9"Project-Id-Version: unity8\n"
9"Project-Id-Version: unity8\n"
10"Report-Msgid-Bugs-To: \n"
10"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
11+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,6 +16,7 @@ msgstr ""
16"MIME-Version: 1.0\n"
16"MIME-Version: 1.0\n"
17"Content-Type: text/plain; charset=CHARSET\n"
17"Content-Type: text/plain; charset=CHARSET\n"
18"Content-Transfer-Encoding: 8bit\n"
18"Content-Transfer-Encoding: 8bit\n"
19+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
21msgid "Phone"
22msgid "Phone"
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr ""
91msgstr ""
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr ""
129msgstr ""
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr ""
189msgstr ""
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
po/zh_CN.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 10:33+0000\n"
11"PO-Revision-Date: 2013-06-27 10:33+0000\n"
12"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
12"Last-Translator: Anthony Wong <anthony.wong@canonical.com>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:26+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr "YouTube"
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "近期搜索"
91msgstr "近期搜索"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "正在运行的应用程序"
129msgstr "正在运行的应用程序"
@@ -153,15 +188,15 @@ msgstr "经常在线"
153msgid "Videos"
188msgid "Videos"
154msgstr "视频"
189msgstr "视频"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr "导演:"
193msgstr "导演:"
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr "主演:"
197msgstr "主演:"
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr "作者:"
201msgstr "作者:"
167
202
po/zh_TW.po+40−5
@@ -7,14 +7,15 @@ msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-08-09 10:12+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11"PO-Revision-Date: 2013-06-27 10:24+0000\n"
11"PO-Revision-Date: 2013-06-27 10:24+0000\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
13"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17+"Plural-Forms: nplurals=1; plural=0;\n"
17−"X-Launchpad-Export-Date: 2013-08-10 06:06+0000\n"
18+"X-Launchpad-Export-Date: 2013-08-14 06:26+0000\n"
18"X-Generator: Launchpad (build 16723)\n"
19"X-Generator: Launchpad (build 16723)\n"
19
20
20#: Applications/applications.js:23
21#: Applications/applications.js:23
@@ -89,6 +90,40 @@ msgstr ""
89msgid "Recent searches"
90msgid "Recent searches"
90msgstr "最近搜尋"
91msgstr "最近搜尋"
91
92
93+#. TRANSLATORS: Number of persons who rated this app
94+#: Dash/Apps/AppInfo.qml:72
95+#, qt-format
96+msgid "(%1)"
97+msgstr ""
98+
99+#. TRANSLATORS: Number of persons who wrote reviews for this app
100+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
101+#, qt-format
102+msgid "%1 review"
103+msgid_plural "%1 reviews"
104+msgstr[0] ""
105+msgstr[1] ""
106+
107+#: Dash/Apps/AppPreview.qml:181
108+msgid "Rate this"
109+msgstr ""
110+
111+#: Dash/Apps/AppReviews.qml:72
112+msgid "Add a review"
113+msgstr ""
114+
115+#: Dash/Apps/AppReviews.qml:84
116+msgid "Review"
117+msgstr ""
118+
119+#: Dash/Apps/AppReviews.qml:118
120+msgid "Send"
121+msgstr ""
122+
123+#: Dash/Apps/AppReviews.qml:136
124+msgid "Comments:"
125+msgstr ""
126+
92#: Dash/DashApps.qml:65
127#: Dash/DashApps.qml:65
93msgid "Running apps"
128msgid "Running apps"
94msgstr "執行中的程式"
129msgstr "執行中的程式"
@@ -153,15 +188,15 @@ msgstr ""
153msgid "Videos"
188msgid "Videos"
154msgstr "影片"
189msgstr "影片"
155
190
156−#: Dash/Video/VideoPreview.qml:98
191+#: Dash/Video/VideoPreview.qml:130
157msgid "Directed by:"
192msgid "Directed by:"
158msgstr ""
193msgstr ""
159
194
160−#: Dash/Video/VideoPreview.qml:121
195+#: Dash/Video/VideoPreview.qml:153
161msgid "Starring:"
196msgid "Starring:"
162msgstr ""
197msgstr ""
163
198
164−#: Dash/Video/VideoPreview.qml:144
199+#: Dash/Video/VideoPreview.qml:176
165msgid "Author:"
200msgid "Author:"
166msgstr ""
201msgstr ""
167
202
src/Panel/Indicators/client/indicatorsclient.cpp+12
@@ -26,6 +26,8 @@
26#include <QQmlEngine>
26#include <QQmlEngine>
27#include <QDebug>
27#include <QDebug>
28
28
29+namespace {
30+
29void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
31void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
30{
32{
31 QStringList importPathList = engine->importPathList();
33 QStringList importPathList = engine->importPathList();
@@ -51,11 +53,21 @@ void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
51 engine->setImportPathList(importPathList);
53 engine->setImportPathList(importPathList);
52}
54}
53
55
56+void resolveIconTheme() {
57+ QString ubuntuIconTheme = getenv("UBUNTU_ICON_THEME");
58+ if (ubuntuIconTheme.isEmpty()) {
59+ QIcon::setThemeName("ubuntu-mobile");
60+ }
61+}
62+} // namespace
63+
54IndicatorsClient::IndicatorsClient(int &argc, char **argv)
64IndicatorsClient::IndicatorsClient(int &argc, char **argv)
55 : QObject(0),
65 : QObject(0),
56 m_view(0)
66 m_view(0)
57{
67{
58 m_application = new QApplication(argc, argv);
68 m_application = new QApplication(argc, argv);
69+ resolveIconTheme();
70+
59 QStringList args = m_application->arguments();
71 QStringList args = m_application->arguments();
60
72
61 m_view = new QQuickView;
73 m_view = new QQuickView;
src/Panel/Indicators/servicefiles/com.canonical.indicator.battery+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-battery
2Name=indicator-battery
3ObjectPath=/com/canonical/indicator/battery
3ObjectPath=/com/canonical/indicator/battery
4+Position=40
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/battery/phone
7ObjectPath=/com/canonical/indicator/battery/phone
src/Panel/Indicators/servicefiles/com.canonical.indicator.messages+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-messaging
2Name=indicator-messaging
3ObjectPath=/com/canonical/indicator/messages
3ObjectPath=/com/canonical/indicator/messages
4+Position=50
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/messages/phone
7ObjectPath=/com/canonical/indicator/messages/phone
src/Panel/Indicators/servicefiles/com.canonical.indicator.time+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-time
2Name=indicator-time
3ObjectPath=/com/canonical/indicator/time
3ObjectPath=/com/canonical/indicator/time
4+Position=20
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/time/phone
7ObjectPath=/com/canonical/indicator/time/phone
src/Panel/Indicators/servicefiles/com.canonical.settings.network+2−1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2−Name=indicator-network
2+Name=chewie-network
3ObjectPath=/com/canonical/settings/network
3ObjectPath=/com/canonical/settings/network
4+Position=69
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/settings/network/phone
7ObjectPath=/com/canonical/settings/network/phone
src/Panel/Indicators/servicefiles/com.canonical.settings.sound+2−1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2−Name=indicator-sound
2+Name=chewie-sound
3ObjectPath=/com/canonical/settings/sound
3ObjectPath=/com/canonical/settings/sound
4+Position=30
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/settings/sound/phone
7ObjectPath=/com/canonical/settings/sound/phone
tests/autopilot/unity8/shell/emulators/dash.py+3−3
@@ -25,9 +25,9 @@ class Dash(UnityEmulatorBase):
25 """An emulator that understands the Dash."""
25 """An emulator that understands the Dash."""
26
26
27 def get_home_applications_grid(self):
27 def get_home_applications_grid(self):
28− return self.select_single(
28+ return self.get_scope('home').select_single(
29− "ApplicationsFilterGrid",
29+ "GenericFilterGrid",
30− objectName="dashHomeApplicationsGrid"
30+ objectName="applications.scope"
31 )
31 )
32
32
33 def get_application_icon(self, text):
33 def get_application_icon(self, text):
tests/autopilot/unity8/shell/tests/test_lock_screen.py+19−2
@@ -27,7 +27,9 @@ from autopilot.matchers import Eventually
27from autopilot.platform import model
27from autopilot.platform import model
28from testtools import skipUnless
28from testtools import skipUnless
29from testtools.matchers import Equals
29from testtools.matchers import Equals
30+import logging
30
31
32+logger = logging.getLogger(__name__)
31
33
32class TestLockscreen(UnityTestCase):
34class TestLockscreen(UnityTestCase):
33
35
@@ -143,7 +145,10 @@ class TestLockscreen(UnityTestCase):
143
145
144 pinentryField = self.main_window.get_pinentryField()
146 pinentryField = self.main_window.get_pinentryField()
145 self.touch.tap_object(pinentryField)
147 self.touch.tap_object(pinentryField)
148+ self.assertThat(pinentryField.activeFocus, Eventually(Equals(True)))
146− self.keyboard.type(passphrase)
149+ for character in passphrase:
150+ self._type_character(character, pinentryField)
151+ logger.debug("Typed passphrase: %s", pinentryField.text)
147 self.keyboard.type("\n")
152 self.keyboard.type("\n")
148
153
149 def _enter_prompt_passphrase(self, passphrase):
154 def _enter_prompt_passphrase(self, passphrase):
@@ -159,5 +164,17 @@ class TestLockscreen(UnityTestCase):
159
164
160 prompt = self.main_window.get_greeter().get_prompt()
165 prompt = self.main_window.get_greeter().get_prompt()
161 self.touch.tap_object(prompt)
166 self.touch.tap_object(prompt)
167+ self.assertThat(prompt.activeFocus, Eventually(Equals(True)))
162− self.keyboard.type(passphrase)
168+ for character in passphrase:
169+ self._type_character(character, prompt)
170+ logger.debug("Typed passphrase: %s", prompt.text)
163 self.keyboard.type("\n")
171 self.keyboard.type("\n")
172+
173+ def _type_character(self, character, prompt, retries=5):
174+ current_text = prompt.text
175+ self.keyboard.type(character)
176+ try:
177+ self.assertThat(prompt.text, Eventually(Equals(current_text + character)))
178+ except AssertionError:
179+ if retries > 0:
180+ self._type_character(character, prompt, retries-1)
tests/data/unity/indicators/com.canonical.indicator.fake1+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-fake1
2Name=indicator-fake1
3ObjectPath=/com/canonical/indicator/fake1
3ObjectPath=/com/canonical/indicator/fake1
4+Position=1
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/fake1/phone
7ObjectPath=/com/canonical/indicator/fake1/phone
tests/data/unity/indicators/com.canonical.indicator.fake2+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-fake2
2Name=indicator-fake2
3ObjectPath=/com/canonical/indicator/fake2
3ObjectPath=/com/canonical/indicator/fake2
4+Position=0
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/fake2/phone
7ObjectPath=/com/canonical/indicator/fake2/phone
tests/data/unity/indicators/com.canonical.indicator.fake3+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-fake3
2Name=indicator-fake3
3ObjectPath=/com/canonical/indicator/fake3
3ObjectPath=/com/canonical/indicator/fake3
4+Position=3
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/fake3/phone
7ObjectPath=/com/canonical/indicator/fake3/phone
tests/data/unity/indicators/com.canonical.indicator.fake4+1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2Name=indicator-fake4
2Name=indicator-fake4
3ObjectPath=/com/canonical/indicator/fake4
3ObjectPath=/com/canonical/indicator/fake4
4+Position=2
4
5
5[phone]
6[phone]
6ObjectPath=/com/canonical/indicator/fake4/phone
7ObjectPath=/com/canonical/indicator/fake4/phone
tests/mocks/CMakeLists.txt+2−1
@@ -1,6 +1,7 @@
1+add_subdirectory(HudClient)
1add_subdirectory(libusermetrics)
2add_subdirectory(libusermetrics)
2add_subdirectory(LightDM)
3add_subdirectory(LightDM)
4+add_subdirectory(Powerd)
3add_subdirectory(QMenuModel)
5add_subdirectory(QMenuModel)
4add_subdirectory(Ubuntu)
6add_subdirectory(Ubuntu)
5add_subdirectory(Unity)
7add_subdirectory(Unity)
6−add_subdirectory(HudClient)
tests/mocks/Powerd/CMakeLists.txtnew file+21
@@ -0,0 +1,21 @@
1+add_definitions(-DSM_BUSNAME=sessionBus)
2+
3+add_library(MockPowerd-qml MODULE
4+ plugin.cpp
5+ Powerd.cpp
6+ )
7+
8+qt5_use_modules(MockPowerd-qml Qml)
9+
10+# copy qmldir file into build directory for shadow builds
11+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
12+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
13+ )
14+
15+install(TARGETS MockPowerd-qml
16+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Powerd
17+ )
18+
19+install(FILES qmldir
20+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Powerd
21+ )
tests/mocks/Powerd/Powerd.cppnew file+24
@@ -0,0 +1,24 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "Powerd.h"
20+
21+Powerd::Powerd(QObject* parent)
22+ : QObject(parent)
23+{
24+}
tests/mocks/Powerd/Powerd.hnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#ifndef UNITY_MOCK_POWERD_H
20+#define UNITY_MOCK_POWERD_H
21+
22+#include <QtCore/QObject>
23+#include <QtDBus/QDBusInterface>
24+
25+class Powerd: public QObject
26+{
27+ Q_OBJECT
28+
29+public:
30+ explicit Powerd(QObject *parent = 0);
31+
32+Q_SIGNALS:
33+ void powerStateChange(int state);
34+};
35+
36+#endif
tests/mocks/Powerd/plugin.cppnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "plugin.h"
20+#include "Powerd.h"
21+
22+#include <QtQml/QtQml>
23+
24+static QObject *powerd_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25+{
26+ Q_UNUSED(engine)
27+ Q_UNUSED(scriptEngine)
28+ return new Powerd();
29+}
30+
31+void PowerdPlugin::registerTypes(const char *uri)
32+{
33+ Q_ASSERT(uri == QLatin1String("Powerd"));
34+ qmlRegisterSingletonType<Powerd>(uri, 0, 1, "Powerd", powerd_provider);
35+}
tests/mocks/Powerd/plugin.hnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#ifndef MOCK_POWER_PLUGIN_H
20+#define MOCK_POWER_PLUGIN_H
21+
22+#include <QtQml/QQmlEngine>
23+#include <QtQml/QQmlExtensionPlugin>
24+
25+class PowerdPlugin : public QQmlExtensionPlugin
26+{
27+ Q_OBJECT
28+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
29+
30+public:
31+ void registerTypes(const char *uri);
32+};
33+
34+#endif
tests/mocks/Powerd/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Powerd
2+plugin MockPowerd-qml
tests/mocks/Ubuntu/CMakeLists.txt+1
@@ -1 +1,2 @@
1add_subdirectory(Application)
1add_subdirectory(Application)
2+add_subdirectory(DownloadDaemonListener)
tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txtnew file+18
@@ -0,0 +1,18 @@
1+set(FakeUbuntuDownloadDaemonListenerQml_SOURCES
2+ plugin.cpp
3+ MockDownloadTracker.cpp
4+)
5+
6+add_library(FakeUbuntuDownloadDaemonListenerQml MODULE ${FakeUbuntuDownloadDaemonListenerQml_SOURCES})
7+
8+qt5_use_modules(FakeUbuntuDownloadDaemonListenerQml Core Quick)
9+
10+# copy files into build directory for shadow builds
11+add_custom_target(UbuntuDownloadQmlDirFile ALL
12+ COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
13+ DEPENDS qmldir
14+)
15+
16+install(TARGETS FakeUbuntuDownloadDaemonListenerQml
17+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/DownloadDaemonListener
18+ )
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cppnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
19+ */
20+
21+
22+#include "MockDownloadTracker.h"
23+
24+MockDownloadTracker::MockDownloadTracker(QObject *parent)
25+ : QObject(parent)
26+ , m_active(false)
27+{
28+}
29+
30+bool MockDownloadTracker::isServiceReady() const
31+{
32+ return m_active;
33+}
34+
35+QString MockDownloadTracker::dbusPath() const
36+{
37+ return m_dbusPath;
38+}
39+
40+void MockDownloadTracker::setDbusPath(const QString& path)
41+{
42+ if(m_dbusPath != path){
43+ m_dbusPath = path;
44+ startService();
45+ }
46+}
47+
48+QString MockDownloadTracker::service() const
49+{
50+ return m_service;
51+}
52+
53+void MockDownloadTracker::setService(const QString& service)
54+{
55+ if(m_service != service){
56+ m_service = service;
57+ startService();
58+ }
59+}
60+
61+void MockDownloadTracker::startService()
62+{
63+ if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
64+ m_active = true;
65+ Q_EMIT serviceReadyChanged(m_active);
66+ }
67+}
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
19+ */
20+
21+
22+#ifndef MOCKDOWNLOADTRACKER_H
23+#define MOCKDOWNLOADTRACKER_H
24+
25+#include <QObject>
26+
27+class MockDownloadTracker : public QObject
28+{
29+ Q_OBJECT
30+ Q_DISABLE_COPY(MockDownloadTracker)
31+ Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged)
32+ Q_PROPERTY(QString dbusPath READ dbusPath WRITE setDbusPath NOTIFY dbusPathChanged)
33+ Q_PROPERTY(bool serviceReady READ isServiceReady NOTIFY serviceReadyChanged)
34+
35+public:
36+ explicit MockDownloadTracker(QObject *parent = 0);
37+
38+ QString service() const;
39+ QString dbusPath() const;
40+ bool isServiceReady() const;
41+
42+ void setDbusPath(const QString& path);
43+ void setService(const QString& service);
44+
45+Q_SIGNALS:
46+ void serviceChanged(const QString &service);
47+ void dbusPathChanged(const QString &dbusPath);
48+ void serviceReadyChanged(const bool &serviceReady);
49+
50+ void canceled(bool success);
51+ void error(const QString &error);
52+ void finished(const QString &path);
53+ void paused(bool success);
54+ void progress(qulonglong received, qulonglong total);
55+ void resumed(bool success);
56+ void started(bool success);
57+
58+private:
59+ QString m_dbusPath;
60+ QString m_service;
61+ bool m_active;
62+
63+ void startService();
64+};
65+
66+#endif // MOCKDOWNLOADTRACKER_H
tests/mocks/Ubuntu/DownloadDaemonListener/plugin.cppnew file+28
@@ -0,0 +1,28 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "MockDownloadTracker.h"
19+
20+#include <QtQml>
21+#include <QtQml/QQmlContext>
22+#include <qqml.h>
23+
24+
25+void FakeUbuntuDownloadDaemonListenerQmlPlugin::registerTypes(const char *uri)
26+{
27+ qmlRegisterType<MockDownloadTracker>(uri, 0, 1, "DownloadTracker");
28+}
tests/mocks/Ubuntu/DownloadDaemonListener/plugin.hnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef PLUGIN_H
18+#define PLUGIN_H
19+
20+#include <QQmlExtensionPlugin>
21+
22+class FakeUbuntuDownloadDaemonListenerQmlPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+public:
27+ void registerTypes(const char *uri);
28+};
29+
30+#endif
tests/mocks/Ubuntu/DownloadDaemonListener/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Ubuntu.DownloadDaemonListener
2+plugin FakeUbuntuDownloadDaemonListenerQml
tests/mocks/Unity/Indicators/IndicatorsModel.qml+1−1
@@ -64,7 +64,7 @@ ListModel {
64 isValid: "";
64 isValid: "";
65 }
65 }
66 ListElement {
66 ListElement {
67− identifier: "indicator-fake4";
67+ identifier: "indicator-fake5";
68 priority: 4
68 priority: 4
69 title: "Menu5";
69 title: "Menu5";
70 description: "";
70 description: "";
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+10−14
@@ -22,34 +22,30 @@
22
22
23MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(parent)
23MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(parent)
24{
24{
25− MockLauncherItem *item = new MockLauncherItem("phone-app", "/usr/share/applications/phone-app.desktop", "Phone", "phone-app");
25+ MockLauncherItem *item = new MockLauncherItem("phone-app", "/usr/share/applications/phone-app.desktop", "Phone", "phone-app", this);
26 m_list.append(item);
26 m_list.append(item);
27− item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera");
27+ item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera", this);
28 m_list.append(item);
28 m_list.append(item);
29− item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery");
29+ item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);
30 m_list.append(item);
30 m_list.append(item);
31− item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook");
31+ item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook", this);
32 m_list.append(item);
32 m_list.append(item);
33− item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser");
33+ item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this);
34 m_list.append(item);
34 m_list.append(item);
35− item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter");
35+ item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);
36 m_list.append(item);
36 m_list.append(item);
37− item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail");
37+ item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this);
38 m_list.append(item);
38 m_list.append(item);
39− item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather");
39+ item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this);
40 m_list.append(item);
40 m_list.append(item);
41− item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
41+ item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this);
42 m_list.append(item);
42 m_list.append(item);
43− item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar");
43+ item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar", this);
44 m_list.append(item);
44 m_list.append(item);
45}
45}
46
46
47MockLauncherModel::~MockLauncherModel()
47MockLauncherModel::~MockLauncherModel()
48{
48{
49− while (!m_list.empty())
50− {
51− m_list.takeFirst()->deleteLater();
52− }
53}
49}
54
50
55int MockLauncherModel::rowCount(const QModelIndex& parent) const
51int MockLauncherModel::rowCount(const QModelIndex& parent) const
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+22
@@ -1612,6 +1612,28 @@ private Q_SLOTS:
1612 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1612 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1613 }
1613 }
1614
1614
1615+ void testMaximizeVisibleAreaWithItemResize()
1616+ {
1617+ model->setProperty(0, "size", 1000);
1618+
1619+ bool res = lvwph->maximizeVisibleArea(1);
1620+ QVERIFY(res);
1621+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1622+
1623+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1624+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1625+ verifyItem(0, -658., 1000., false);
1626+ verifyItem(1, 342., 200., false);
1627+ verifyItem(2, 542, 350., true);
1628+ QCOMPARE(lvwph->m_minYExtent, 0.);
1629+ QCOMPARE(lvwph->m_clipItem->y(), 708.);
1630+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1631+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1632+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1633+ QCOMPARE(lvwph->contentY(), 708.);
1634+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1635+ }
1636+
1615private:
1637private:
1616 QQuickView *view;
1638 QQuickView *view;
1617 ListViewWithPageHeader *lvwph;
1639 ListViewWithPageHeader *lvwph;
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+22
@@ -2033,6 +2033,28 @@ private Q_SLOTS:
2033 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
2033 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
2034 }
2034 }
2035
2035
2036+ void testMaximizeVisibleAreaWithItemResize()
2037+ {
2038+ model->setProperty(0, "size", 1000);
2039+
2040+ bool res = lvwph->maximizeVisibleArea(1);
2041+ QVERIFY(res);
2042+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
2043+
2044+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
2045+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2046+ verifyItem(0, -738., 1040., false, "Agressive", true);
2047+ verifyItem(1, 302., 240., false, "Regular", false);
2048+ verifyItem(2, 542, 390., true, "Mild", true);
2049+ QCOMPARE(lvwph->m_minYExtent, 0.);
2050+ QCOMPARE(lvwph->m_clipItem->y(), 788.);
2051+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2052+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
2053+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
2054+ QCOMPARE(lvwph->contentY(), 788.);
2055+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2056+ }
2057+
2036private:
2058private:
2037 QQuickView *view;
2059 QQuickView *view;
2038 ListViewWithPageHeader *lvwph;
2060 ListViewWithPageHeader *lvwph;
tests/plugins/Unity/CMakeLists.txt+9−1
@@ -2,12 +2,16 @@ add_subdirectory(Indicators)
2
2
3pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
3pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
4pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
4pkg_check_modules(LIBUNITYPROTO REQUIRED unity-protocol-private)
5+pkg_check_modules(LIBUNITY REQUIRED unity)
6+pkg_check_modules(LIBSIGCPP REQUIRED sigc++-2.0)
5
7
6include_directories(
8include_directories(
7 ${Unity-qml_SOURCE_DIR}
9 ${Unity-qml_SOURCE_DIR}
8 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Unity
10 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Unity
9 ${CMAKE_CURRENT_BINARY_DIR}
11 ${CMAKE_CURRENT_BINARY_DIR}
10 ${LIBUNITYPROTO_INCLUDE_DIRS}
12 ${LIBUNITYPROTO_INCLUDE_DIRS}
13+ ${LIBUNITY_INCLUDE_DIRS}
14+ ${LIBSIGCPP_INCLUDE_DIRS}
11 ${UNITYCORE_INCLUDE_DIRS}
15 ${UNITYCORE_INCLUDE_DIRS}
12 )
16 )
13
17
@@ -20,7 +24,7 @@ macro(run_tests)
20 -o -,txt)
24 -o -,txt)
21 add_test(NAME test${CLASSNAME}${_test} COMMAND ${testCommand})
25 add_test(NAME test${CLASSNAME}${_test} COMMAND ${testCommand})
22 add_custom_target(${_test} ${testCommand})
26 add_custom_target(${_test} ${testCommand})
23− add_executable(${_test}Exec ${_test}.cpp previewbindingstest.cpp)
27+ add_executable(${_test}Exec ${_test}.cpp)
24 qt5_use_modules(${_test}Exec Test Core Qml)
28 qt5_use_modules(${_test}Exec Test Core Qml)
25 set_tests_properties(test${CLASSNAME}${_test}
29 set_tests_properties(test${CLASSNAME}${_test}
26 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Unity:${LIBUNITYPROTO_LIBRARY_DIRS}")
30 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Unity:${LIBUNITYPROTO_LIBRARY_DIRS}")
@@ -28,7 +32,9 @@ macro(run_tests)
28 target_link_libraries(${_test}Exec
32 target_link_libraries(${_test}Exec
29 Unity-qml
33 Unity-qml
30 ${UNITYCORE_LDFLAGS}
34 ${UNITYCORE_LDFLAGS}
35+ ${LIBUNITY_LDFLAGS}
31 ${LIBUNITYPROTO_LDFLAGS}
36 ${LIBUNITYPROTO_LDFLAGS}
37+ ${LIBSIGCPP_LDFLAGS}
32 )
38 )
33
39
34 set(_test_list "${_test_list};${_test}")
40 set(_test_list "${_test_list};${_test}")
@@ -36,5 +42,7 @@ macro(run_tests)
36endmacro(run_tests)
42endmacro(run_tests)
37
43
38run_tests(
44run_tests(
45+ signalslisttest
39 previewbindingstest
46 previewbindingstest
47+ filtersbindingstest
40 )
48 )
tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp+1−1
@@ -72,11 +72,11 @@ private Q_SLOTS:
72 QVERIFY(indicator ? true : false);
72 QVERIFY(indicator ? true : false);
73
73
74 QCOMPARE(indicator->identifier(), QString("indicator-fake1"));
74 QCOMPARE(indicator->identifier(), QString("indicator-fake1"));
75+ QCOMPARE(indicator->position(), 1);
75
76
76 // Check that the initial properties have been set.
77 // Check that the initial properties have been set.
77 QVariantMap props = indicator->indicatorProperties().toMap();
78 QVariantMap props = indicator->indicatorProperties().toMap();
78 QCOMPARE(props.count(), 4);
79 QCOMPARE(props.count(), 4);
79− QCOMPARE(props["busType"].toInt(), 1);
80 QCOMPARE(props["busName"].toString(), QString("com.canonical.indicator.fake1"));
80 QCOMPARE(props["busName"].toString(), QString("com.canonical.indicator.fake1"));
81 QCOMPARE(props["actionsObjectPath"].toString(), QString("/com/canonical/indicator/fake1"));
81 QCOMPARE(props["actionsObjectPath"].toString(), QString("/com/canonical/indicator/fake1"));
82
82
tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp+23−16
@@ -66,10 +66,10 @@ private Q_SLOTS:
66 {
66 {
67 // Priority order. (2, 1, 4, 3)
67 // Priority order. (2, 1, 4, 3)
68 QVariantMap map;
68 QVariantMap map;
69− QVariantMap map1; map1["priority"] = 1; map1["title"] = "fake1";
69+ QVariantMap map1; map1["title"] = "fake1";
70− QVariantMap map2; map2["priority"] = 0; map2["title"] = "fake2";
70+ QVariantMap map2; map2["title"] = "fake2";
71− QVariantMap map3; map3["priority"] = 3; map3["title"] = "fake3";
71+ QVariantMap map3; map3["title"] = "fake3";
72− QVariantMap map4; map4["priority"] = 2; map4["title"] = "fake4";
72+ QVariantMap map4; map4["title"] = "fake4";
73 map["indicator-fake1"] = map1;
73 map["indicator-fake1"] = map1;
74 map["indicator-fake2"] = map2;
74 map["indicator-fake2"] = map2;
75 map["indicator-fake3"] = map3;
75 map["indicator-fake3"] = map3;
@@ -79,21 +79,28 @@ private Q_SLOTS:
79 model.setIndicatorData(map);
79 model.setIndicatorData(map);
80 model.load();
80 model.load();
81
81
82− QCOMPARE(model.data(0, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake2"));
82+ // should be in order:
83− QCOMPARE(model.data(0, IndicatorsModelRole::Title).toString(), QString("fake2"));
83+ // fake3, fake4, fake1, fake2
84− QCOMPARE(model.data(0, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake2"));
85
84
86− QCOMPARE(model.data(1, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake1"));
85+ QCOMPARE(model.data(0, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake3"));
87− QCOMPARE(model.data(1, IndicatorsModelRole::Title).toString(), QString("fake1"));
86+ QCOMPARE(model.data(0, IndicatorsModelRole::Title).toString(), QString("fake3"));
87+ QCOMPARE(model.data(0, IndicatorsModelRole::Position).toInt(), 3);
88− QCOMPARE(model.data(1, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake1"));
88+ QCOMPARE(model.data(0, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake3"));
89
89
90− QCOMPARE(model.data(2, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake4"));
90+ QCOMPARE(model.data(1, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake4"));
91− QCOMPARE(model.data(2, IndicatorsModelRole::Title).toString(), QString("fake4"));
91+ QCOMPARE(model.data(1, IndicatorsModelRole::Title).toString(), QString("fake4"));
92+ QCOMPARE(model.data(1, IndicatorsModelRole::Position).toInt(), 2);
92− QCOMPARE(model.data(2, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake4"));
93+ QCOMPARE(model.data(1, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake4"));
93
94
95+ QCOMPARE(model.data(2, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake1"));
96+ QCOMPARE(model.data(2, IndicatorsModelRole::Title).toString(), QString("fake1"));
97+ QCOMPARE(model.data(2, IndicatorsModelRole::Position).toInt(), 1);
98+ QCOMPARE(model.data(2, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake1"));
99+
94− QCOMPARE(model.data(3, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake3"));
100+ QCOMPARE(model.data(3, IndicatorsModelRole::Identifier).toString(), QString("indicator-fake2"));
95− QCOMPARE(model.data(3, IndicatorsModelRole::Title).toString(), QString("fake3"));
101+ QCOMPARE(model.data(3, IndicatorsModelRole::Title).toString(), QString("fake2"));
102+ QCOMPARE(model.data(3, IndicatorsModelRole::Position).toInt(), 0);
96− QCOMPARE(model.data(3, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake3"));
103+ QCOMPARE(model.data(3, IndicatorsModelRole::IndicatorProperties).toMap()["busName"].toString(), QString("com.canonical.indicator.fake2"));
97 }
104 }
98};
105};
99
106
tests/plugins/Unity/filtersbindingstest.cppnew file+484
@@ -0,0 +1,484 @@
1+/*
2+* Copyright (C) 2013 Canonical, Ltd.
3+*
4+* Authors:
5+* Pawel Stolowski <pawel.stolowski@canonical.com>
6+*
7+* This program is free software; you can redistribute it and/or modify
8+* it under the terms of the GNU General Public License as published by
9+* the Free Software Foundation; version 3.
10+*
11+* This program is distributed in the hope that it will be useful,
12+* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+* GNU General Public License for more details.
15+*
16+* You should have received a copy of the GNU General Public License
17+* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+*/
19+
20+#include "filtersbindingstest.h"
21+
22+// libunity-core
23+#include <UnityCore/Filter.h>
24+#include <UnityCore/MultiRangeFilter.h>
25+
26+// Qt
27+#include <QTest>
28+#include <QSignalSpy>
29+
30+// libunity
31+#include <unity.h>
32+
33+// local
34+#include "filter.h"
35+#include "multirangefilter.h"
36+#include "checkoptionfilter.h"
37+#include "radiooptionfilter.h"
38+#include "ratingsfilter.h"
39+#include "ratingfilteroption.h"
40+#include "genericoptionsmodel.h"
41+
42+void FiltersBindingsTest::initTestCase()
43+{
44+}
45+
46+GVariant* FiltersBindingsTest::createOptions(int numOfOptions)
47+{
48+ auto vtype = g_variant_type_new("a(sssb)");
49+ auto vb = g_variant_builder_new(vtype);
50+ for (int i = 0; i<numOfOptions; i++) {
51+ const std::string optId = "opt" + std::to_string(i);
52+ const std::string optName = "Option " + std::to_string(i);
53+ g_variant_builder_add(vb, "(sssb)", optId.c_str(), optName.c_str(), "", false);
54+ }
55+ return g_variant_builder_end(vb);
56+}
57+
58+DeeModel* FiltersBindingsTest::createFilterModel()
59+{
60+ const char* filter_schema[8] = {"s", "s", "s", "s", "a{sv}", "b", "b", "b"};
61+ auto model = dee_sequence_model_new();
62+ dee_model_set_schema_full (DEE_MODEL(model), filter_schema, 8);
63+ return model;
64+}
65+
66+void FiltersBindingsTest::createMultiRangeFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
67+{
68+ createFilter(model, "filter-multirange", id, name, optionCount);
69+}
70+
71+void FiltersBindingsTest::createRadioOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
72+{
73+ createFilter(model, "filter-radiooption", id, name, optionCount);
74+}
75+
76+void FiltersBindingsTest::createCheckOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
77+{
78+ createFilter(model, "filter-checkoption", id, name, optionCount);
79+}
80+
81+void FiltersBindingsTest::createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name)
82+{
83+ GVariant* row[8];
84+
85+ row[0] = g_variant_new_string(id.c_str());
86+ row[1] = g_variant_new_string(name.c_str());
87+ row[2] = g_variant_new_string(""); // icon hint
88+ row[3] = g_variant_new_string("filter-ratings");
89+
90+ GVariant *children[2];
91+ GVariant *key1 = g_variant_new_string("show-all-button");
92+ GVariant *key2 = g_variant_new_string("rating");
93+ children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(false)));
94+ children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(g_variant_new_double(0.0f)));
95+ auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
96+
97+ row[4] = fhints;
98+ row[5] = g_variant_new_boolean(true); // visible
99+ row[6] = g_variant_new_boolean(false); // collapsed
100+ row[7] = g_variant_new_boolean(false); // filtering
101+
102+ dee_model_append_row(model, row);
103+}
104+
105+void FiltersBindingsTest::createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount)
106+{
107+ GVariant* row[8];
108+
109+ row[0] = g_variant_new_string(id.c_str());
110+ row[1] = g_variant_new_string(name.c_str());
111+ row[2] = g_variant_new_string(""); // icon hint
112+ row[3] = g_variant_new_string(renderer.c_str()); // renderer
113+
114+ GVariant *children[2];
115+ GVariant *key1 = g_variant_new_string("show-all-button");
116+ GVariant *key2 = g_variant_new_string("options");
117+ children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(false)));
118+ children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(createOptions(optionCount)));
119+ auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
120+
121+ row[4] = fhints;
122+ row[5] = g_variant_new_boolean(true); // visible
123+ row[6] = g_variant_new_boolean(false); // collapsed
124+ row[7] = g_variant_new_boolean(false); // filtering
125+
126+ dee_model_append_row(model, row);
127+}
128+
129+void FiltersBindingsTest::testMultiRangeFilter()
130+{
131+ auto model = createFilterModel();
132+
133+ createMultiRangeFilter(model, "f1", "Filter1", 1);
134+ createMultiRangeFilter(model, "f2", "Filter2", 2);
135+ createMultiRangeFilter(model, "f3", "Filter3", 3);
136+
137+ // create filter out of 1st row
138+ auto iter = dee_model_get_first_iter(DEE_MODEL(model));
139+ {
140+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
141+ QVERIFY(core_filter != nullptr);
142+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
143+ auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
144+ QVERIFY(multi_filter != nullptr);
145+ auto options = multi_filter->options();
146+ QCOMPARE(options->rowCount(), 1);
147+
148+ auto idx = options->index(0);
149+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
150+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
151+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
152+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
153+
154+ QCOMPARE(id_var.toString(), QString("opt0"));
155+ QCOMPARE(name_var.toString(), QString("Option 0"));
156+ QCOMPARE(icon_var.toString(), QString(""));
157+ QCOMPARE(active_var.toBool(), false);
158+
159+ delete multi_filter;
160+ }
161+
162+ // create filter out of 2nd row
163+ iter = dee_model_next(DEE_MODEL(model), iter);
164+ {
165+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
166+ QVERIFY(core_filter != nullptr);
167+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
168+ auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
169+ QVERIFY(multi_filter != nullptr);
170+ auto options = multi_filter->options();
171+ QCOMPARE(options->rowCount(), 2);
172+
173+ auto idx = options->index(0);
174+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
175+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
176+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
177+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
178+
179+ QCOMPARE(id_var.toString(), QString("opt0"));
180+ QCOMPARE(name_var.toString(), QString("Option 0"));
181+ QCOMPARE(icon_var.toString(), QString(""));
182+ QCOMPARE(active_var.toBool(), false);
183+
184+ AbstractFilterOption* opt1 = options->getRawOption(0);
185+ QCOMPARE(opt1->id(), QString("opt0"));
186+
187+ AbstractFilterOption* opt2 = options->getRawOption(1);
188+ QCOMPARE(opt2->id(), QString("opt1"));
189+
190+ delete multi_filter;
191+ }
192+
193+ // create filter out of 3nd row
194+ iter = dee_model_next(DEE_MODEL(model), iter);
195+ {
196+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
197+ QVERIFY(core_filter != nullptr);
198+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
199+ auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
200+ QVERIFY(multi_filter != nullptr);
201+ auto options = multi_filter->options();
202+ QCOMPARE(options->rowCount(), 3);
203+
204+ AbstractFilterOption* opt0 = options->getRawOption(0);
205+ QCOMPARE(opt0->id(), QString("opt0"));
206+
207+ AbstractFilterOption* opt1 = options->getRawOption(1);
208+ QCOMPARE(opt1->id(), QString("opt1"));
209+
210+ AbstractFilterOption* opt2 = options->getRawOption(2);
211+ QCOMPARE(opt2->id(), QString("opt2"));
212+
213+ // verify combined filter options are bound to correct underlying unity options
214+ auto core_multi_filter = std::dynamic_pointer_cast<unity::dash::MultiRangeFilter>(core_filter);
215+ QCOMPARE(QString::fromStdString(core_multi_filter->options()[0]->id()), QString("opt0"));
216+ QCOMPARE(QString::fromStdString(core_multi_filter->options()[1]->id()), QString("opt1"));
217+ QCOMPARE(QString::fromStdString(core_multi_filter->options()[2]->id()), QString("opt2"));
218+
219+ QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
220+ QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
221+ QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
222+
223+ // test active property changes
224+ QCOMPARE(opt0->active(), false);
225+
226+ opt0->setActive(true); // activate 1st option
227+ QCOMPARE(opt0spy.count(), 1);
228+ QCOMPARE(opt1spy.count(), 0);
229+ QCOMPARE(opt2spy.count(), 0);
230+ QCOMPARE(opt0->active(), true);
231+ QCOMPARE(opt1->active(), false);
232+ QCOMPARE(opt2->active(), false);
233+
234+ opt1->setActive(true);
235+ QCOMPARE(opt0spy.count(), 2);
236+ QCOMPARE(opt1spy.count(), 1);
237+ QCOMPARE(opt2spy.count(), 0);
238+ QCOMPARE(opt0->active(), false); //1st combined option gets deactivated
239+ QCOMPARE(opt1->active(), true);
240+ QCOMPARE(opt2->active(), false);
241+
242+ opt1->setActive(false); // and de-activate it
243+ QCOMPARE(opt0spy.count(), 2);
244+ QCOMPARE(opt1spy.count(), 2);
245+ QCOMPARE(opt2spy.count(), 0);
246+ QCOMPARE(opt0->active(), false);
247+ QCOMPARE(opt1->active(), false);
248+ QCOMPARE(opt2->active(), false);
249+
250+ opt2->setActive(true); // activate another combined option
251+ QCOMPARE(opt0spy.count(), 2);
252+ QCOMPARE(opt1spy.count(), 2);
253+ QCOMPARE(opt2spy.count(), 1);
254+ QCOMPARE(opt0->active(), false);
255+ QCOMPARE(opt1->active(), false);
256+ QCOMPARE(opt2->active(), true);
257+
258+ delete multi_filter;
259+ }
260+}
261+
262+void FiltersBindingsTest::testCheckOptionFilter()
263+{
264+ auto model = createFilterModel();
265+
266+ createCheckOptionFilter(model, "f1", "Filter1", 3);
267+
268+ // create filter out of 1st row
269+ auto iter = dee_model_get_first_iter(DEE_MODEL(model));
270+ {
271+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
272+ QVERIFY(core_filter != nullptr);
273+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
274+ auto check_filter = dynamic_cast<CheckOptionFilter*>(bind_filter);
275+ QVERIFY(check_filter != nullptr);
276+ auto options = check_filter->options();
277+ QCOMPARE(options->rowCount(), 3);
278+
279+ QCOMPARE(check_filter->id(), QString("f1"));
280+ QCOMPARE(check_filter->name(), QString("Filter1"));
281+ QCOMPARE(check_filter->iconHint(), QString(""));
282+ QCOMPARE(check_filter->rendererName(), QString("filter-checkoption"));
283+ QCOMPARE(check_filter->visible(), true);
284+ QCOMPARE(check_filter->collapsed(), false);
285+ QCOMPARE(check_filter->filtering(), false);
286+
287+ auto idx = options->index(0);
288+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
289+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
290+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
291+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
292+
293+ QCOMPARE(id_var.toString(), QString("opt0"));
294+ QCOMPARE(name_var.toString(), QString("Option 0"));
295+ QCOMPARE(icon_var.toString(), QString(""));
296+ QCOMPARE(active_var.toBool(), false);
297+
298+ idx = options->index(1);
299+ id_var = options->data(idx, GenericOptionsModel::RoleId);
300+ name_var = options->data(idx, GenericOptionsModel::RoleName);
301+ icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
302+ active_var = options->data(idx, GenericOptionsModel::RoleActive);
303+
304+ QCOMPARE(id_var.toString(), QString("opt1"));
305+ QCOMPARE(name_var.toString(), QString("Option 1"));
306+ QCOMPARE(icon_var.toString(), QString(""));
307+ QCOMPARE(active_var.toBool(), false);
308+
309+ AbstractFilterOption* opt0 = options->getRawOption(0);
310+ AbstractFilterOption* opt1 = options->getRawOption(1);
311+ AbstractFilterOption* opt2 = options->getRawOption(2);
312+
313+ QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
314+ QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
315+ QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
316+ QSignalSpy dataChangedSpy(options, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
317+
318+ // test active property changes
319+ QCOMPARE(opt0->active(), false);
320+ QCOMPARE(opt1->active(), false);
321+ QCOMPARE(opt2->active(), false);
322+
323+ opt0->setActive(true);
324+ QCOMPARE(opt0spy.count(), 1);
325+ QCOMPARE(opt1spy.count(), 0);
326+ QCOMPARE(opt2spy.count(), 0);
327+ QCOMPARE(opt0->active(), true);
328+ QCOMPARE(opt1->active(), false);
329+ QCOMPARE(opt2->active(), false);
330+
331+ opt1->setActive(true);
332+ QCOMPARE(opt0spy.count(), 2);
333+ QCOMPARE(opt1spy.count(), 1);
334+ QCOMPARE(opt2spy.count(), 0);
335+ QCOMPARE(opt0->active(), false);
336+ QCOMPARE(opt1->active(), true);
337+ QCOMPARE(opt2->active(), false);
338+
339+ QCOMPARE(dataChangedSpy.count(), 3);
340+
341+ delete check_filter;
342+ }
343+}
344+
345+void FiltersBindingsTest::testRadioOptionFilter()
346+{
347+ auto model = createFilterModel();
348+
349+ createRadioOptionFilter(model, "f1", "Filter1", 3);
350+
351+ // create filter out of 1st row
352+ auto iter = dee_model_get_first_iter(DEE_MODEL(model));
353+ {
354+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
355+ QVERIFY(core_filter != nullptr);
356+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
357+ auto radio_filter = dynamic_cast<RadioOptionFilter*>(bind_filter);
358+ QVERIFY(radio_filter != nullptr);
359+ auto options = radio_filter->options();
360+ QCOMPARE(options->rowCount(), 3);
361+
362+ auto idx = options->index(0);
363+ QVariant id_var = options->data(idx, GenericOptionsModel::RoleId);
364+ QVariant name_var = options->data(idx, GenericOptionsModel::RoleName);
365+ QVariant icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
366+ QVariant active_var = options->data(idx, GenericOptionsModel::RoleActive);
367+
368+ QCOMPARE(id_var.toString(), QString("opt0"));
369+ QCOMPARE(name_var.toString(), QString("Option 0"));
370+ QCOMPARE(icon_var.toString(), QString(""));
371+ QCOMPARE(active_var.toBool(), false);
372+
373+ idx = options->index(1);
374+ id_var = options->data(idx, GenericOptionsModel::RoleId);
375+ name_var = options->data(idx, GenericOptionsModel::RoleName);
376+ icon_var = options->data(idx, GenericOptionsModel::RoleIconHint);
377+ active_var = options->data(idx, GenericOptionsModel::RoleActive);
378+
379+ QCOMPARE(id_var.toString(), QString("opt1"));
380+ QCOMPARE(name_var.toString(), QString("Option 1"));
381+ QCOMPARE(icon_var.toString(), QString(""));
382+ QCOMPARE(active_var.toBool(), false);
383+
384+ AbstractFilterOption* opt0 = options->getRawOption(0);
385+ AbstractFilterOption* opt1 = options->getRawOption(1);
386+ AbstractFilterOption* opt2 = options->getRawOption(2);
387+
388+ QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
389+ QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
390+ QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
391+ QSignalSpy dataChangedSpy(options, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
392+
393+ // test active property changes
394+ QCOMPARE(opt0->active(), false);
395+ QCOMPARE(opt1->active(), false);
396+ QCOMPARE(opt2->active(), false);
397+
398+ opt0->setActive(true);
399+ QCOMPARE(opt0spy.count(), 1);
400+ QCOMPARE(opt1spy.count(), 0);
401+ QCOMPARE(opt2spy.count(), 0);
402+ QCOMPARE(opt0->active(), true);
403+ QCOMPARE(opt1->active(), false);
404+ QCOMPARE(opt2->active(), false);
405+
406+ opt1->setActive(true);
407+ QCOMPARE(opt0spy.count(), 2);
408+ QCOMPARE(opt1spy.count(), 1);
409+ QCOMPARE(opt2spy.count(), 0);
410+ QCOMPARE(opt0->active(), false);
411+ QCOMPARE(opt1->active(), true);
412+ QCOMPARE(opt2->active(), false);
413+
414+ QCOMPARE(dataChangedSpy.count(), 3);
415+
416+ delete radio_filter;
417+ }
418+}
419+
420+void FiltersBindingsTest::testRatingsFilter()
421+{
422+ auto model = createFilterModel();
423+
424+ createRatingsFilter(model, "f1", "Filter1");
425+
426+ // create filter out of 1st row
427+ auto iter = dee_model_get_first_iter(DEE_MODEL(model));
428+ {
429+ auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
430+ QVERIFY(core_filter != nullptr);
431+ auto bind_filter = Filter::newFromUnityFilter(core_filter);
432+ auto rating_filter = dynamic_cast<RatingsFilter*>(bind_filter);
433+ QVERIFY(rating_filter != nullptr);
434+ auto options = rating_filter->options();
435+ QCOMPARE(options->rowCount(), 5);
436+
437+ RatingFilterOption* opt[5];
438+ for (int i = 0; i<5; i++) {
439+ opt[i] = dynamic_cast<RatingFilterOption *>(options->getRawOption(i));
440+ }
441+
442+ QSignalSpy opt0spy(opt[0], SIGNAL(activeChanged(bool)));
443+ QSignalSpy opt4spy(opt[4], SIGNAL(activeChanged(bool)));
444+ QSignalSpy dataChangedSpy(options, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&)));
445+
446+ QVERIFY(qAbs(opt[0]->value() - 0.2f) <= 0.0001f);
447+ QVERIFY(qAbs(opt[1]->value() - 0.4f) <= 0.0001f);
448+ QVERIFY(qAbs(opt[2]->value() - 0.6f) <= 0.0001f);
449+ QVERIFY(qAbs(opt[3]->value() - 0.8f) <= 0.0001f);
450+ QVERIFY(qAbs(opt[4]->value() - 1.0f) <= 0.0001f);
451+
452+ QVERIFY(rating_filter->rating() <= 0.0001f); // rating equals zero
453+
454+ // all options initially inactive
455+ for (int i=0; i<5; i++) {
456+ QCOMPARE(opt[i]->active(), false);
457+ }
458+
459+ // verify activation for all options
460+ for (int i=0; i<5; i++) {
461+ opt[i]->setActive(true);
462+ QCOMPARE(opt[i]->active(), true);
463+ QVERIFY(rating_filter->rating() - ((i+1)*0.2f) <= 0.0001f);
464+
465+ // verify that all other options are inactive
466+ for (int j=0; j<5; j++) {
467+ if (i != j) {
468+ QCOMPARE(opt[j]->active(), false);
469+ }
470+ }
471+ }
472+
473+ QCOMPARE(opt0spy.count(), 2);
474+ QCOMPARE(opt4spy.count(), 1);
475+
476+ opt[4]->setActive(false);
477+ QVERIFY(rating_filter->rating() <= 0.0001f); // rating equals zero
478+ QCOMPARE(opt4spy.count(), 2);
479+
480+ QCOMPARE(dataChangedSpy.count(), 10);
481+ }
482+}
483+
484+QTEST_MAIN(FiltersBindingsTest)
tests/plugins/Unity/filtersbindingstest.hnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Pawel Stolowski <pawel.stolowski@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef FILTERSBINDINGSTEST_H
21+#define FILTERSBINDINGSTEST_H
22+
23+#include <QObject>
24+#include <dee.h>
25+
26+class FiltersBindingsTest : public QObject
27+{
28+ Q_OBJECT
29+
30+ private Q_SLOTS:
31+ void initTestCase();
32+ void testMultiRangeFilter();
33+ void testCheckOptionFilter();
34+ void testRadioOptionFilter();
35+ void testRatingsFilter();
36+
37+ private:
38+ DeeModel* createFilterModel();
39+ GVariant* createOptions(int numOfOptions);
40+ void createMultiRangeFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
41+ void createCheckOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
42+ void createRadioOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount);
43+ void createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name);
44+ void createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount);
45+};
46+
47+#endif // FILTERSBINDINGSTEST_H
tests/plugins/Unity/signalslisttest.cppnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// local
18+#include "signalslisttest.h"
19+#include "signalslist.h"
20+
21+// Qt
22+#include <QTest>
23+
24+class TestSource
25+{
26+ public:
27+ TestSource(): m_count(0) {}
28+ void update()
29+ {
30+ countChanged(++m_count);
31+ }
32+
33+ sigc::signal<void, int> countChanged;
34+ int m_count;
35+};
36+
37+void SignalsListTest::testSignalsList()
38+{
39+ TestSource src;
40+ SignalsList signals;
41+ int counter = -1;
42+
43+ signals << src.countChanged.connect([&counter](int val) {
44+ counter = val;
45+ });
46+
47+ src.update();
48+ QCOMPARE(counter, 1);
49+ src.update();
50+ QCOMPARE(counter, 2);
51+
52+ signals.disconnectAll();
53+ src.update();
54+ QCOMPARE(counter, 2);
55+}
56+
57+QTEST_MAIN(SignalsListTest)
tests/plugins/Unity/signalslisttest.hnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef SIGNALSLISTTEST_H
18+#define SIGNALSLISTTEST_H
19+
20+#include <QObject>
21+
22+class SignalsListTest : public QObject
23+{
24+ Q_OBJECT
25+
26+ private Q_SLOTS:
27+ void testSignalsList();
28+};
29+
30+#endif // SIGNALSLISTTEST_H
tests/qmltests/CMakeLists.txt+2
@@ -49,6 +49,8 @@ add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_D
49add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
49add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
50 ${CMAKE_BINARY_DIR}/tests/mocks)
50 ${CMAKE_BINARY_DIR}/tests/mocks)
51add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
51add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
52+add_qml_test(Dash/Apps AppPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
53+add_qml_test(Dash/Video VideoPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
52add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
54add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
53 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
55 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
54add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
56add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
tests/qmltests/Components/tst_FilterGrid.qml−35
@@ -42,15 +42,6 @@ Rectangle {
42 values: [1,2,3,4]
42 values: [1,2,3,4]
43 selectedIndex: 1
43 selectedIndex: 1
44 }
44 }
45− Row {
46− spacing: units.gu(1)
47− Label { anchors.verticalCenter: parent.verticalCenter
48− text: "Expandable" }
49− CheckBox {
50− id: expandableCheckBox
51− checked: true
52− }
53− }
54 Row {
45 Row {
55 spacing: units.gu(1)
46 spacing: units.gu(1)
56 Label { anchors.verticalCenter: parent.verticalCenter
47 Label { anchors.verticalCenter: parent.verticalCenter
@@ -94,7 +85,6 @@ Rectangle {
94 collapsedRowCount:
85 collapsedRowCount:
95 collapsedRowCountSelector.values[collapsedRowCountSelector.selectedIndex]
86 collapsedRowCountSelector.values[collapsedRowCountSelector.selectedIndex]
96 filter: filterCheckBox.checked
87 filter: filterCheckBox.checked
97− expandable: expandableCheckBox.checked
98 minimumHorizontalSpacing: units.gu(1)
88 minimumHorizontalSpacing: units.gu(1)
99 delegateWidth: units.gu(6)
89 delegateWidth: units.gu(6)
100 delegateHeight: units.gu(6)
90 delegateHeight: units.gu(6)
@@ -142,31 +132,6 @@ Rectangle {
142 collapsedRowCountSelector.selectedIndex = 1
132 collapsedRowCountSelector.selectedIndex = 1
143 }
133 }
144
134
145− // Checks that the filter toggle button, the one that says "View All (xy)",
146− // shows up only when it's possible for the grid to be expanded.
147− function test_filterToggleButton() {
148− var filterToggleButton = findChild(filterGrid, "filterToggleButton");
149−
150− for (var i = 0; i < 4; ++i) {
151− collapsedRowCountSelector.selectedIndex = i
152− // row count == index + 1
153− // The total number of rows is 4.
154−
155− expandableCheckBox.checked = false
156− compare(filterToggleButton.visible, false)
157− expandableCheckBox.checked = true
158−
159− if ((i+1) < 4)
160− compare(filterToggleButton.visible, true)
161− else
162− compare(filterToggleButton.visible, false)
163− }
164−
165− // back to initial state
166− collapsedRowCountSelector.selectedIndex = 1
167− expandableCheckBox.checked = true
168− }
169−
170 function countVisibleDelegates() {
135 function countVisibleDelegates() {
171 return __countVisibleDelegates(filterGrid.visibleChildren, 0)
136 return __countVisibleDelegates(filterGrid.visibleChildren, 0)
172 }
137 }
tests/qmltests/Dash/Apps/tst_AppPreview.qmlnew file+152
@@ -0,0 +1,152 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import Ubuntu.Components 0.1
20+import "../../../../Dash/Apps"
21+import Unity.Test 0.1 as UT
22+
23+Item {
24+ id: root
25+ width: units.gu(60)
26+ height: units.gu(80)
27+
28+ property var calls: []
29+
30+ SignalSpy {
31+ id: sendPreviewSpy
32+ target: appPreview
33+ signalName: "sendUserReview"
34+ }
35+
36+ property string commentary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a mi vitae augue rhoncus lobortis ut rutrum metus. Curabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh.";
37+ QtObject { id: screenshots; property var value: ["fake_image1.png", "fake_image2.png", "fake_image3.png"] }
38+ QtObject { id: rating; property int value: 8 }
39+ QtObject { id: rated; property int value: 120 }
40+ QtObject { id: reviews; property int value: 8 }
41+ QtObject { id: progress; property string value: "source" }
42+ QtObject { id: comments; property var value: [
43+ ["Unity User", 4, "08/20/2013", root.commentary],
44+ ["Unity User", 8, "01/15/2013", root.commentary],
45+ ["Unity User", 10, "10/02/2013", root.commentary],
46+ ]
47+ }
48+
49+ QtObject {
50+ id: data
51+ property string title: "Unity App"
52+ property string appIcon: "fake_image.png"
53+ property string description: "This is an Application description"
54+ property var execute: root.fake_call
55+ property var infoMap: {
56+ "more-screenshots": screenshots,
57+ "rating": rating,
58+ "rated": rated,
59+ "reviews": reviews,
60+ "comments": comments
61+ }
62+ property var actions: [
63+ { "id": 123, "displayName": "action1" },
64+ { "id": 456, "displayName": "action2" },
65+ { "id": 789, "displayName": "action3" },
66+ ]
67+ }
68+
69+ function fake_call(id, data){
70+ root.calls[root.calls.length] = id;
71+ }
72+
73+ // The component under test
74+ AppPreview {
75+ id: appPreview
76+ anchors.fill: parent
77+
78+ previewData: data
79+ }
80+
81+ UT.UnityTestCase {
82+ name: "AppPreview"
83+ when: windowShown
84+
85+ function cleanup() {
86+ root.calls = new Array();
87+ sendPreviewSpy.clear();
88+ var reviewField = findChild(appPreview, "reviewField");
89+ reviewField.focus = false;
90+ reviewField.text = "";
91+ }
92+
93+ function test_actions() {
94+ var buttons = findChild(appPreview, "gridButtons");
95+ compare(buttons.count, 3, "Not the proper amount of actions detected.");
96+
97+ for(var i = 0; i < buttons.count; i++) {
98+ buttons.currentIndex = i;
99+ buttons.currentItem.clicked();
100+ }
101+
102+ var actions = data.actions;
103+ for(var i = 0; i < actions.length; i++) {
104+ compare(root.calls[i], actions[i].id, "Id of action not found.");
105+ }
106+ }
107+
108+ function test_rated() {
109+ var rated = findChild(appPreview, "ratedLabel");
110+ compare(rated.text, "(120)", "Rates not equal");
111+ }
112+
113+ function test_reviews() {
114+ var rated = findChild(appPreview, "reviewsLabel");
115+ compare(rated.text, "8 reviews", "Reviews don't match");
116+ }
117+
118+ function test_send_review() {
119+ var appReviews = findChild(appPreview, "appReviews");
120+ appReviews.sendReview("review");
121+ sendPreviewSpy.wait();
122+ }
123+
124+ function test_review_focus() {
125+ var appReviews = findChild(appPreview, "appReviews");
126+ var sendButton = findChild(appReviews, "sendButton");
127+ var reviewField = findChild(appReviews, "reviewField");
128+
129+ compare(reviewField.focus, false, "ReviewField shouldn't have focus");
130+ compare(appReviews.state, "", "State should be empty");
131+
132+ mouseClick(reviewField, reviewField.width/2, reviewField.height/2);
133+ compare(reviewField.focus, true, "Review Field should have focus");
134+ compare(appReviews.state, "editing", "State should be 'editing'");
135+ }
136+
137+ function test_comments() {
138+ var commentsArea = findChild(appPreview, "commentsArea");
139+ compare(commentsArea.count, 3);
140+ for(var i = 0; i < 3; i++) {
141+ var username = commentsArea.itemAt(i).children[0].children[0].text
142+ var rate = commentsArea.itemAt(i).children[0].children[1].children[0].rating
143+ var date = commentsArea.itemAt(i).children[0].children[1].children[1].text
144+ var comment = commentsArea.itemAt(i).children[1].text
145+ compare(username, comments.value[i][0], "Username don't match");
146+ compare(rate, comments.value[i][1], "Rating don't match");
147+ compare(date, comments.value[i][2], "Date don't match");
148+ compare(comment, comments.value[i][3], "Comment don't match");
149+ }
150+ }
151+ }
152+}
tests/qmltests/Dash/Video/tst_VideoPreview.qmlnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import "../../../../Dash/Video"
20+import Unity.Test 0.1 as UT
21+
22+Item {
23+ id: root
24+ width: units.gu(60)
25+ height: units.gu(80)
26+
27+ SignalSpy {
28+ id: previewClickedSpy
29+ target: preview
30+ signalName: "previewImageClicked"
31+ }
32+
33+ // The component under test
34+ VideoPreview {
35+ id: preview
36+ anchors.fill: parent
37+ }
38+
39+ UT.UnityTestCase {
40+ name: "VideoPreview"
41+ when: windowShown
42+
43+ function test_play_button_data() {
44+ return [
45+ {tag: "playable", playable: true},
46+ {tag: "not playable", playable: false}
47+ ]
48+ }
49+
50+ function test_play_button(data) {
51+ var playButton = findChild(preview, "playButton")
52+ preview.playable = data.playable
53+ compare(playButton.visible, data.playable)
54+ }
55+
56+ function test_play_button_click() {
57+ preview.playable = true
58+ var playButton = findChild(preview, "playButton")
59+ mouseClick(playButton, 1, 1)
60+ tryCompare(previewClickedSpy, "count", 1)
61+ }
62+ }
63+}
tests/qmltests/Dash/tst_DashPreview.qml+2−23
@@ -32,7 +32,6 @@ Item {
32 id: preview
32 id: preview
33 anchors.fill: parent
33 anchors.fill: parent
34 title: "Testing rocks, debugging sucks!"
34 title: "Testing rocks, debugging sucks!"
35− forceSquare: true
36
35
37 buttons: Row {
36 buttons: Row {
38 width: parent.width
37 width: parent.width
@@ -55,9 +54,9 @@ Item {
55 }
54 }
56 }
55 }
57
56
58− caption: Label { text: "Caption label" }
57+ header: Label { text: "Caption label" }
59
58
60− description: Column {
59+ body: Column {
61 id: testContent
60 id: testContent
62 objectName: "testContent"
61 objectName: "testContent"
63 width: parent.width
62 width: parent.width
@@ -102,26 +101,6 @@ Item {
102 compare(closeSpy.count, 1, "Close signal not emitted")
101 compare(closeSpy.count, 1, "Close signal not emitted")
103 }
102 }
104
103
105− function test_play_button_data() {
106− return [
107− {tag: "playable", playable: true},
108− {tag: "not playable", playable: false}
109− ]
110− }
111−
112− function test_play_button(data) {
113− var playButton = findChild(preview, "playButton")
114− preview.playable = data.playable
115− compare(playButton.visible, data.playable)
116− }
117−
118− function test_play_button_click() {
119− preview.playable = true
120− var playButton = findChild(preview, "playButton")
121− mouseClick(playButton, 1, 1)
122− tryCompare(previewClickedSpy, "count", 1)
123− }
124−
125 function test_columns_data() {
104 function test_columns_data() {
126 return [
105 return [
127 {tag: "1 columns", width: units.gu(5), height: units.gu(10), columns: 1},
106 {tag: "1 columns", width: units.gu(5), height: units.gu(10), columns: 1},
tests/qmltests/Panel/tst_MenuContent.qml+32−47
@@ -85,29 +85,29 @@ Item {
85
85
86 function activate_content(index)
86 function activate_content(index)
87 {
87 {
88− menuContent.currentMenuIndex = index
88+ menuContent.setCurrentMenuIndex(index)
89 }
89 }
90
90
91 function get_test_menu_objecName(index) {
91 function get_test_menu_objecName(index) {
92 return "menu_page"+(index+1);
92 return "menu_page"+(index+1);
93 }
93 }
94
94
95− property string test_menu_objectName : ""
95+ property string testTabObjectName : ""
96− function current_menu_equals_test_menu() {
96+
97+ function selected_tab_equals_test_tab() {
97− var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
98+ var currentTab = menu_content_test.findChild(menuContent, "tabs").selectedTab
98− if (current_loader == undefined) {
99+ if (currentTab == undefined) {
99− console.log("current_loader 'menus' undefined");
100+ console.log("selected tab undefined");
100 return false;
101 return false;
101 }
102 }
102
103
103− var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
104+ var testTab = menu_content_test.findChild(menuContent, testTabObjectName);
104− if (menu == undefined) {
105+ if (testTab == undefined) {
105− console.log("test_menu " + test_menu_objectName + " undefined");
106+ console.log("test_tab " + testTabObjectName + " undefined");
106 return false;
107 return false;
107 }
108 }
108
109
109− // The parent of the menu will be the loader
110+ return testTab == currentTab;
110− return menu.parent == current_loader;
111 }
111 }
112
112
113 UT.UnityTestCase {
113 UT.UnityTestCase {
@@ -123,81 +123,66 @@ Item {
123
123
124 // Check that the correct menus are displayed for the requested item.
124 // Check that the correct menus are displayed for the requested item.
125 function test_show_menu() {
125 function test_show_menu() {
126− var menu_count = indicatorsModel.count;
126+ var menuCount = indicatorsModel.count;
127− verify(menu_count > 0, "Menu count should be greater than zero");
127+ verify(menuCount > 0, "Menu count should be greater than zero");
128
128
129− var menus = menu_content_test.findChild(menuContent, "menus")
129+ var tabs = menu_content_test.findChild(menuContent, "tabs")
130
130
131 // Loop over twice to test jump between last and first.
131 // Loop over twice to test jump between last and first.
132− for (var i = 0; i < menu_count*2; i++) {
132+ for (var i = 0; i < menuCount*2; i++) {
133
133
134− var menu_index = i%menu_count;
134+ var menuIndex = i%menuCount;
135
135
136− activate_content(menu_index);
136+ activate_content(menuIndex);
137− test_menu_objectName = get_test_menu_objecName(menu_index);
137+ testTabObjectName = indicatorsModel.data(menuIndex, Indicators.IndicatorsModelRole.Identifier);
138− compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
138+ compare(tabs.selectedTabIndex, menuIndex, "Current tab index does not match selected tab index");
139− tryCompareFunction(current_menu_equals_test_menu, true);
139+ tryCompareFunction(selected_tab_equals_test_tab, true);
140 }
140 }
141 }
141 }
142
142
143 // Calling activateContent should call start on all menus
143 // Calling activateContent should call start on all menus
144 function test_activate_content() {
144 function test_activate_content() {
145− var menu_count = indicatorsModel.count;
145+ var menuCount = indicatorsModel.count;
146− verify(menu_count > 0, "Menu count should be greater than zero");
146+ verify(menuCount > 0, "Menu count should be greater than zero");
147
147
148 // Ensure all the menus are stopped first
148 // Ensure all the menus are stopped first
149 menuContent.__contentActive = false;
149 menuContent.__contentActive = false;
150− for (var i = 0; i < menu_count; i++) {
150+ for (var i = 0; i < menuCount; i++) {
151 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
151 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
152 }
152 }
153
153
154 // activate content the content to call stop.
154 // activate content the content to call stop.
155 menuContent.activateContent();
155 menuContent.activateContent();
156− for (var i = 0; i < menu_count; i++) {
156+ for (var i = 0; i < menuCount; i++) {
157 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
157 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
158 }
158 }
159 }
159 }
160
160
161 // Calling activateContent should call stop on all menus.
161 // Calling activateContent should call stop on all menus.
162 function test_release_content() {
162 function test_release_content() {
163− var menu_count = indicatorsModel.count;
163+ var menuCount = indicatorsModel.count;
164− verify(menu_count > 0, "Menu count should be greater than zero");
164+ verify(menuCount > 0, "Menu count should be greater than zero");
165
165
166 // Ensure all the menus are started first
166 // Ensure all the menus are started first
167 menuContent.__contentActive = true;
167 menuContent.__contentActive = true;
168− for (var i = 0; i < menu_count; i++) {
168+ for (var i = 0; i < menuCount; i++) {
169 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
169 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
170 }
170 }
171 // release the content to call stop.
171 // release the content to call stop.
172 menuContent.releaseContent();
172 menuContent.releaseContent();
173− for (var i = 0; i < menu_count; i++) {
173+ for (var i = 0; i < menuCount; i++) {
174 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
174 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
175 }
175 }
176 }
176 }
177
177
178− // Header title should be the same as the item
179− function test_menu_header() {
180− var menu_count = indicatorsModel.count;
181− verify(menu_count > 0, "Menu count should be greater than zero");
182−
183− var header = findChild(menuContent, "header")
184−
185− for (var i = 0; i < menu_count; i++) {
186− activate_content(i);
187−
188− var menu_title = indicatorsModel.get(i).title;
189− compare(header.title, menu_title, "Header doesnt match menu title for menu " + i);
190− }
191− }
192−
193 // Tests QTBUG-30632 - asynchronous loader crashes when changing index quickly.
178 // Tests QTBUG-30632 - asynchronous loader crashes when changing index quickly.
194 function test_multi_activate() {
179 function test_multi_activate() {
195− var menu_count = indicatorsModel.count;
180+ var menuCount = indicatorsModel.count;
196− verify(menu_count > 0, "Menu count should be greater than zero");
181+ verify(menuCount > 0, "Menu count should be greater than zero");
197
182
198 for (var i = 0; i < 100; i++) {
183 for (var i = 0; i < 100; i++) {
199− activate_content(i % menu_count);
184+ activate_content(i % menuCount);
200− compare(menuContent.currentMenuIndex, i%menu_count);
185+ compare(menuContent.currentMenuIndex, i%menuCount);
201 }
186 }
202 wait(100);
187 wait(100);
203 }
188 }
tests/qmltests/tst_Shell.qml+56−18
@@ -21,6 +21,7 @@ import QtQuick 2.0
21import QtTest 1.0
21import QtTest 1.0
22import Ubuntu.Application 0.1
22import Ubuntu.Application 0.1
23import Unity.Test 0.1 as UT
23import Unity.Test 0.1 as UT
24+import Powerd 0.1
24
25
25import "../.."
26import "../.."
26
27
@@ -53,26 +54,30 @@ Item {
53 when: windowShown
54 when: windowShown
54
55
55 function initTestCase() {
56 function initTestCase() {
56− // swipe away the greeter/lockscreen
57+ swipeAwayGreeter();
57− var touchX = shell.width - (shell.edgeSize / 2);
58− var touchY = shell.height / 2;
59− touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY);
60−
61− var dash = findChild(shell, "dash");
62− // wait until the animation has finished
63− tryCompare(dash, "contentScale", 1.0);
64− tryCompare(dash, "opacity", 1.0);
65 }
58 }
66
59
67 function cleanup() {
60 function cleanup() {
61+ // If a test invoked the greeter, make sure we swipe it away again
62+ var greeter = findChild(shell, "greeter");
63+ if (greeter.shown) {
64+ swipeAwayGreeter();
65+ }
66+
68 // kill all (fake) running apps
67 // kill all (fake) running apps
69− ApplicationManager.mainStageApplications.clear();
68+ killApps(ApplicationManager.mainStageApplications);
70− ApplicationManager.sideStageApplications.clear();
69+ killApps(ApplicationManager.sideStageApplications);
71
70
72 var dashHome = findChild(shell, "DashHome");
71 var dashHome = findChild(shell, "DashHome");
73 swipeUntilScopeViewIsReached(dashHome);
72 swipeUntilScopeViewIsReached(dashHome);
74 }
73 }
75
74
75+ function killApps(apps) {
76+ while (apps.count > 0) {
77+ ApplicationManager.stopProcess(apps.get(0));
78+ }
79+ }
80+
76 /*
81 /*
77 Test the effect of a right-edge drag on the dash in 3 situations:
82 Test the effect of a right-edge drag on the dash in 3 situations:
78 1 - when no application has been launched yet
83 1 - when no application has been launched yet
@@ -100,15 +105,48 @@ Item {
100 // Minimize that application once again
105 // Minimize that application once again
101 swipeFromLeftEdge();
106 swipeFromLeftEdge();
102
107
103− // kill it
108+ // Right edge behavior should now be the same as before that app,
104− ApplicationManager.mainStageApplications.clear();
109+ // was launched. Manually cleanup beforehand to get to initial
105−
110+ // state.
111+ cleanup();
106 waitForUIToSettle();
112 waitForUIToSettle();
107−
108− // Right edge behavior should now be the same as before that app was launched
109 checkRightEdgeDragWithNoRunningApps();
113 checkRightEdgeDragWithNoRunningApps();
110 }
114 }
111
115
116+ function test_suspend() {
117+ var greeter = findChild(shell, "greeter");
118+
119+ // Launch an app from the launcher
120+ dragLauncherIntoView();
121+ tapOnAppIconInLauncher();
122+ waitUntilApplicationWindowIsFullyVisible();
123+
124+ var mainApp = ApplicationManager.mainStageFocusedApplication;
125+ tryCompareFunction(function() { return mainApp != null; }, true);
126+
127+ // Now suspend
128+ Powerd.powerStateChange(0);
129+ tryCompare(greeter, "showProgress", 1);
130+ tryCompare(ApplicationManager, "mainStageFocusedApplication", null);
131+
132+ // And wake up
133+ Powerd.powerStateChange(1);
134+ tryCompare(ApplicationManager, "mainStageFocusedApplication", mainApp);
135+ tryCompare(greeter, "showProgress", 1);
136+ }
137+
138+ function swipeAwayGreeter() {
139+ var greeter = findChild(shell, "greeter");
140+ tryCompare(greeter, "showProgress", 1);
141+
142+ var touchX = shell.width - (shell.edgeSize / 2);
143+ var touchY = shell.height / 2;
144+ touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY);
145+
146+ // wait until the animation has finished
147+ tryCompare(greeter, "showProgress", 0);
148+ }
149+
112 /*
150 /*
113 Perform a right-edge drag when the Dash is being show and there are
151 Perform a right-edge drag when the Dash is being show and there are
114 no running/minimized apps to be restored.
152 no running/minimized apps to be restored.
@@ -123,8 +161,8 @@ Item {
123
161
124 var dash = findChild(shell, "dash");
162 var dash = findChild(shell, "dash");
125 // check that dash has normal scale and opacity
163 // check that dash has normal scale and opacity
126− compare(dash.contentScale, 1.0);
164+ tryCompare(dash.contentScale, 1.0);
127− compare(dash.opacity, 1.0);
165+ tryCompare(dash.opacity, 1.0);
128
166
129 touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY,
167 touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY,
130 true /* beginTouch */, false /* endTouch */);
168 true /* beginTouch */, false /* endTouch */);