on xenial help sign in
Merge from trunk
cf44c47Michael Terry
CMakeLists.txt+1
@@ -48,6 +48,7 @@ add_custom_target(cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2
48 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
48 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
49
49
50include(FindPkgConfig)
50include(FindPkgConfig)
51+find_package(Qt5Core)
51find_package(Qt5Qml)
52find_package(Qt5Qml)
52find_package(Qt5Quick)
53find_package(Qt5Quick)
53find_package(Qt5Gui)
54find_package(Qt5Gui)
Components/BasicShell.qml+33−2
@@ -14,6 +14,7 @@
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
16
17+import GSettings 1.0
17import QtQuick 2.0
18import QtQuick 2.0
18import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
19import "../Components"
20import "../Components"
@@ -28,8 +29,38 @@ FocusScope {
28 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
29 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
29
30
30 property real edgeSize: units.gu(2)
31 property real edgeSize: units.gu(2)
31− property url default_background: shell.width >= units.gu(60) ? "../graphics/tablet_background.jpg" : "../graphics/phone_background.jpg"
32+ property url defaultBackground: shell.width >= units.gu(60) ? "../graphics/tablet_background.jpg" : "../graphics/phone_background.jpg"
32− property url background: default_background
33+ property url background
34+
35+ GSettings {
36+ id: backgroundSettings
37+ schema.id: "org.gnome.desktop.background"
38+ }
39+ property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
40+ onGSettingsPictureChanged: {
41+ shell.background = gSettingsPicture
42+ }
43+
44+ // This is a dummy image that is needed to determine if the picture url
45+ // in backgroundSettings points to a valid picture file.
46+ // We can't do this with the real background image because setting a
47+ // new source in onStatusChanged triggers a binding loop detection
48+ // inside Image, which causes it not to render even though a valid source
49+ // would be set. We don't mind about this image staying black and just
50+ // use it for verification to populate the source for the real
51+ // background image.
52+ Image {
53+ source: shell.background
54+ height: 0
55+ width: 0
56+ sourceSize.height: 0
57+ sourceSize.width: 0
58+ onStatusChanged: {
59+ if (status == Image.Error && source != shell.defaultBackground) {
60+ shell.background = defaultBackground
61+ }
62+ }
63+ }
33
64
34 VolumeControl {
65 VolumeControl {
35 id: volumeControl
66 id: volumeControl
Components/CrossFadeImage.qml+3−1
@@ -85,7 +85,7 @@ Item {
85 Connections {
85 Connections {
86 target: __nextImage
86 target: __nextImage
87 onStatusChanged: {
87 onStatusChanged: {
88− if (__nextImage.status == Image.Ready) {
88+ if (__nextImage.status == Image.Ready || __nextImage.status == Image.Error) {
89 swapImages();
89 swapImages();
90 }
90 }
91 }
91 }
@@ -96,6 +96,7 @@ Item {
96 anchors.fill: parent
96 anchors.fill: parent
97 cache: false
97 cache: false
98 asynchronous: true
98 asynchronous: true
99+ fillMode: Image.PreserveAspectCrop
99 z: 1
100 z: 1
100 }
101 }
101
102
@@ -104,6 +105,7 @@ Item {
104 anchors.fill: parent
105 anchors.fill: parent
105 cache: false
106 cache: false
106 asynchronous: true
107 asynchronous: true
108+ fillMode: Image.PreserveAspectCrop
107 z: 0
109 z: 0
108 }
110 }
109
111
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+89
@@ -0,0 +1,89 @@
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+ visible: root.rating >= 0
57+ spacing: units.gu(1)
58+
59+ RatingStars {
60+ id: ratingStars
61+ maximumRating: 10
62+ }
63+
64+ Label {
65+ id: ratedLabel
66+ objectName: "ratedLabel"
67+ fontSize: "medium"
68+ color: "white"
69+ style: Text.Raised
70+ styleColor: "black"
71+ opacity: .6
72+ //TRANSLATORS: Number of persons who rated this app
73+ text: i18n.tr("(%1)").arg(root.rated)
74+ }
75+
76+ Label {
77+ id: reviewsLabel
78+ objectName: "reviewsLabel"
79+ fontSize: "medium"
80+ color: "white"
81+ style: Text.Raised
82+ styleColor: "black"
83+ opacity: .6
84+ //TRANSLATORS: Number of persons who wrote reviews for this app
85+ text: i18n.tr("%1 review", "%1 reviews", root.reviews).arg(root.reviews)
86+ }
87+ }
88+ }
89+}
Dash/Apps/AppPreview.qmlnew file+200
@@ -0,0 +1,200 @@
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"] != null ? previewData.infoMap["more-screenshots"].value : [previewData.image]
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: Math.round(root.previewData.rating * 10)
142+ reviews: root.previewData.numRatings
143+ rated: root.previewData.infoMap["rated"] ? root.previewData.infoMap["rated"].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+ Column {
158+ visible: root.previewData.rating >= 0
159+ anchors { left: parent.left; right: parent.right }
160+ spacing: parent.spacing
161+
162+ ListItem.ThinDivider { }
163+
164+ Item {
165+ anchors { left: parent.left; right: parent.right }
166+ height: rateLabel.height
167+
168+ Label {
169+ id: rateLabel
170+ fontSize: "medium"
171+ color: "white"
172+ style: Text.Raised
173+ styleColor: "black"
174+ opacity: .9
175+ text: i18n.tr("Rate this")
176+
177+ anchors.left: parent.left
178+ anchors.verticalCenter: parent.verticalCenter
179+ }
180+
181+ // FIXME these need to be made interactive and connected to the scope
182+ RatingStars {
183+ anchors.right: parent.right
184+ anchors.verticalCenter: parent.verticalCenter
185+ }
186+ }
187+
188+ ListItem.ThinDivider { }
189+
190+ AppReviews {
191+ objectName: "appReviews"
192+ anchors { left: parent.left; right: parent.right }
193+
194+ model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
195+
196+ onSendReview: root.sendUserReview(review);
197+ }
198+ }
199+ }
200+}
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/gallery-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+17−135
@@ -19,155 +19,37 @@ 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− onPositionedAtBeginning: {
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−
48− Connections {
49− target: panel
50− onSearchClicked: if (isCurrent) {
51− pageHeader.triggerSearch()
52− categoryView.showHeader()
53− }
54− }
55−
56 ListModel {
32 ListModel {
57− id: categoryListModel
33+ 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
34
83− // FIXME this should not be needed, the backend should handle all that itself
35+ ListElement { name: "running-apps" }
84− property var installedModel: null
85−
86− Repeater {
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 }
36 }
93
37
94− property var categoryModels: {
38+ SortFilterProxyModel {
95− "FrequentlyUsedAppsModel": frequentlyUsedAppsModel,
39+ id: runningApplicationsModel
96− "InstalledApplicationsModel": installedModel,
97− "AppsAvailableForDownloadModel": appsAvailableForDownloadModel,
98− }
99−
100− ScopeListView {
101− id: categoryView
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
40
117− delegate: Base {
41+ property var firstModel: mainStageApplicationsModel
118− id: container
42+ property var secondModel: sideStageApplicationModel
119− highlightWhenPressed: false
43+ property bool canEnableTerminationMode: scopeView.isCurrent
120
44
121− Loader {
45+ model: dummyVisibilityModifier
122− anchors {
46+ 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
47+ filterRegExp: invertMatch ? ((mainStageApplicationsModel.count === 0 &&
131− item.secondModel = sideStageApplicationModel
48+ sideStageApplicationModel.count === 0) ? RegExp("running-apps") : RegExp("")) : RegExp("disabled")
132− item.canEnableTerminationMode =
49+ 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− }
50+ }
159
51
160− sectionProperty: "category"
52+ onScopeChanged: {
161− sectionDelegate: Header {
53+ scopeView.scope.categories.overrideResults("recent", runningApplicationsModel);
162− width: categoryView.width
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 }
54 }
173}
55}
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+27−5
@@ -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,29 +70,37 @@ 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 {
77+ anchors { left: parent.left; right: parent.right }
63 visible: text != ""
78 visible: text != ""
64 fontSize: "medium"
79 fontSize: "medium"
65 opacity: 0.6
80 opacity: 0.6
66 color: "white"
81 color: "white"
67− text: previewData.subtitle
82+ text: previewData.subtitle.replace(/[\r\n]+/g, "<br />")
68 style: Text.Raised
83 style: Text.Raised
69 styleColor: "black"
84 styleColor: "black"
70 wrapMode: Text.WordWrap
85 wrapMode: Text.WordWrap
86+ textFormat: Text.RichText
87+ // FIXME: workaround for https://bugreports.qt-project.org/browse/QTBUG-33020
88+ onWidthChanged: { wrapMode = Text.NoWrap; wrapMode = Text.WordWrap }
71 }
89 }
72
90
73 Label {
91 Label {
92+ anchors { left: parent.left; right: parent.right }
74 visible: text != ""
93 visible: text != ""
75 fontSize: "small"
94 fontSize: "small"
76 opacity: 0.6
95 opacity: 0.6
77 color: "white"
96 color: "white"
78− text: previewData.description
97+ text: previewData.description.replace(/[\r\n]+/g, "<br />")
79 style: Text.Raised
98 style: Text.Raised
80 styleColor: "black"
99 styleColor: "black"
81 wrapMode: Text.WordWrap
100 wrapMode: Text.WordWrap
101+ textFormat: Text.RichText
102+ // FIXME: workaround for https://bugreports.qt-project.org/browse/QTBUG-33020
103+ onWidthChanged: { wrapMode = Text.NoWrap; wrapMode = Text.WordWrap }
82 }
104 }
83 }
105 }
84}
106}
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+10−2
@@ -28,8 +28,16 @@ FocusScope {
28 signal movementStarted
28 signal movementStarted
29 signal positionedAtBeginning
29 signal positionedAtBeginning
30
30
31− // FIXME delay the search so that daemons have time to settle
31+ // FIXME delay the search so that daemons have time to settle, note that
32+ // removing this will break ScopeView::test_changeScope
32− onScopeChanged: timer.restart()
33+ onScopeChanged: {
34+ timer.restart();
35+ scope.activateApplication.connect(activateApp);
36+ }
37+
38+ function activateApp(desktopFilePath) {
39+ shell.activateApplication(desktopFilePath);
40+ }
33
41
34 Timer {
42 Timer {
35 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.

Greeter/GreeterContent.qml−1
@@ -37,7 +37,6 @@ MouseArea {
37
37
38 source: shell.background
38 source: shell.background
39 anchors.fill: parent
39 anchors.fill: parent
40− crossFade: false
41 fadeInFirst: false
40 fadeInFirst: false
42 }
41 }
43
42
Greeter/Lockscreen.qml+1
@@ -56,6 +56,7 @@ Showable {
56 Image {
56 Image {
57 anchors.fill: parent
57 anchors.fill: parent
58 source: root.required ? root.background : ""
58 source: root.required ? root.background : ""
59+ fillMode: Image.PreserveAspectCrop
59 }
60 }
60
61
61 MouseArea {
62 MouseArea {
GreeterShell.qml+1−4
@@ -73,6 +73,7 @@ BasicShell {
73
73
74 Greeter {
74 Greeter {
75 id: greeter
75 id: greeter
76+ objectName: "greeter"
76
77
77 available: true
78 available: true
78 hides: [launcher, panel.indicators]
79 hides: [launcher, panel.indicators]
@@ -104,10 +105,6 @@ BasicShell {
104 }
105 }
105
106
106 onUnlocked: login()
107 onUnlocked: login()
107− onSelected: {
108− var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
109− shell.background = bgPath ? bgPath : default_background
110− }
111
108
112 onLeftTeaserPressedChanged: {
109 onLeftTeaserPressedChanged: {
113 if (leftTeaserPressed) {
110 if (leftTeaserPressed) {
Launcher/FoldingLauncherDelegate.qmlnew file+133
@@ -0,0 +1,133 @@
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+
20+LauncherDelegate {
21+ id: root
22+
23+ // The angle used for rotating
24+ angle: {
25+ // First/last items are special
26+ if (index == 0 || index == priv.listView.count-1) {
27+ if (priv.distanceFromEdge < 0) {
28+ // proportion equation: distanceFromTopEdge : angle = totalUnfoldedHeight/2 : maxAngle
29+ return Math.max(-maxAngle, priv.distanceFromEdge * maxAngle / (priv.listView.foldingAreaHeight)) * priv.orientationFlag
30+ }
31+ return 0; // Don't fold first/last item as long as inside the view
32+ }
33+
34+ // Are we in the already completely outside the flickable? Fold for the last 5 degrees
35+ if (priv.distanceFromEdge < 0) {
36+ // proportion equation: -distanceFromTopEdge : angle = totalUnfoldedHeight : 5
37+ return Math.max(-maxAngle, (priv.distanceFromEdge * 5 / priv.listView.foldingAreaHeight) - (maxAngle-5)) * priv.orientationFlag
38+ }
39+
40+ // We are overlapping with the folding area, fold the icon to maxAngle - 5 degrees
41+ if (priv.overlapWithFoldingArea > 0) {
42+ // proportion equation: overlap: totalHeight = angle : (maxAngle - 5)
43+ return -priv.overlapWithFoldingArea * (maxAngle -5) / priv.listView.foldingAreaHeight * priv.orientationFlag;
44+ }
45+ return 0;
46+ }
47+
48+ // This is the offset that keeps the items inside the panel
49+ offset: {
50+ // First/last items are special
51+ if (index == 0 || index == priv.listView.count-1) {
52+ // Just keep them bound to the edges in case they're outside of the visible area
53+ if (priv.distanceFromEdge < 0) {
54+ return (-priv.distanceFromEdge - (height - effectiveHeight)) * priv.orientationFlag;
55+ }
56+ return 0;
57+ }
58+
59+ // Are we already completely outside the flickable? Stop the icon here.
60+ if (priv.distanceFromEdge < -priv.totalUnfoldedHeight) {
61+ return (-priv.distanceFromEdge - (root.height - effectiveHeight)) * priv.orientationFlag;
62+ }
63+
64+ // We're touching the edge, move slower than the actual flicking speed.
65+ if (priv.distanceFromEdge < 0) {
66+ return (Math.abs(priv.distanceFromEdge) * priv.totalEffectiveHeight / priv.totalUnfoldedHeight) * priv.orientationFlag
67+ }
68+ return 0;
69+ }
70+
71+ itemOpacity: {
72+ // First/last items are special
73+ if (index == 0 || index == priv.listView.count-1) {
74+ if (priv.distanceFromEdge < 0) {
75+ // Fade from 1 to 0 in the distance of 3 * foldingAreaHeight (which is when the next item reaches the edge)
76+ return 1.0 - (-priv.distanceFromEdge / (priv.listView.foldingAreaHeight * 3))
77+ }
78+ return 1; // Don't make first/last item transparent as long as inside the view
79+ }
80+
81+ // Are we already completely outside the flickable? Fade from 0.75 to 0 in 2 items height
82+ if (priv.distanceFromEdge < 0) {
83+ // proportion equation: -distanceFromEdge : 1-opacity = totalUnfoldedHeight : 0.75
84+ return 0.75 - (-priv.distanceFromEdge * 0.75 / (priv.totalUnfoldedHeight*2))
85+ }
86+
87+ // We are overlapping with the folding area, fade out to 0.75
88+ if (priv.overlapWithFoldingArea > 0) {
89+ // proportion equation: overlap : totalHeight = 1-opacity : 0.25
90+ return 1 - (priv.overlapWithFoldingArea * 0.25 / priv.listView.foldingAreaHeight)
91+ }
92+ return 1;
93+ }
94+
95+ brightness: {
96+ // First/last items are special
97+ if (index == 0 || index == priv.listView.count-1) {
98+ if (priv.distanceFromEdge < 0) {
99+ return -(-priv.distanceFromEdge / (priv.listView.foldingAreaHeight * 3))
100+ }
101+ return 0;
102+ }
103+ // Are we already completely outside the flickable? Fade from 0.7 to 0 in 2 items height
104+ if (priv.distanceFromEdge < 0) {
105+ return -0.3 - (-priv.distanceFromEdge * 0.1 / (priv.totalUnfoldedHeight*2))
106+ }
107+
108+ // We are overlapping with the folding area, fade out to 0.7
109+ if (priv.overlapWithFoldingArea > 0) {
110+ return - (priv.overlapWithFoldingArea * 0.3 / priv.listView.foldingAreaHeight)
111+ }
112+ return 0;
113+ }
114+
115+ QtObject {
116+ id: priv
117+
118+ property ListView listView: root.ListView.view
119+ property real totalUnfoldedHeight: listView.itemHeight + listView.spacing
120+ property real totalEffectiveHeight: effectiveHeight + listView.spacing
121+ property real effectiveContentY: listView.contentY - listView.originY
122+ property real effectiveY: y - listView.originY
123+ property real bottomDraggingDistanceOffset: listView.draggedIndex > index ? totalUnfoldedHeight : 0
124+ property real distanceFromTopEdge: -(effectiveContentY + listView.topMargin - index*totalUnfoldedHeight)
125+ property real distanceFromBottomEdge: listView.height - listView.bottomMargin - (effectiveY+height) + effectiveContentY + bottomDraggingDistanceOffset
126+
127+ property real distanceFromEdge: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? distanceFromBottomEdge : distanceFromTopEdge
128+ property real orientationFlag: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? -1 : 1
129+
130+ property real overlapWithFoldingArea: listView.foldingAreaHeight - distanceFromEdge
131+ }
132+
133+}
Launcher/Launcher.qml+4−4
@@ -73,7 +73,7 @@ Item {
73 id: dismissTimer
73 id: dismissTimer
74 interval: 5000
74 interval: 5000
75 onTriggered: {
75 onTriggered: {
76− if (!panel.moving) {
76+ if (!panel.preventHiding) {
77 root.state = ""
77 root.state = ""
78 } else {
78 } else {
79 dismissTimer.restart()
79 dismissTimer.restart()
@@ -135,9 +135,9 @@ Item {
135 id: backgroundShade
135 id: backgroundShade
136 anchors.fill: parent
136 anchors.fill: parent
137 color: "black"
137 color: "black"
138− opacity: root.state == "visible" ? 0.4 : 0
138+ opacity: root.state == "visible" ? 0.6 : 0
139
139
140− Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuad} }
140+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.BriskDuration } }
141 }
141 }
142
142
143 LauncherPanel {
143 LauncherPanel {
@@ -162,7 +162,7 @@ Item {
162 root.dashItemSelected(index)
162 root.dashItemSelected(index)
163 }
163 }
164
164
165− onMovingChanged: {
165+ onPreventHidingChanged: {
166 if (dismissTimer.running) {
166 if (dismissTimer.running) {
167 dismissTimer.restart();
167 dismissTimer.restart();
168 }
168 }
Launcher/LauncherDelegate.qml+89−175
@@ -21,29 +21,33 @@ Item {
21 id: root
21 id: root
22
22
23 property string iconName
23 property string iconName
24−
24+ property int count: -1
25− property real angle: 0
25+ property int progress: -1
26 property bool highlighted: false
26 property bool highlighted: false
27− property real offset: 0
28− property alias brightness: transformEffect.brightness
29− property real itemOpacity: 1
30−
31 property real maxAngle: 0
27 property real maxAngle: 0
32 property bool inverted: false
28 property bool inverted: false
33
29
34− readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * height
30+ readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
35− readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * height
31+ readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
36
32
37− property bool dragging:false
33+ property int itemWidth
34+ property int itemHeight
35+ // The angle used for rotating
36+ property real angle: 0
37+ // This is the offset that keeps the items inside the panel
38+ property real offset: 0
39+ property real itemOpacity: 1
40+ property real brightness: 0
38
41
39− signal clicked()
42+ onIconNameChanged: shaderEffectSource.scheduleUpdate();
40− signal longtap()
43+ onCountChanged: shaderEffectSource.scheduleUpdate();
41− signal released()
44+ onProgressChanged: shaderEffectSource.scheduleUpdate();
45+ onHighlightedChanged: shaderEffectSource.scheduleUpdate();
42
46
43 Item {
47 Item {
44 id: iconItem
48 id: iconItem
45− width: parent.width
49+ width: parent.itemWidth
46− height: parent.height
50+ height: parent.itemHeight
47 anchors.centerIn: parent
51 anchors.centerIn: parent
48
52
49 UbuntuShape {
53 UbuntuShape {
@@ -58,31 +62,79 @@ Item {
58 sourceSize.height: iconShape.height
62 sourceSize.height: iconShape.height
59 source: "../graphics/applicationIcons/" + root.iconName + ".png"
63 source: "../graphics/applicationIcons/" + root.iconName + ".png"
60 }
64 }
61−
62− MouseArea {
63− id: mouseArea
64− anchors.fill: parent
65− onClicked: root.clicked()
66− onCanceled: root.released()
67− preventStealing: false
68−
69− onPressAndHold: {
70− root.state = "moving"
71− }
72− onReleased: {
73− root.state = "docked"
74− }
75− }
76 }
65 }
66+
77 BorderImage {
67 BorderImage {
78 id: overlayHighlight
68 id: overlayHighlight
79 anchors.centerIn: iconItem
69 anchors.centerIn: iconItem
80 rotation: inverted ? 180 : 0
70 rotation: inverted ? 180 : 0
81− source: isSelected ? "graphics/selected.sci" : "graphics/non-selected.sci"
71+ source: root.highlighted ? "graphics/selected.sci" : "graphics/non-selected.sci"
82− width: root.width + units.gu(0.5)
72+ width: root.itemWidth + units.gu(0.5)
73+ height: root.itemHeight + units.gu(0.5)
74+ }
75+
76+ BorderImage {
77+ objectName: "countEmblem"
78+ anchors {
79+ right: parent.right
80+ top: parent.top
81+ margins: -units.dp(1)
82+ }
83+ width: Math.min(units.gu(7.5), Math.max(units.gu(3), countLabel.implicitWidth + units.gu(2.5)))
83− height: width
84+ height: units.gu(3)
84− property bool isSelected: root.highlighted || mouseArea.pressed
85+ source: "graphics/notification.sci"
85− onIsSelectedChanged: shaderEffectSource.scheduleUpdate();
86+ visible: root.count > 0
87+
88+ Label {
89+ id: countLabel
90+ text: root.count
91+ anchors.centerIn: parent
92+ width: units.gu(6)
93+ horizontalAlignment: Text.AlignHCenter
94+ elide: Text.ElideRight
95+ color: "white"
96+ fontSize: "small"
97+ font.bold: true
98+ }
99+ }
100+
101+ BorderImage {
102+ id: progressOverlay
103+ objectName: "progressOverlay"
104+ anchors {
105+ left: iconItem.left
106+ right: iconItem.right
107+ bottom: iconItem.bottom
108+ leftMargin: units.gu(0.5)
109+ rightMargin: units.gu(0.5)
110+ bottomMargin: units.gu(0.5)
111+ }
112+ height: units.gu(1.5)
113+ visible: root.progress > -1
114+ source: "graphics/progressbar-trough.sci"
115+
116+ // For fill calculation we need to remove the 2 units of border defined in .sci file
117+ property int adjustedWidth: width - units.gu(2)
118+
119+ Item {
120+ anchors {
121+ left: parent.left
122+ top: parent.top
123+ bottom: parent.bottom
124+ }
125+ width: Math.min(100, root.progress) / 100 * parent.adjustedWidth + units.gu(1)
126+ clip: true
127+
128+ BorderImage {
129+ anchors {
130+ left: parent.left
131+ top: parent.top
132+ bottom: parent.bottom
133+ }
134+ width: progressOverlay.width
135+ source: "graphics/progressbar-fill.sci"
136+ }
137+ }
86 }
138 }
87 }
139 }
88
140
@@ -90,14 +142,13 @@ Item {
90 id: transformEffect
142 id: transformEffect
91 anchors.centerIn: parent
143 anchors.centerIn: parent
92 anchors.verticalCenterOffset: root.offset
144 anchors.verticalCenterOffset: root.offset
93− width: parent.width
145+ width: parent.itemWidth
94− height: parent.height
146+ height: parent.itemHeight
95 property real itemOpacity: root.itemOpacity
147 property real itemOpacity: root.itemOpacity
96− property real brightness: 0
148+ property real brightness: Math.max(-1, root.brightness)
97 property real angle: root.angle
149 property real angle: root.angle
98 rotation: root.inverted ? 180 : 0
150 rotation: root.inverted ? 180 : 0
99
151
100−
101 property variant source: ShaderEffectSource {
152 property variant source: ShaderEffectSource {
102 id: shaderEffectSource
153 id: shaderEffectSource
103 sourceItem: iconItem
154 sourceItem: iconItem
@@ -149,141 +200,4 @@ Item {
149 gl_FragColor = sourceColor;
200 gl_FragColor = sourceColor;
150 }"
201 }"
151 }
202 }
152−
153− QtObject {
154− id: priv
155−
156− property ListView listView: root.ListView.view
157− property real totalUnfoldedHeight: listView.itemSize + listView.spacing
158− property real totalEffectiveHeight: effectiveHeight + listView.spacing
159− property real effectiveContentY: listView.contentY - listView.originY
160− property real effectiveY: y - listView.originY
161− property real distanceFromTopEdge: -(effectiveContentY + listView.topMargin - index*totalUnfoldedHeight)
162− property real distanceFromBottomEdge: listView.height - listView.bottomMargin - (effectiveY+height) + effectiveContentY
163−
164− property real distanceFromEdge: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? distanceFromBottomEdge : distanceFromTopEdge
165− property real orientationFlag: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? -1 : 1
166−
167− property real overlapWithFoldingArea: listView.foldingAreaHeight - distanceFromEdge
168− }
169−
170− states: [
171− State {
172− name: "docked"
173− PropertyChanges {
174− target: root
175−
176− // This is the offset that keeps the items inside the panel
177− offset: {
178− // First/last items are special
179− if (index == 0 || index == priv.listView.count-1) {
180− // Just keep them bound to the edges in case they're outside of the visible area
181− if (priv.distanceFromEdge < 0) {
182− return (-priv.distanceFromEdge - (height - effectiveHeight)) * priv.orientationFlag;
183− }
184− return 0;
185− }
186−
187− // Are we already completely outside the flickable? Stop the icon here.
188− if (priv.distanceFromEdge < -priv.totalUnfoldedHeight) {
189− return (-priv.distanceFromEdge - (root.height - effectiveHeight)) * priv.orientationFlag;
190− }
191−
192− // We're touching the edge, move slower than the actual flicking speed.
193− if (priv.distanceFromEdge < 0) {
194− return (Math.abs(priv.distanceFromEdge) * priv.totalEffectiveHeight / priv.totalUnfoldedHeight) * priv.orientationFlag
195− }
196− return 0;
197− }
198−
199− // The angle used for rotating
200− angle: {
201− // First/last items are special
202− if (index == 0 || index == priv.listView.count-1) {
203− if (priv.distanceFromEdge < 0) {
204− // proportion equation: distanceFromTopEdge : angle = totalUnfoldedHeight/2 : maxAngle
205− return Math.max(-maxAngle, priv.distanceFromEdge * maxAngle / (priv.listView.foldingAreaHeight)) * priv.orientationFlag
206− }
207− return 0; // Don't fold first/last item as long as inside the view
208− }
209−
210− // Are we in the already completely outside the flickable? Fold for the last 5 degrees
211− if (priv.distanceFromEdge < 0) {
212− // proportion equation: -distanceFromTopEdge : angle = totalUnfoldedHeight : 5
213− return Math.max(-maxAngle, (priv.distanceFromEdge * 5 / priv.listView.foldingAreaHeight) - (maxAngle-5)) * priv.orientationFlag
214− }
215−
216− // We are overlapping with the folding area, fold the icon to maxAngle - 5 degrees
217− if (priv.overlapWithFoldingArea > 0) {
218− // proportion equation: overlap: totalHeight = angle : (maxAngle - 5)
219− return -priv.overlapWithFoldingArea * (maxAngle -5) / priv.listView.foldingAreaHeight * priv.orientationFlag;
220− }
221− return 0;
222− }
223−
224− itemOpacity: {
225− // First/last items are special
226− if (index == 0 || index == priv.listView.count-1) {
227− if (priv.distanceFromEdge < 0) {
228− // Fade from 1 to 0 in the distance of 3 * foldingAreaHeight (which is when the next item reaches the edge)
229− return 1.0 - (-priv.distanceFromEdge / (priv.listView.foldingAreaHeight * 3))
230− }
231− return 1; // Don't make first/last item transparent as long as inside the view
232− }
233−
234− // Are we already completely outside the flickable? Fade from 0.75 to 0 in 2 items height
235− if (priv.distanceFromEdge < 0) {
236− // proportion equation: -distanceFromEdge : 1-opacity = totalUnfoldedHeight : 0.75
237− return 0.75 - (-priv.distanceFromEdge * 0.75 / (priv.totalUnfoldedHeight*2))
238− }
239−
240− // We are overlapping with the folding area, fade out to 0.75
241− if (priv.overlapWithFoldingArea > 0) {
242− // proportion equation: overlap : totalHeight = 1-opacity : 0.25
243− return 1 - (priv.overlapWithFoldingArea * 0.25 / priv.listView.foldingAreaHeight)
244− }
245− return 1;
246− }
247−
248− brightness: {
249− // First/last items are special
250− if (index == 0 || index == priv.listView.count-1) {
251− if (priv.distanceFromEdge < 0) {
252− return -(-priv.distanceFromEdge / (priv.listView.foldingAreaHeight * 3))
253− }
254− return 0;
255− }
256− // Are we already completely outside the flickable? Fade from 0.7 to 0 in 2 items height
257− if (priv.distanceFromEdge < 0) {
258− return -0.3 - (-priv.distanceFromEdge * 0.1 / (priv.totalUnfoldedHeight*2))
259− }
260−
261− // We are overlapping with the folding area, fade out to 0.7
262− if (priv.overlapWithFoldingArea > 0) {
263− return - (priv.overlapWithFoldingArea * 0.3 / priv.listView.foldingAreaHeight)
264− }
265− return 0;
266− }
267− }
268− },
269−
270− State {
271− name: "moving"
272− PropertyChanges {
273− target: launcherDelegate;
274− offset: 0
275− angle: 0
276− }
277− PropertyChanges {
278− target: root
279− highlighted: true
280− dragging: true
281− }
282− PropertyChanges {
283− target: mouseArea
284− preventStealing: true
285− drag.target: root
286− }
287− }
288− ]
289}
203}
Launcher/LauncherPanel.qml+389−91
@@ -16,8 +16,10 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItems
19import Unity 0.1
20import Unity 0.1
20import Unity.Launcher 0.1
21import Unity.Launcher 0.1
22+import Ubuntu.Components.Popups 0.1
21import "../Components/ListItems"
23import "../Components/ListItems"
22
24
23Item {
25Item {
@@ -29,53 +31,33 @@ Item {
29 property bool inverted: true
31 property bool inverted: true
30 property bool dragging: false
32 property bool dragging: false
31 property bool moving: launcherListView.moving || launcherListView.flicking
33 property bool moving: launcherListView.moving || launcherListView.flicking
32− property int dragPosition: 0
34+ property bool preventHiding: moving || dndArea.draggedIndex >= 0 || dndArea.quickListPopover !== null || dndArea.pressed
33 property int highlightIndex: -1
35 property int highlightIndex: -1
34
36
35 signal applicationSelected(string desktopFile)
37 signal applicationSelected(string desktopFile)
36 signal dashItemSelected(int index)
38 signal dashItemSelected(int index)
37
39
38− onDragPositionChanged: {
39− var effectiveDragPosition = root.inverted ? launcherListView.height - dragPosition : dragPosition - mainColumn.anchors.margins
40−
41− var hiddenContentHeight = launcherListView.contentHeight - launcherListView.height
42− // Shortening scrollable height because the first/last item needs to be fully expanded before reaching the top/bottom
43− var scrollableHeight = launcherListView.height - (launcherListView.itemSize + launcherColumn.spacing) *2
44− // As we shortened the scrollableHeight, lets move everything down by the itemSize
45− var shortenedEffectiveDragPosition = effectiveDragPosition - launcherListView.itemSize - launcherColumn.spacing
46− var newContentY = shortenedEffectiveDragPosition * hiddenContentHeight / scrollableHeight
47−
48− // limit top/bottom to prevent overshooting
49− launcherListView.contentY = Math.min(hiddenContentHeight, Math.max(0, newContentY));
50−
51− // Now calculate the current index:
52− // > the current mouse position + the hidden/scolled content on top is the mouse position in the averall view
53− // > adjust that removing all the margins
54− // > divide by itemSize to get index
55− highlightIndex = (effectiveDragPosition + launcherListView.contentY - mainColumn.anchors.margins*3 - launcherColumn.spacing/2) / (launcherListView.itemSize + launcherColumn.spacing)
56− }
57−
58 BorderImage {
40 BorderImage {
59 id: background
41 id: background
60 source: "graphics/launcher_bg.sci"
42 source: "graphics/launcher_bg.sci"
61 anchors.fill: parent
43 anchors.fill: parent
44+ anchors.rightMargin: root.inverted ? 0 : -units.gu(1)
45+ anchors.leftMargin: root.inverted ? -units.gu(1) : 0
46+ rotation: root.rotation
62 }
47 }
63
48
64 Column {
49 Column {
65 id: mainColumn
50 id: mainColumn
66 anchors {
51 anchors {
67 fill: parent
52 fill: parent
68− topMargin: units.gu(0.5)
69− bottomMargin: units.gu(1)
70 leftMargin: units.gu(0.5)
53 leftMargin: units.gu(0.5)
71 rightMargin: units.gu(0.5)
54 rightMargin: units.gu(0.5)
72 }
55 }
73− spacing: units.gu(0.5)
74
56
75 MouseArea {
57 MouseArea {
76 id: dashItem
58 id: dashItem
77 width: parent.width
59 width: parent.width
78− height: units.gu(6.5)
60+ height: units.gu(7)
79 onClicked: root.dashItemSelected(0)
61 onClicked: root.dashItemSelected(0)
80 z: 1
62 z: 1
81 Image {
63 Image {
@@ -100,87 +82,403 @@ Item {
100 anchors.left: parent.left
82 anchors.left: parent.left
101 anchors.right: parent.right
83 anchors.right: parent.right
102 height: parent.height - dashItem.height - parent.spacing*2
84 height: parent.height - dashItem.height - parent.spacing*2
103− ListView {
85+
104− id: launcherListView
86+ Item {
105− objectName: "launcherListView"
106 anchors.fill: parent
87 anchors.fill: parent
88+ clip: true
89+
90+ ListView {
91+ id: launcherListView
92+ objectName: "launcherListView"
107− anchors.topMargin: -itemSize
93+ anchors {
94+ fill: parent
95+ topMargin: -extensionSize + units.gu(0.5)
108− anchors.bottomMargin: -itemSize
96+ bottomMargin: -extensionSize + units.gu(1)
97+ }
109− topMargin: itemSize
98+ topMargin: extensionSize
110− bottomMargin: itemSize
99+ bottomMargin: extensionSize
111− height: parent.height - dashItem.height - parent.spacing*2
100+ height: parent.height - dashItem.height - parent.spacing*2
112− model: root.model
101+ model: root.model
113− cacheBuffer: itemSize * 3
102+ cacheBuffer: itemHeight * 3
114− snapMode: ListView.SnapToItem
103+ snapMode: interactive ? ListView.SnapToItem : ListView.NoSnap
115− highlightRangeMode: ListView.ApplyRange
104+ highlightRangeMode: ListView.ApplyRange
116− preferredHighlightBegin: (height - itemSize) / 2
105+ preferredHighlightBegin: (height - itemHeight) / 2
117− preferredHighlightEnd: (height + itemSize) / 2
106+ preferredHighlightEnd: (height + itemHeight) / 2
118−
107+ spacing: units.gu(0.5)
108+
109+ // The size of the area the ListView is extended to make sure items are not
110+ // destroyed when dragging them outside the list. This needs to be at least
111+ // itemHeight to prevent folded items from disappearing and DragArea limits
112+ // need to be smaller than this size to avoid breakage.
113+ property int extensionSize: itemHeight * 3
114+
119− // The height of the area where icons start getting folded
115+ // The height of the area where icons start getting folded
120− property int foldingAreaHeight: itemSize * 0.75
116+ property int foldingAreaHeight: itemHeight * 0.75
121− property int itemSize: width
117+ property int itemWidth: width
118+ property int itemHeight: width * 7.5 / 8
122− property int clickFlickSpeed: units.gu(60)
119+ property int clickFlickSpeed: units.gu(60)
123−
120+ property int draggedIndex: dndArea.draggedIndex
124− delegate: LauncherDelegate {
121+ property real realContentY: contentY - originY + topMargin
122+ property int realItemHeight: itemHeight + spacing
123+
124+ displaced: Transition {
125+ NumberAnimation { properties: "x,y"; duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing }
126+ }
127+
128+ delegate: FoldingLauncherDelegate {
125− id: launcherDelegate
129+ id: launcherDelegate
126− objectName: "launcherDelegate" + index
130+ objectName: "launcherDelegate" + index
127− width: launcherListView.itemSize
131+ itemHeight: launcherListView.itemHeight
128− height: launcherListView.itemSize
132+ itemWidth: launcherListView.itemWidth
133+ width: itemWidth
134+ height: itemHeight
129− iconName: model.icon
135+ iconName: model.icon
136+ count: model.count
137+ progress: model.progress
130− inverted: root.inverted
138+ inverted: root.inverted
131− highlighted: root.dragging && index === root.highlightIndex
139+ highlighted: dragging && index === root.highlightIndex
132− z: -Math.abs(offset)
140+ z: -Math.abs(offset)
133− state: "docked"
134− maxAngle: 60
141+ maxAngle: 60
135−
142+ property bool dragging: false
143+
144+ ThinDivider {
145+ id: dropIndicator
146+ objectName: "dropIndicator"
147+ anchors.centerIn: parent
148+ width: parent.width + mainColumn.anchors.leftMargin + mainColumn.anchors.rightMargin
149+ opacity: 0
150+ }
151+
152+ states: [
153+ State {
154+ name: "selected"
155+ when: dndArea.selectedItem === launcherDelegate && fakeDragItem.visible && !dragging
156+ PropertyChanges {
157+ target: launcherDelegate
158+ itemOpacity: 0
159+ }
160+ },
161+ State {
162+ name: "dragging"
163+ when: dragging
164+ PropertyChanges {
165+ target: launcherDelegate
166+ height: units.gu(1)
167+ itemOpacity: 0
168+ }
169+ PropertyChanges {
170+ target: dropIndicator
171+ opacity: 1
172+ }
173+ },
174+ State {
175+ name: "expanded"
176+ when: dndArea.draggedIndex >= 0 && (dndArea.preDragging || dndArea.dragging || dndArea.postDragging) && dndArea.draggedIndex != index
177+ PropertyChanges {
178+ target: launcherDelegate
179+ angle: 0
180+ offset: 0
181+ itemOpacity: 0.6
182+ }
183+ }
184+ ]
185+
186+ transitions: [
187+ Transition {
188+ from: ""
189+ to: "selected"
190+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.FastDuration }
191+ },
192+ Transition {
193+ from: "*"
194+ to: "expanded"
195+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.FastDuration }
196+ UbuntuNumberAnimation { properties: "angle,offset" }
197+ },
198+ Transition {
199+ from: "expanded"
200+ to: ""
201+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.BriskDuration }
202+ UbuntuNumberAnimation { properties: "angle,offset" }
203+ },
204+ Transition {
205+ from: "selected"
206+ to: "dragging"
207+ UbuntuNumberAnimation { properties: "height" }
208+ NumberAnimation { target: dropIndicator; properties: "opacity"; duration: UbuntuAnimation.FastDuration }
209+ },
210+ Transition {
211+ from: "dragging"
212+ to: "*"
213+ NumberAnimation { target: dropIndicator; properties: "opacity"; duration: UbuntuAnimation.FastDuration }
214+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.BriskDuration }
215+ SequentialAnimation {
216+ UbuntuNumberAnimation { properties: "height" }
217+ PropertyAction { target: dndArea; property: "postDragging"; value: false }
218+ PropertyAction { target: dndArea; property: "draggedIndex"; value: -1 }
219+ }
220+ }
221+ ]
222+ }
223+
224+ MouseArea {
225+ id: dndArea
226+ objectName: "dndArea"
227+ anchors {
228+ fill: parent
229+ topMargin: launcherListView.topMargin
230+ bottomMargin: launcherListView.bottomMargin
231+ }
232+ drag.minimumY: -launcherListView.topMargin
233+ drag.maximumY: height + launcherListView.bottomMargin
234+
235+ property int draggedIndex: -1
236+ property var selectedItem
237+ property bool preDragging: false
238+ property bool dragging: selectedItem !== undefined && selectedItem !== null && selectedItem.dragging
239+ property bool postDragging: false
240+ property int startX
241+ property int startY
242+ property var quickListPopover: null
243+
244+ onPressed: {
245+ selectedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
246+ if (selectedItem !== null) {
247+ selectedItem.highlighted = true
248+ }
249+ }
250+
136− onClicked: {
251+ onClicked: {
252+ var index = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
253+ var clickedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
254+
255+ // Check if we actually clicked an item or only at the spacing in between
256+ if (clickedItem === null) {
257+ return;
258+ }
259+
137− // First/last item do the scrolling at more than 12 degrees
260+ // First/last item do the scrolling at more than 12 degrees
138− if (index == 0 || index == launcherListView.count -1) {
261+ if (index == 0 || index == launcherListView.count - 1) {
262+ if (clickedItem.angle > 12) {
263+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
264+ } else if (clickedItem.angle < -12) {
265+ launcherListView.flick(0, launcherListView.clickFlickSpeed);
266+ } else {
267+ root.applicationSelected(LauncherModel.get(index).desktopFile);
268+ }
269+ return;
270+ }
271+
272+ // the rest launches apps up to an angle of 30 degrees
139− if (angle > 12) {
273+ if (clickedItem.angle > 30) {
140 launcherListView.flick(0, -launcherListView.clickFlickSpeed);
274 launcherListView.flick(0, -launcherListView.clickFlickSpeed);
141− } else if (angle < -12) {
275+ } else if (clickedItem.angle < -30) {
142 launcherListView.flick(0, launcherListView.clickFlickSpeed);
276 launcherListView.flick(0, launcherListView.clickFlickSpeed);
143 } else {
277 } else {
144 root.applicationSelected(LauncherModel.get(index).desktopFile);
278 root.applicationSelected(LauncherModel.get(index).desktopFile);
145 }
279 }
146− return;
147 }
280 }
148
281
149− // the rest launches apps up to an angle of 30 degrees
282+ onCanceled: {
150− if (angle > 30) {
283+ selectedItem.highlighted = false
151− launcherListView.flick(0, -launcherListView.clickFlickSpeed);
284+ selectedItem = undefined;
152− } else if (angle < -30) {
285+ preDragging = false;
153− launcherListView.flick(0, launcherListView.clickFlickSpeed);
286+ postDragging = false;
154− } else {
287+ }
155− root.applicationSelected(LauncherModel.get(index).desktopFile);
288+
289+ onReleased: {
290+ var droppedIndex = draggedIndex;
291+ if (dragging) {
292+ postDragging = true;
293+ } else {
294+ draggedIndex = -1;
295+ }
296+
297+ if (!selectedItem) {
298+ return;
299+ }
300+
301+ selectedItem.highlighted = false
302+ selectedItem.dragging = false;
303+ selectedItem = undefined;
304+ preDragging = false;
305+
306+ drag.target = undefined
307+
308+ progressiveScrollingTimer.stop();
309+ launcherListView.interactive = true;
310+ if (droppedIndex >= launcherListView.count - 2 && postDragging) {
311+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
312+ }
313+ }
314+
315+ onPressAndHold: {
316+ if (Math.abs(selectedItem.angle) > 30) {
317+ return;
318+ }
319+
320+ draggedIndex = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
321+
322+ // Opening QuickList
323+ var quickListModel = launcherListView.model.get(draggedIndex).quickList
324+ var quickListAppId = launcherListView.model.get(draggedIndex).appId
325+
326+ quickListPopover = PopupUtils.open(popoverComponent, selectedItem,
327+ {model: quickListModel, appId: quickListAppId})
328+
329+ launcherListView.interactive = false
330+
331+ var yOffset = draggedIndex > 0 ? (mouseY + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouseY + launcherListView.realContentY
332+
333+ fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon
334+ fakeDragItem.x = 0
335+ fakeDragItem.y = mouseY - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin
336+ fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1)
337+ fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1)
338+ fakeDragItem.count = LauncherModel.get(draggedIndex).count
339+ fakeDragItem.progress = LauncherModel.get(draggedIndex).progress
340+ fakeDragItem.flatten()
341+ drag.target = fakeDragItem
342+
343+ startX = mouseX
344+ startY = mouseY
345+ }
346+
347+ onPositionChanged: {
348+ if (draggedIndex >= 0) {
349+ if (!selectedItem.dragging) {
350+ var distance = Math.max(Math.abs(mouseX - startX), Math.abs(mouseY - startY))
351+ if (!preDragging && distance > units.gu(1.5)) {
352+ preDragging = true;
353+ PopupUtils.close(quickListPopover)
354+ }
355+ if (distance > launcherListView.itemHeight) {
356+ selectedItem.dragging = true
357+ preDragging = false;
358+ }
359+ }
360+ if (!selectedItem.dragging) {
361+ return
362+ }
363+
364+ var itemCenterY = fakeDragItem.y + fakeDragItem.height / 2
365+
366+ // Move it down by the the missing size to compensate index calculation with only expanded items
367+ itemCenterY += (launcherListView.itemHeight - selectedItem.height) / 2
368+
369+ if (mouseY > launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin - launcherListView.realItemHeight) {
370+ progressiveScrollingTimer.downwards = false
371+ progressiveScrollingTimer.start()
372+ } else if (mouseY < launcherListView.realItemHeight) {
373+ progressiveScrollingTimer.downwards = true
374+ progressiveScrollingTimer.start()
375+ } else {
376+ progressiveScrollingTimer.stop()
377+ }
378+
379+ var newIndex = (itemCenterY + launcherListView.realContentY) / launcherListView.realItemHeight
380+
381+ if (newIndex > draggedIndex + 1) {
382+ newIndex = draggedIndex + 1
383+ } else if (newIndex < draggedIndex) {
384+ newIndex = draggedIndex -1
385+ } else {
386+ return
387+ }
388+
389+ if (newIndex >= 0 && newIndex < launcherListView.count) {
390+ launcherListView.model.move(draggedIndex, newIndex)
391+ draggedIndex = newIndex
392+ }
393+ }
394+ }
395+ }
396+ Timer {
397+ id: progressiveScrollingTimer
398+ interval: 2
399+ repeat: true
400+ running: false
401+ property bool downwards: true
402+ onTriggered: {
403+ if (downwards) {
404+ var minY = -launcherListView.topMargin
405+ if (launcherListView.contentY > minY) {
406+ launcherListView.contentY = Math.max(launcherListView.contentY - units.dp(2), minY)
407+ }
408+ } else {
409+ var maxY = launcherListView.contentHeight - launcherListView.height + launcherListView.topMargin + launcherListView.originY
410+ if (launcherListView.contentY < maxY) {
411+ launcherListView.contentY = Math.min(launcherListView.contentY + units.dp(2), maxY)
412+ }
413+ }
156 }
414 }
157 }
415 }
158 }
416 }
417+ }
159
418
160− MouseArea {
419+ LauncherDelegate {
161− id: topFoldingArea
420+ id: fakeDragItem
162− anchors {
421+ objectName: "fakeDragItem"
163− left: parent.left
422+ visible: dndArea.draggedIndex >= 0 && !dndArea.postDragging
164− right: parent.right
423+ itemWidth: launcherListView.itemWidth
165− top: parent.top
166− topMargin: launcherListView.topMargin
424+ itemHeight: launcherListView.itemHeight
167− }
425+ height: itemHeight
168− height: launcherListView.itemSize / 2
426+ width: itemWidth
169− enabled: launcherListView.contentY > -launcherListView.topMargin
427+ rotation: root.rotation
170− onClicked: launcherListView.flick(0, launcherListView.clickFlickSpeed)
428+ highlighted: true
429+ itemOpacity: 0.8
430+
431+ function flatten() {
432+ fakeDragItemAnimation.start();
171 }
433 }
172
434
173− MouseArea {
435+ UbuntuNumberAnimation {
174− id: bottomFoldingArea
436+ id: fakeDragItemAnimation
175− anchors {
437+ target: fakeDragItem;
176− left: parent.left
438+ properties: "angle,offset";
177− right: parent.right
439+ to: 0
178− bottom: parent.bottom
440+ }
179− bottomMargin: launcherListView.bottomMargin
441+ }
442+ }
443+ }
444+
445+ Component {
446+ id: popoverComponent
447+
448+ Popover {
449+ id: popover
450+ property var model
451+ property string appId
452+ contentWidth: quickListColumn.width
453+
454+ // FIXME: There's a bug in the Popover positioning that it covers the item in case it is rotated.
455+ // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1204470
456+ // For now, let's move the Popover around with callerMargin.
457+ // Remove popupMargin once the bug is fixed.
458+ property int popupMargin: root.inverted ? launcherListView.itemHeight : 0;
459+
460+ callerMargin: units.gu(1) + popupMargin
461+
462+ Column {
463+ id: quickListColumn
464+ width: units.gu(30)
465+ height: childrenRect.height
466+
467+ Repeater {
468+ model: popover.model
469+
470+ ListItems.Standard {
471+ objectName: "quickListEntry" + index
472+ text: (model.clickable ? "" : "<b>") + model.label + (model.clickable ? "" : "</b>")
473+ highlightWhenPressed: model.clickable
474+ onClicked: {
475+ if (!model.clickable) {
476+ return;
477+ }
478+ LauncherModel.quickListActionInvoked(appId, index);
479+ PopupUtils.close(popover);
480+ }
180 }
481 }
181− height: launcherListView.itemSize / 2
182− enabled: launcherListView.contentHeight - launcherListView.height - launcherListView.contentY > -launcherListView.bottomMargin
183− onClicked: launcherListView.flick(0, -launcherListView.clickFlickSpeed)
184 }
482 }
185 }
483 }
186 }
484 }
Launcher/graphics/launcher_bg@18.pngdeleted

Binary file not shown.

Launcher/graphics/launcher_bg@18.scideleted−5
@@ -1,5 +0,0 @@
1−border.left: 0
2−border.top: 0
3−border.bottom: 0
4−border.right: 24
5−source: launcher_bg@18.png
Launcher/graphics/launcher_bg@30.pngnew file

Binary file not shown.

Launcher/graphics/launcher_bg@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 4
2+border.top: 4
3+border.bottom: 4
4+border.right: 66
5+source: launcher_bg@30.png
Launcher/graphics/notification@30.pngnew file

Binary file not shown.

Launcher/graphics/notification@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 36
2+border.top: 36
3+border.bottom: 36
4+border.right: 36
5+source: notification@30.png
Launcher/graphics/progressbar-fill@30.pngnew file

Binary file not shown.

Launcher/graphics/progressbar-fill@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 36
2+border.top: 16
3+border.bottom: 28
4+border.right: 36
5+source: progressbar-fill@30.png
Launcher/graphics/progressbar-trough@30.pngnew file

Binary file not shown.

Launcher/graphics/progressbar-trough@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 36
2+border.top: 16
3+border.bottom: 26
4+border.right: 36
5+source: progressbar-trough@30.png
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+18−14
@@ -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: networkPage
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 }
@@ -56,24 +60,24 @@ PageStack {
56 id: networkAgent
60 id: networkAgent
57
61
58 onSecretRequested: {
62 onSecretRequested: {
59− _network.push(passwordPageComponent, {"token": token});
63+ networkPage.push(passwordPageComponent, {"token": token});
60 }
64 }
61 }
65 }
62
66
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/NetworkIndicatorPage2.qmlnew 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+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+import Unity.Indicators.Network 0.1 as ICNetwork
23+import Ubuntu.Components 0.1
24+
25+PageStack {
26+ id: networkPage
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
32+
33+ property alias title: _mainPage.title
34+ property alias emptyText: pluginItem.emptyText
35+ property alias busName: pluginItem.busName
36+ property alias actionsObjectPath : pluginItem.actionsObjectPath
37+ property alias menuObjectPaths : pluginItem.menuObjectPaths
38+
39+ anchors.fill: parent
40+
41+ Page {
42+ id: _mainPage
43+
44+ Indicators.IndicatorPage {
45+ id: pluginItem
46+ anchors.fill: parent
47+ }
48+ }
49+
50+ Component {
51+ id: passwordPageComponent
52+
53+ ICNetwork.PasswordPage {
54+ agent: networkAgent
55+ }
56+ }
57+
58+ ICNetwork.NetworkAgent {
59+ id: networkAgent
60+
61+ onSecretRequested: {
62+ networkPage.push(passwordPageComponent, {"token": token});
63+ }
64+ }
65+
66+ function start()
67+ {
68+ push(_mainPage);
69+ pluginItem.start();
70+ }
71+
72+ function stop()
73+ {
74+ clear();
75+ pluginItem.stop();
76+ }
77+
78+ function reset()
79+ {
80+ pluginItem.reset();
81+ }
82+}
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+23−16
@@ -27,40 +27,47 @@ Indicators.IndicatorsModel {
27 Component.onCompleted: load()
27 Component.onCompleted: load()
28
28
29 indicatorData : {
29 indicatorData : {
30− 'indicator-messaging' : {
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+ },
36+ 'indicator-messages' : {
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,
41− 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/SoundIndicatorWidget.qml',
45+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
42− 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
46+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
43 },
47 },
44 'indicator-network' : {
48 'indicator-network' : {
45 'title': 'Networks',
49 'title': 'Networks',
46 'description' : '',
50 'description' : '',
47− 'priority': 30,
48− 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorWidget.qml',
51+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
49− 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage.qml'
52+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/NetworkIndicatorPage2.qml'
50 },
53 },
51− 'indicator-battery' : {
54+ 'indicator-power' : {
52 'title': 'Battery',
55 'title': 'Battery',
53 'description' : '',
56 'description' : '',
54− 'priority': 40,
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' : '',
55− 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget.qml',
63+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
56− 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage.qml'
64+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
57 },
65 },
58− 'indicator-time' : {
66+ 'indicator-datetime' : {
59 'title': 'Date and Time',
67 'title': 'Date and Time',
60 'description' : '',
68 'description' : '',
61− 'priority': 100,
62− 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorWidget.qml',
69+ 'widgetSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorWidget2.qml',
63− 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DatetimeIndicatorPage.qml'
70+ 'pageSource' : ApplicationPaths.shellAppDirectory()+'/Panel/Indicators/DefaultIndicatorPage2.qml'
64 }
71 }
65 }
72 }
66}
73}
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+6−8
@@ -118,12 +118,12 @@ BasicShell {
118 // through the translucent parts of the shell surface.
118 // through the translucent parts of the shell surface.
119 visible: !fullyCovered && !applicationSurfaceShouldBeSeen
119 visible: !fullyCovered && !applicationSurfaceShouldBeSeen
120
120
121− Image {
121+ CrossFadeImage {
122 id: backgroundImage
122 id: backgroundImage
123− source: shell.background
123+ objectName: "backgroundImage"
124− sourceSize.width: parent.width
124+
125− sourceSize.height: parent.height
126 anchors.fill: parent
125 anchors.fill: parent
126+ source: shell.background
127 }
127 }
128
128
129 Rectangle {
129 Rectangle {
@@ -161,7 +161,6 @@ BasicShell {
161 }
161 }
162 }
162 }
163
163
164−
165 Item {
164 Item {
166 id: stagesOuterContainer
165 id: stagesOuterContainer
167
166
@@ -225,7 +224,6 @@ BasicShell {
225 ignoreUnknownSignals: true
224 ignoreUnknownSignals: true
226 }
225 }
227
226
228−
229 Stage {
227 Stage {
230 id: mainStage
228 id: mainStage
231
229
@@ -537,7 +535,7 @@ BasicShell {
537 }
535 }
538
536
539 Label {
537 Label {
540− anchors.fill: parent
538+ anchors.centerIn: parent
541 visible: applicationManager.fake
539 visible: applicationManager.fake
542 text: "EARLY ALPHA\nNOT READY FOR USE"
540 text: "EARLY ALPHA\nNOT READY FOR USE"
543 color: "lightgrey"
541 color: "lightgrey"
@@ -546,7 +544,7 @@ BasicShell {
546 horizontalAlignment: Text.AlignHCenter
544 horizontalAlignment: Text.AlignHCenter
547 verticalAlignment: Text.AlignVCenter
545 verticalAlignment: Text.AlignVCenter
548 fontSizeMode: Text.Fit
546 fontSizeMode: Text.Fit
549− font.pixelSize: height/2
550 rotation: -45
547 rotation: -45
548+ scale: Math.min(parent.width, parent.height) / width
551 }
549 }
552}
550}
build+5−2
@@ -40,11 +40,14 @@ install_dependencies() {
40 echo "Installing Unity 8 dependencies.."
40 echo "Installing Unity 8 dependencies.."
41 sudo apt-get install devscripts \
41 sudo apt-get install devscripts \
42 equivs \
42 equivs \
43+ gsettings-desktop-schemas \
43 qmenumodel-qml \
44 qmenumodel-qml \
44− qtdeclarative5-ubuntu-ui-toolkit-plugin \
45 qtdeclarative5-dee-plugin \
45 qtdeclarative5-dee-plugin \
46+ qtdeclarative5-gsettings1.0 \
47+ qtdeclarative5-ubuntu-ui-toolkit-plugin \
48+ unity-notifications-impl \
49+ qtdeclarative5-xmllistmodel-plugin \
46 ubuntu-mobile-icons \
50 ubuntu-mobile-icons \
47− unity-notifications-impl-1 \
48 unity-scope-home \
51 unity-scope-home \
49 unity-lens-applications \
52 unity-lens-applications \
50 || exit 5
53 || exit 5
cmake/modules/Plugins.cmake+18−9
@@ -1,3 +1,9 @@
1+find_program(qmlplugindump_exe qmlplugindump)
2+
3+if(NOT qmlplugindump_exe)
4+ msg(FATAL_ERROR "Could not locate qmlplugindump.")
5+endif()
6+
1# Creates target for copying and installing qmlfiles
7# Creates target for copying and installing qmlfiles
2#
8#
3# export_qmlfiles(plugin sub_path)
9# export_qmlfiles(plugin sub_path)
@@ -40,16 +46,19 @@ macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
40 set(multi_value_keywords TARGETS)
46 set(multi_value_keywords TARGETS)
41 cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
47 cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
42
48
49+ # Only try to generate .qmltypes if not cross compiling
50+ if(NOT CMAKE_CROSSCOMPILING)
43− # create the plugin.qmltypes file
51+ # create the plugin.qmltypes file
44− add_custom_target(${PLUGIN}-qmltypes ALL
52+ add_custom_target(${PLUGIN}-qmltypes ALL
45− COMMAND qmlplugindump -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
53+ COMMAND ${qmlplugindump_exe} -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
46− )
54+ )
47− add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
55+ add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
48
56
49− # install the qmltypes file.
57+ # install the qmltypes file.
50− install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
58+ install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
51− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
59+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
52− )
60+ )
61+ endif()
53
62
54 # install the additional targets
63 # install the additional targets
55 install(TARGETS ${qmlplugin_TARGETS}
64 install(TARGETS ${qmlplugin_TARGETS}
debian/changelog+224
@@ -1,3 +1,227 @@
1+unity8 (7.81.3+13.10.20130821-0ubuntu1) saucy; urgency=low
2+
3+ [ Michael Zanetti ]
4+ * added support for count emblems and progress overlays on the
5+ launcher.
6+
7+ [ Pawel Stolowski ]
8+ * Add role for getting filter options model. Add method to activate
9+ option based on index or id.
10+
11+ [ Ted Gould ]
12+ * Mark indicators-client as providing an indicator-renderer.
13+
14+ [ Nick Dedekind ]
15+ * Added flatmenuproxymodel pass-through signals from qmenumodel.
16+ * Renamed indicator-messaging to indicator-messages.
17+
18+ [ Gerry Boland ]
19+ * Typo fix in FrequentlyUsedAppsModel.
20+
21+ [ Ubuntu daily release ]
22+ * Automatic snapshot from revision 224
23+
24+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 21 Aug 2013 08:05:13 +0000
25+
26+unity8 (7.81.3+13.10.20130820.2-0ubuntu1) saucy; urgency=low
27+
28+ [ Michael Zanetti ]
29+ * initial support for quicklists For now they support pinning and
30+ removing of items.
31+
32+ [ Ubuntu daily release ]
33+ * Automatic snapshot from revision 217
34+
35+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 20 Aug 2013 10:09:36 +0000
36+
37+unity8 (7.81.3+13.10.20130820-0ubuntu1) saucy; urgency=low
38+
39+ [ Andrea Cimitan ]
40+ * Implement background changing through gsettings. Make sure it does
41+ fallback to default background when needed.
42+
43+ [ Michael Zanetti ]
44+ * Implement background changing through gsettings. Make sure it does
45+ fallback to default background when needed.
46+ * Add Drag'n'drop support to Launcher As dragging an item pins it to
47+ the launcher this also contains initial quicklist and pinning
48+ support in the plugin part.
49+
50+ [ Michał Sawicz ]
51+ * Fix generic preview wrapping and force rich text parsing.
52+
53+ [ Michal Hruby ]
54+ * Remove the override for Apps available for download, click scope
55+ provides these now.
56+ * Hide rating widgets when scope provides rating set to < 0.0. Also
57+ fallback to regular preview image if there are no more_screenshots
58+ specified.
59+
60+ [ Albert Astals ]
61+ * Make sure minYExtent is updated before setting the new content
62+ height Otherwise bad things can happen in the positioning .
63+
64+ [ Ubuntu daily release ]
65+ * Automatic snapshot from revision 215
66+
67+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 20 Aug 2013 02:08:42 +0000
68+
69+unity8 (7.81.3+13.10.20130816.3-0ubuntu1) saucy; urgency=low
70+
71+ [ Michal Hruby ]
72+ * Implement overrideResults() method, which allows us to seamlessly
73+ combine real scope data with mocked data.
74+
75+ [ Michał Sawicz ]
76+ * Wait for activeFocus before typing in autopilot tests. (LP:
77+ #1212580)
78+
79+ [ Nick Dedekind ]
80+ * Fixed network indicator password dialog not appearing. (LP:
81+ #1212730)
82+ * Remove time & battery indicator service info.
83+
84+ [ Albert Astals ]
85+ * Dash category expansion.
86+ * Fix crash in the shell test Give the item a parent, otherwise the
87+ qml engine decides to adopt it and when we do the deleteLater on
88+ them, they have been already deleted. Since we are the parents, we
89+ don't need to call the deleteLAter eiether they'll be properly
90+ deleted on our deletion.
91+
92+ [ Michael Zanetti ]
93+ * make entering text in lockscreen tests more robust. (LP: #1212580)
94+
95+ [ Michael Terry ]
96+ * Define the 'build' target as PHONY so make doesn't get confused by
97+ our 'build' script.
98+ * Add a test for the Powerd plugin shell support.
99+
100+ [ Pawel Stolowski ]
101+ * Bindings for filters.
102+
103+ [ Ubuntu daily release ]
104+ * Automatic snapshot from revision 208
105+
106+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 Aug 2013 14:11:35 +0000
107+
108+unity8 (7.81.3+13.10.20130814.3-0ubuntu1) saucy; urgency=low
109+
110+ [ Ted Gould ]
111+ * Upstart signals to control indicator services.
112+
113+ [ Nick Dedekind ]
114+ * Replaced indicator menu listView with tabs view.
115+ * Transition Unity.Indicators to UnityMenuModel.
116+
117+ [ Ubuntu daily release ]
118+ * Automatic snapshot from revision 197
119+
120+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 14 Aug 2013 14:33:39 +0000
121+
122+unity8 (7.81.3+13.10.20130814.1-0ubuntu1) saucy; urgency=low
123+
124+ [ Michał Sawicz ]
125+ * Add AppPreview.
126+
127+ [ Nick Dedekind ]
128+ * Use key from indicator service file to source indicator positions.
129+
130+ [ Diego Sarmentero ]
131+ * Add AppPreview.
132+
133+ [ Ubuntu daily release ]
134+ * Automatic snapshot from revision 193
135+
136+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 14 Aug 2013 06:33:14 +0000
137+
138+unity8 (7.81.3+13.10.20130813.1-0ubuntu1) saucy; urgency=low
139+
140+ [ Michael Zanetti ]
141+ * don't scale the EARLY ALPHA warning text bigger than the screen is.
142+
143+ [ Michał Sawicz ]
144+ * Add debug logging to passphrase entry.
145+
146+ [ Albert Astals ]
147+ * Remove unneeded stuff from CMakelists.txt set(CMAKE_AUTOMOC ON)
148+ include(FindPkgConfig) find_package(Qt5Core REQUIRED)
149+ find_package(Qt5Quick REQUIRED) Are already on the top-level
150+ CMakeLists.txt so no need to write them again Well, actually the
151+ Qt5Core wasn't and i added it, it's not really necessary since it's
152+ pulled by the others that depend on it, but it doesn't hurt to be
153+ explicit.
154+
155+ [ Ubuntu daily release ]
156+ * Automatic snapshot from revision 189
157+
158+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 13 Aug 2013 14:08:32 +0000
159+
160+unity8 (7.81.3+13.10.20130812.1-0ubuntu1) saucy; urgency=low
161+
162+ [ Michael Zanetti ]
163+ * preserve lockscreen's background wallpaper's aspect ratio. (LP:
164+ #1208892)
165+
166+ [ Ubuntu daily release ]
167+ * Automatic snapshot from revision 184
168+
169+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 12 Aug 2013 19:14:35 +0000
170+
171+unity8 (7.81.3+13.10.20130812-0ubuntu1) saucy; urgency=low
172+
173+ [ Albert Astals ]
174+ * Fix uses of uninitialized values reported by valgrind.
175+
176+ [ Ubuntu daily release ]
177+ * Automatic snapshot from revision 182
178+
179+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 12 Aug 2013 14:33:29 +0000
180+
181+unity8 (7.81.3+13.10.20130809.1-0ubuntu1) saucy; urgency=low
182+
183+ [ Michal Hruby ]
184+ * Set phone form factor for scope requests.
185+
186+ [ Michał Sawicz ]
187+ * Add support for plurals and update the translation template.
188+
189+ [ Ubuntu daily release ]
190+ * Automatic snapshot from revision 179
191+
192+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 09 Aug 2013 15:35:06 +0000
193+
194+unity8 (7.81.3+13.10.20130809-0ubuntu1) saucy; urgency=low
195+
196+ [ Michał Sawicz ]
197+ * Prepare unity8 for cross-building.
198+
199+ [ Ubuntu daily release ]
200+ * Automatic snapshot from revision 176
201+
202+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 09 Aug 2013 02:32:10 +0000
203+
204+unity8 (7.81.3+13.10.20130808-0ubuntu1) saucy; urgency=low
205+
206+ [ Michał Sawicz ]
207+ * Re-enable battery slider test.
208+
209+ [ Nick Dedekind ]
210+ * Workaround for non-deletion of indicator page menu items. (LP:
211+ #1183065, #1206991)
212+
213+ [ Albert Astals ]
214+ * LVPWH: Fix regression handling the sticky top section culling r166
215+ introduced the regression, this fixes it+tests.
216+ * Implement+test the maximizeVisibleArea function Tries to show as
217+ much possible of an index that is already shown on screen Will be
218+ used for the dash category expansion.
219+
220+ [ Ubuntu daily release ]
221+ * Automatic snapshot from revision 174
222+
223+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 08 Aug 2013 15:23:17 +0000
224+
1unity8 (7.81.3+13.10.20130807-0ubuntu1) saucy; urgency=low
225unity8 (7.81.3+13.10.20130807-0ubuntu1) saucy; urgency=low
2
226
3 [ Michał Sawicz ]
227 [ Michał Sawicz ]
debian/control+13−6
@@ -11,22 +11,26 @@ Build-Depends: cmake,
11 libgles2-mesa-dev[armhf],
11 libgles2-mesa-dev[armhf],
12 libhud-client2-dev,
12 libhud-client2-dev,
13 libjson-perl,
13 libjson-perl,
14+ libnih-dbus-dev,
15+ libnih-dev,
14 libnm-glib-dev,
16 libnm-glib-dev,
15 libnm-util-dev,
17 libnm-util-dev,
16 liblightdm-qt5-3-dev,
18 liblightdm-qt5-3-dev,
17 libpulse-dev,
19 libpulse-dev,
18− libqmenumodel-dev,
20+ libqmenumodel-dev (>= 0.2.7),
19 libqt5v8-5-private-dev,
21 libqt5v8-5-private-dev,
22+ libsigc++-2.0-dev,
20 libunity-api-dev (>= 7.80.3),
23 libunity-api-dev (>= 7.80.3),
21 libunity-core-6.0-dev (<< 7.80),
24 libunity-core-6.0-dev (<< 7.80),
22− libunity-dev (>= 7.0.3),
25+ libunity-dev (>= 7.0.12),
23 libunity-scopes-json-def-phone,
26 libunity-scopes-json-def-phone,
27+ libupstart-dev,
24 libusermetricsoutput1-dev,
28 libusermetricsoutput1-dev,
25 libxcb1-dev,
29 libxcb1-dev,
26 pkg-config,
30 pkg-config,
27− python (>= 2.7),
31+ python:any (>= 2.7),
28 python-setuptools,
32 python-setuptools,
29− python3,
33+ python3:any,
30 qt5-default,
34 qt5-default,
31 qtbase5-dev,
35 qtbase5-dev,
32 qtbase5-dev-tools,
36 qtbase5-dev-tools,
@@ -49,7 +53,7 @@ Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
49
53
50Package: indicators-client
54Package: indicators-client
51Architecture: amd64 armhf i386
55Architecture: amd64 armhf i386
52−Depends: qmenumodel-qml,
56+Depends: qmenumodel-qml (>= 0.2.7),
53 qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
57 qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
54 unity8 (= ${binary:Version}),
58 unity8 (= ${binary:Version}),
55 ${misc:Depends},
59 ${misc:Depends},
@@ -59,8 +63,11 @@ Description: Indicators client test application
59
63
60Package: unity8
64Package: unity8
61Architecture: any
65Architecture: any
66+Provides: indicator-renderer,
67+Depends: gsettings-desktop-schemas,
62−Depends: qmenumodel-qml,
68+ qmenumodel-qml (>= 0.2.7),
63 qtdeclarative5-dee-plugin,
69 qtdeclarative5-dee-plugin,
70+ qtdeclarative5-gsettings1.0,
64 qtdeclarative5-ubuntu-ui-toolkit-plugin,
71 qtdeclarative5-ubuntu-ui-toolkit-plugin,
65 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
72 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
66 qtdeclarative5-xmllistmodel-plugin,
73 qtdeclarative5-xmllistmodel-plugin,
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+47−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 }
@@ -1209,6 +1244,7 @@ void ListViewWithPageHeader::updatePolish()
1209 }
1244 }
1210
1245
1211 m_contentHeightDirty = false;
1246 m_contentHeightDirty = false;
1247+ adjustMinYExtent();
1212 setContentHeight(contentHeight);
1248 setContentHeight(contentHeight);
1213 }
1249 }
1214}
1250}
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/Ubuntu/Gestures/CMakeLists.txt−6
@@ -1,12 +1,6 @@
1# export_qmlplugin macro
1# export_qmlplugin macro
2include(Plugins)
2include(Plugins)
3
3
4−set(CMAKE_AUTOMOC ON)
5−
6−include(FindPkgConfig)
7−find_package(Qt5Core REQUIRED)
8−find_package(Qt5Quick REQUIRED)
9−
10set(UbuntuGestureQml_SOURCES
4set(UbuntuGestureQml_SOURCES
11 plugin.cpp
5 plugin.cpp
12 AxisVelocityCalculator.cpp
6 AxisVelocityCalculator.cpp
plugins/Ubuntu/Gestures/Damper.h+2
@@ -24,6 +24,8 @@
24 */
24 */
25template <class Type> class Damper {
25template <class Type> class Damper {
26public:
26public:
27+ Damper() : m_value(0), m_maxDelta(0) { }
28+
27 // Maximum delta between the raw value and its dampened counterpart.
29 // Maximum delta between the raw value and its dampened counterpart.
28 void setMaxDelta(Type maxDelta) {
30 void setMaxDelta(Type maxDelta) {
29 if (maxDelta < 0) qFatal("Damper::maxDelta must be a positive number.");
31 if (maxDelta < 0) qFatal("Damper::maxDelta must be a positive number.");
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−10
@@ -3,22 +3,27 @@ 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)
12add_subdirectory(Network)
15add_subdirectory(Network)
13
16
14include_directories(
17include_directories(
15 ${CMAKE_CURRENT_SOURCE_DIR}
18 ${CMAKE_CURRENT_SOURCE_DIR}
16 ${CMAKE_CURRENT_BINARY_DIR}
19 ${CMAKE_CURRENT_BINARY_DIR}
20+ ${GLIB_INCLUDE_DIRS}
21+ ${GIO_INCLUDE_DIRS}
17 ${QMENUMODEL_INCLUDE_DIRS}
22 ${QMENUMODEL_INCLUDE_DIRS}
23+ ${LIBUPSTART_INCLUDE_DIRS}
18)
24)
19
25
20set(IndicatorsQML_SOURCES
26set(IndicatorsQML_SOURCES
21− flatmenuproxymodel.cpp
22 indicator.cpp
27 indicator.cpp
23 indicators.h
28 indicators.h
24 indicatorsmanager.cpp
29 indicatorsmanager.cpp
@@ -26,24 +31,22 @@ set(IndicatorsQML_SOURCES
26 menucontentactivator.cpp
31 menucontentactivator.cpp
27 modelprinter.cpp
32 modelprinter.cpp
28 plugin.cpp
33 plugin.cpp
34+ rootactionstate.cpp
35+ unitymenumodelcache.cpp
36+ unitymenumodelstack.cpp
29)
37)
30add_definitions(-DUNITYINDICATORS_LIBRARY)
38add_definitions(-DUNITYINDICATORS_LIBRARY)
31
39
32−set(IndicatorsQML_RESOURCES
33− resources/indicators.qrc
34−)
35−
36−qt5_add_resources(IndicatorsQML_RESOURCES_RCC
37− ${IndicatorsQML_RESOURCES}
38−)
39
40
40add_library(IndicatorsQml SHARED
41add_library(IndicatorsQml SHARED
41− ${IndicatorsQML_RESOURCES_RCC}
42 ${IndicatorsQML_SOURCES}
42 ${IndicatorsQML_SOURCES}
43)
43)
44
44
45target_link_libraries(IndicatorsQml
45target_link_libraries(IndicatorsQml
46+ ${GLIB_LIBRARIES}
47+ ${GIO_LIBRARIES}
46 ${QMENUMODEL_LDFLAGS}
48 ${QMENUMODEL_LDFLAGS}
49+ ${LIBUPSTART_LIBRARIES}
47)
50)
48
51
49qt5_use_modules(IndicatorsQml Core Qml Quick)
52qt5_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/Network/qml/AccessPoint.qml+16−22
@@ -22,47 +22,41 @@ import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
22import Ubuntu.Components.ListItems 0.1 as ListItem
23import Unity.Indicators 0.1 as Indicators
23import Unity.Indicators 0.1 as Indicators
24
24
25−Indicators.MenuItem {
25+Indicators.FramedMenuItem {
26 id: accessPoint
26 id: accessPoint
27− property variant actionWifiApStrength : menu && actionGroup ? actionGroup.action(menu.extra.canonical_wifi_ap_strength_action) : null
28− property variant wifiApStrength : actionWifiApStrength && actionWifiApStrength.valid ? actionWifiApStrength.state : "0"
29
27
28+ readonly property bool checked: menu ? menu.isToggled : false
29+
30+ onCheckedChanged: {
31+ // Can't rely on binding. Checked is assigned on click.
32+ checkBoxActive.checked = checked;
33+ }
34+
35+ // FIXME - we need to get the strength from menu.ext.xCanonicalWifiApStrengthAction
36+ // but UnityMenuModel doesnt support fetching actions not attached to menu item.
30 function getNetworkIcon(data) {
37 function getNetworkIcon(data) {
31 var imageName = "nm-signal-100"
38 var imageName = "nm-signal-100"
32− var signalStrength = parseInt(wifiApStrength)
33
39
34− if (data.extra.canonical_wifi_ap_is_adhoc) {
40+ if (data.ext.xCanonicalWifiApIsAdhoc) {
35 imageName = "nm-adhoc";
41 imageName = "nm-adhoc";
36− } else if (signalStrength == 0) {
37− imageName = "nm-signal-00";
38− } else if (signalStrength <= 25) {
39− imageName = "nm-signal-25";
40− } else if (signalStrength <= 50) {
41− imageName = "nm-signal-50";
42− } else if (signalStrength <= 75) {
43− imageName = "nm-signal-75";
44 }
42 }
45−
43+ if (data.ext.xCanonicalWifiApIsSecure) {
46− if (data.extra.canonical_wifi_ap_is_secure) {
47 imageName += "-secure";
44 imageName += "-secure";
48 }
45 }
49
46
50 return "image://gicon/" + imageName;
47 return "image://gicon/" + imageName;
51 }
48 }
52
49
53− icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://gicon/wifi-none"
50+ icon: menu ? getNetworkIcon(menu) : "image://gicon/wifi-none"
54 iconFrame: false
51 iconFrame: false
55 control: CheckBox {
52 control: CheckBox {
56 id: checkBoxActive
53 id: checkBoxActive
57 height: units.gu(4)
54 height: units.gu(4)
58 width: units.gu(4)
55 width: units.gu(4)
59 anchors.centerIn: parent
56 anchors.centerIn: parent
60− }
61
57
62− Indicators.MenuActionBinding {
58+ onClicked: {
63− actionGroup: accessPoint.actionGroup
59+ accessPoint.activate();
64− action: menu ? menu.action : ""
60+ }
65− target: checkBoxActive
66− property: "checked"
67 }
61 }
68}
62}
plugins/Unity/Indicators/Network/qml/PasswordPage.qml+2−2
@@ -41,7 +41,7 @@ Page {
41 label: "Authentication"
41 label: "Authentication"
42 }
42 }
43
43
44− Indicators.MenuItem {
44+ Indicators.FramedMenuItem {
45 implicitHeight: password.height + units.gu(1)
45 implicitHeight: password.height + units.gu(1)
46
46
47 PasswordTextField {
47 PasswordTextField {
@@ -55,7 +55,7 @@ Page {
55 }
55 }
56 }
56 }
57
57
58− Indicators.MenuItem {
58+ Indicators.FramedMenuItem {
59 Row {
59 Row {
60 anchors {
60 anchors {
61 right: parent.right
61 right: parent.right
plugins/Unity/Indicators/Network/qml/WifiSection.qml+1−7
@@ -24,11 +24,5 @@ import Unity.Indicators 0.1 as Indicators
24Indicators.SectionMenuItem {
24Indicators.SectionMenuItem {
25 id: wifiSectionMenu
25 id: wifiSectionMenu
26
26
27− Indicators.MenuAction {
27+ busy: menu ? menu.ext.xCanonicalBusyAction : false
28− id: busyAction
29− actionGroup: wifiSectionMenu.actionGroup
30− action: menu ? menu.extra.canonical_busy_action : ""
31− }
32−
33− busy: busyAction.valid ? busyAction.state : false
34}
28}
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+41−56
@@ -19,22 +19,12 @@
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
23import Unity.Indicators.Network 0.1 as ICNetwork
22import Unity.Indicators.Network 0.1 as ICNetwork
24
23
25Item {
24Item {
26 id: menuFactory
25 id: menuFactory
27
26
28− property QtObject menu
27+ 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
28
39 property var _map: {
29 property var _map: {
40 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
30 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
@@ -47,64 +37,59 @@ Item {
47 "com.canonical.indicator.slider" : sliderMenu,
37 "com.canonical.indicator.slider" : sliderMenu,
48 "com.canonical.indicator.switch" : switchMenu,
38 "com.canonical.indicator.switch" : switchMenu,
49
39
50− "com.canonical.indicator.messages.messageitem" : messageItem,
40+ "com.canonical.unity.slider" : sliderMenu,
51− "com.canonical.indicator.messages.snapdecision" : snapDecision,
41+ "com.canonical.unity.switch" : switchMenu,
52− "com.canonical.indicator.messages.sourceitem" : groupedMessage,
53
42
54− "unity.widget.systemsettings.tablet.sectiontitle" : wifiSection,
55 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
43 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
56 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
44 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
57 }
45 }
58
46
47+ Component {
48+ id: sliderMenu;
59− Component { id: sliderMenu; Indicators.SliderMenuItem {} }
49+ Indicators.SliderMenuItem {
60− Component { id: switchMenu; Indicators.SwitchMenuItem {} }
50+ Component.onCompleted: {
51+ model.loadExtendedAttributes(modelIndex, {'min-value': 'double',
52+ 'max-value': 'double',
53+ 'min-icon': 'icon',
54+ 'max-icon': 'icon'});
55+ }
56+ }
57+ }
61 Component { id: buttonMenu; Indicators.ButtonMenuItem {} }
58 Component { id: buttonMenu; Indicators.ButtonMenuItem {} }
62 Component { id: divMenu; Indicators.DivMenuItem {} }
59 Component { id: divMenu; Indicators.DivMenuItem {} }
63 Component { id: sectionMenu; Indicators.SectionMenuItem {} }
60 Component { id: sectionMenu; Indicators.SectionMenuItem {} }
64 Component { id: progressMenu; Indicators.ProgressMenuItem {} }
61 Component { id: progressMenu; Indicators.ProgressMenuItem {} }
65− Component { id: messageItem; ICMessaging.MessageMenuItem {} }
62+ Component { id: standardMenu; Indicators.StandardMenuItem {} }
66− Component { id: snapDecision; ICMessaging.SnapDecision {} }
63+ Component { id: switchMenu; Indicators.SwitchMenuItem {} }
67− Component { id: groupedMessage; ICMessaging.GroupedMessage {} }
64+ Component {
65+ id: wifiSection;
68− Component { id: wifiSection; ICNetwork.WifiSection {} }
66+ ICNetwork.WifiSection {
69− Component { id: accessPoint; ICNetwork.AccessPoint {} }
67+ Component.onCompleted: {
70− Component { id: indicatorMenu; Indicators.MenuItem {} }
68+ model.loadExtendedAttributes(modelIndex, {'x-canonical-busy-action': 'bool'});
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 }
69 }
85−
70+ }
86− var widgetType = menuFactory.menu.extra.canonical_type;
71+ }
87− if (widgetType) {
72+ Component {
88− return _map[widgetType];
73+ id: accessPoint;
89− } else {
74+ ICNetwork.AccessPoint {
90− if (widgetType === "com.canonical.indicator.root") {
75+ Component.onCompleted: {
91− return undefined;
76+ model.loadExtendedAttributes(modelIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
92− // Try discovery the item based on the basic properties
77+ 'x-canonical-wifi-ap-is-secure': 'bool'});
93− } else if (menu.hasSection) {
94− return sectionMenu;
95− } else {
96− return indicatorMenu;
97− }
98 }
78 }
99 }
79 }
80+ }
100
81
101− onLoaded: {
82+ function load(modelData) {
102− item.menuActivated = Qt.binding(function() { return isCurrentItem; });
83+ if (modelData.type !== undefined) {
103− item.actionGroup = Qt.binding(function() { return menuFactory.actionGroup; });
84+ var component = _map[modelData.type];
104− item.menu = Qt.binding(function() { return menuFactory.menu; });
85+ if (component !== undefined) {
105−
86+ return component;
106− item.activateMenu.connect(function() { menuFactory.activated(); });
87+ }
107− item.deactivateMenu.connect(function() { menuFactory.deactivated(); });
88+ } else {
89+ if (modelData.isSeparator) {
90+ return divMenu;
91+ }
108 }
92 }
93+ return standardMenu;
109 }
94 }
110}
95}
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/IndicatorsLegacy/Network/CMakeLists.txtnew file+45
@@ -0,0 +1,45 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+project(IndicatorsLegacyNetworkQml)
5+
6+pkg_check_modules(GLIB glib-2.0>=2.32)
7+pkg_check_modules(LIBNM_GLIB libnm-glib>=0.9.6)
8+pkg_check_modules(LIBNM_UTIL libnm-util>=0.9.6)
9+
10+if(LIBNM_GLIB_FOUND AND LIBNM_UTIL_FOUND AND GLIB_FOUND)
11+ set(INDICATORS_LEGACY_NETWORK_SRC
12+ networkagent.cpp
13+ plugin.cpp
14+ secret-agent.c
15+ )
16+
17+ add_library(IndicatorsLegacyNetworkQml MODULE
18+ ${INDICATORS_LEGACY_NETWORK_SRC}
19+ )
20+
21+ qt5_use_modules(IndicatorsLegacyNetworkQml Core Qml Widgets)
22+
23+ set_target_properties(IndicatorsLegacyNetworkQml PROPERTIES COMPILE_FLAGS -fPIC)
24+
25+ include_directories(
26+ ${CMAKE_CURRENT_SOURCE_DIR}
27+ ${GLIB_INCLUDE_DIRS}
28+ ${LIBNM_GLIB_INCLUDE_DIRS}
29+ ${LIBNM_UTIL_INCLUDE_DIRS}
30+ )
31+
32+ target_link_libraries(IndicatorsLegacyNetworkQml
33+ ${GLIB_LIBRARIES}
34+ ${LIBNM_GLIB_LIBRARIES}
35+ ${LIBNM_UTIL_LIBRARIES}
36+ )
37+
38+ # export the qmltypes and plugin files
39+ export_qmlplugin(Unity.IndicatorsLegacy.Network 0.1 Unity/IndicatorsLegacy/Network TARGETS IndicatorsLegacyNetworkQml)
40+
41+else()
42+ message(WARNING "Missing glib or libnm dependency for the network plugin, not building")
43+endif()
44+
45+add_subdirectory(qml)
plugins/Unity/IndicatorsLegacy/Network/networkagent.cppnew file+146
@@ -0,0 +1,146 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+#include "networkagent.h"
22+
23+#include <QVariant>
24+#include <QApplication>
25+#include <QDebug>
26+
27+class NetworkAgentToken
28+{
29+public:
30+ NMConnection *connection;
31+ NMSettingWirelessSecurity *wisec;
32+ guint id;
33+ QByteArray keyMgmt;
34+
35+ NetworkAgentToken(NMConnection *connection,
36+ NMSettingWirelessSecurity *wisec,
37+ guint id,
38+ QByteArray keyMgmt)
39+ : connection(connection),
40+ wisec(wisec),
41+ id(id),
42+ keyMgmt(keyMgmt)
43+ {
44+ if (connection) {
45+ g_object_ref(connection);
46+ } else {
47+ qWarning() << "invalid connection object";
48+ }
49+ }
50+
51+ ~NetworkAgentToken()
52+ {
53+ if (connection) {
54+ g_object_unref(connection);
55+ }
56+ }
57+};
58+
59+NetworkAgent::NetworkAgent(QObject *parent)
60+ : QObject(parent)
61+{
62+ m_agent = unity_settings_secret_agent_new();
63+ g_signal_connect(G_OBJECT(m_agent),
64+ UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
65+ G_CALLBACK(onSecretRequested),
66+ this);
67+
68+ g_signal_connect(G_OBJECT(m_agent),
69+ UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
70+ G_CALLBACK(onSecretRequestCancelled),
71+ this);
72+}
73+
74+NetworkAgent::~NetworkAgent()
75+{
76+ nm_secret_agent_unregister(NM_SECRET_AGENT(m_agent));
77+ g_object_unref(m_agent);
78+}
79+
80+void NetworkAgent::authenticate(const QVariant &token, const QString &key)
81+{
82+ NetworkAgentToken *pToken = (NetworkAgentToken *) token.value<void *>();
83+ if (pToken == NULL) {
84+ return;
85+ }
86+
87+ if ((pToken->keyMgmt == "wpa-none") || (pToken->keyMgmt == "wpa-psk")) {
88+ g_object_set(G_OBJECT(pToken->wisec),
89+ NM_SETTING_WIRELESS_SECURITY_PSK, qPrintable(key),
90+ NULL);
91+ } else if (pToken->keyMgmt == "none") {
92+ g_object_set(G_OBJECT(pToken->wisec),
93+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, qPrintable(key),
94+ NULL);
95+ }
96+
97+ GHashTable *settings = nm_connection_to_hash(pToken->connection,
98+ NM_SETTING_HASH_FLAG_ALL);
99+
100+ unity_settings_secret_agent_provide_secret(m_agent,
101+ pToken->id, settings);
102+ g_hash_table_unref(settings);
103+ delete pToken;
104+}
105+
106+void NetworkAgent::cancel(const QVariant &token)
107+{
108+ NetworkAgentToken *pToken = (NetworkAgentToken *) token.value<void *>();
109+ if (pToken != NULL) {
110+ unity_settings_secret_agent_cancel_request(m_agent, pToken->id);
111+ delete pToken;
112+ }
113+}
114+
115+void NetworkAgent::onSecretRequested(UnitySettingsSecretAgent* /*agent*/,
116+ guint id,
117+ NMConnection* connection,
118+ const char* /*setting_name*/,
119+ const char** /*hints*/,
120+ NMSecretAgentGetSecretsFlags /*flags*/,
121+ NetworkAgent* self)
122+{
123+ NetworkAgentToken *token = new NetworkAgentToken(connection,
124+ NULL,
125+ id,
126+ NULL);
127+
128+ token->wisec = nm_connection_get_setting_wireless_security(connection);
129+ if (token->wisec) {
130+ token->keyMgmt = nm_setting_wireless_security_get_key_mgmt(token->wisec);
131+ }
132+
133+ QVariant varToken = qVariantFromValue((void *) token);
134+ Q_EMIT self->secretRequested(varToken);
135+}
136+
137+void NetworkAgent::onSecretRequestCancelled(UnitySettingsSecretAgent* /*agent*/,
138+ guint /*id*/,
139+ NMConnection* /*connection*/,
140+ const char* /*setting_name*/,
141+ const char** /*hints*/,
142+ NMSecretAgentGetSecretsFlags /*flags*/,
143+ NetworkAgent* /*self*/)
144+{
145+ //Do nothing for now
146+}
plugins/Unity/IndicatorsLegacy/Network/networkagent.hnew 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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+#ifndef NETWORKAGENT_H
22+#define NETWORKAGENT_H
23+
24+#include "secret-agent.h"
25+
26+#include <QObject>
27+
28+class NetworkAgentToken;
29+
30+class NetworkAgent : public QObject
31+{
32+ Q_OBJECT
33+public:
34+ NetworkAgent(QObject *parent=0);
35+ ~NetworkAgent();
36+
37+ Q_INVOKABLE void authenticate(const QVariant &token, const QString &key);
38+ Q_INVOKABLE void cancel(const QVariant &token);
39+
40+Q_SIGNALS:
41+ void secretRequested(const QVariant &token);
42+ void secretRequestCancelled();
43+
44+private:
45+ UnitySettingsSecretAgent *m_agent;
46+
47+ static void onSecretRequested(UnitySettingsSecretAgent *agent,
48+ guint id,
49+ NMConnection *connection,
50+ const char *setting_name,
51+ const char **hints,
52+ NMSecretAgentGetSecretsFlags flags,
53+ NetworkAgent *self);
54+
55+ static void onSecretRequestCancelled(UnitySettingsSecretAgent *agent,
56+ guint id,
57+ NMConnection *connection,
58+ const char *setting_name,
59+ const char **hints,
60+ NMSecretAgentGetSecretsFlags flags,
61+ NetworkAgent *self);
62+
63+};
64+
65+#endif
plugins/Unity/IndicatorsLegacy/Network/plugin.cppnew file+31
@@ -0,0 +1,31 @@
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 "networkagent.h"
27+
28+void IndicatorsNetworkPlugin::registerTypes(const char *uri)
29+{
30+ qmlRegisterType<NetworkAgent>(uri, 0, 1, "NetworkAgent");
31+}
plugins/Unity/IndicatorsLegacy/Network/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_NETWORK_PLUGIN_H
20+#define INDICATORS_NETWORK_PLUGIN_H
21+
22+#include <QtQml/QQmlExtensionPlugin>
23+
24+class IndicatorsNetworkPlugin : 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_NETWORK_PLUGIN_H
plugins/Unity/IndicatorsLegacy/Network/qml/AccessPoint.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+ * 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+import Unity.IndicatorsLegacy 0.1 as Indicators
24+
25+Indicators.MenuItem {
26+ id: accessPoint
27+ property variant actionWifiApStrength : menu && actionGroup ? actionGroup.action(menu.extra.canonical_wifi_ap_strength_action) : null
28+ property variant wifiApStrength : actionWifiApStrength && actionWifiApStrength.valid ? actionWifiApStrength.state : "0"
29+
30+ function getNetworkIcon(data) {
31+ var imageName = "nm-signal-100"
32+ var signalStrength = parseInt(wifiApStrength)
33+
34+ if (data.extra.canonical_wifi_ap_is_adhoc) {
35+ imageName = "nm-adhoc";
36+ } else if (signalStrength == 0) {
37+ imageName = "nm-signal-00";
38+ } else if (signalStrength <= 25) {
39+ imageName = "nm-signal-25";
40+ } else if (signalStrength <= 50) {
41+ imageName = "nm-signal-50";
42+ } else if (signalStrength <= 75) {
43+ imageName = "nm-signal-75";
44+ }
45+
46+ if (data.extra.canonical_wifi_ap_is_secure) {
47+ imageName += "-secure";
48+ }
49+
50+ return "image://gicon/" + imageName;
51+ }
52+
53+ icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://gicon/wifi-none"
54+ iconFrame: false
55+ control: CheckBox {
56+ id: checkBoxActive
57+ height: units.gu(4)
58+ width: units.gu(4)
59+ anchors.centerIn: parent
60+ }
61+
62+ Indicators.MenuActionBinding {
63+ actionGroup: accessPoint.actionGroup
64+ action: menu ? menu.action : ""
65+ target: checkBoxActive
66+ property: "checked"
67+ }
68+}
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/IndicatorsLegacy/Network/qml/PasswordPage.qmlnew file+88
@@ -0,0 +1,88 @@
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+import Unity.IndicatorsLegacy 0.1 as Indicators
24+
25+Page {
26+ id: pagePassword
27+
28+ property variant agent
29+ property variant token
30+
31+ anchors.fill: parent
32+ title: "Network Authentication"
33+
34+ Column {
35+ anchors {
36+ left: parent.left
37+ right: parent.right
38+ }
39+
40+ Indicators.SectionMenuItem {
41+ label: "Authentication"
42+ }
43+
44+ Indicators.MenuItem {
45+ implicitHeight: password.height + units.gu(1)
46+
47+ PasswordTextField {
48+ id: password
49+ anchors {
50+ left: parent.left
51+ right: parent.right
52+ margins: units.gu(3)
53+ verticalCenter: parent.verticalCenter
54+ }
55+ }
56+ }
57+
58+ Indicators.MenuItem {
59+ Row {
60+ anchors {
61+ right: parent.right
62+ verticalCenter: parent.verticalCenter
63+ margins: units.gu(3)
64+ }
65+
66+ spacing: units.gu(1)
67+
68+ Button {
69+ text: "Cancel"
70+ width: units.gu(10)
71+ onClicked: {
72+ agent.cancel(token);
73+ pageStack.pop();
74+ }
75+ }
76+
77+ Button {
78+ text: "OK"
79+ width: units.gu(10)
80+ onClicked: {
81+ agent.authenticate(token, password.text);
82+ pageStack.pop();
83+ }
84+ }
85+ }
86+ }
87+ }
88+}
plugins/Unity/IndicatorsLegacy/Network/qml/PasswordTextField.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+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+
23+Item {
24+ id: textMenu
25+
26+ property alias text: textField.text
27+
28+ height: contentColumn.height
29+
30+ Column {
31+ id: contentColumn
32+ spacing: units.gu(0.5)
33+ anchors {
34+ left: parent.left
35+ right: parent.right
36+ }
37+
38+ TextField {
39+ id: textField
40+
41+ anchors {
42+ left: parent.left
43+ right: parent.right
44+ }
45+
46+ placeholderText: "Password"
47+ echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password
48+ }
49+
50+ Row {
51+ anchors {
52+ left: parent.left
53+ right: parent.right
54+ }
55+
56+ spacing: units.gu(1)
57+
58+ CheckBox {
59+ id: showPassword
60+ }
61+
62+ Label {
63+ text: "Show password"
64+ anchors.verticalCenter: showPassword.verticalCenter
65+ }
66+ }
67+ }
68+}
plugins/Unity/IndicatorsLegacy/Network/qml/WifiSection.qmlnew file+34
@@ -0,0 +1,34 @@
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 Unity.IndicatorsLegacy 0.1 as Indicators
23+
24+Indicators.SectionMenuItem {
25+ id: wifiSectionMenu
26+
27+ Indicators.MenuAction {
28+ id: busyAction
29+ actionGroup: wifiSectionMenu.actionGroup
30+ action: menu ? menu.extra.canonical_busy_action : ""
31+ }
32+
33+ busy: busyAction.valid ? busyAction.state : false
34+}
plugins/Unity/IndicatorsLegacy/Network/qml/qmldirnew file+9
@@ -0,0 +1,9 @@
1+module Unity.IndicatorsLegacy.Network
2+plugin IndicatorsLegacyNetworkQml
3+typeinfo plugin.qmltypes
4+
5+NetworkPage 0.1 NetworkPage.qml
6+AccessPoint 0.1 AccessPoint.qml
7+PasswordPage 0.1 PasswordPage.qml
8+PasswordTextField 0.1 PasswordTextField.qml
9+WifiSection 0.1 WifiSection.qml
plugins/Unity/IndicatorsLegacy/Network/secret-agent.cnew file+382
@@ -0,0 +1,382 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+
22+#include <glib.h>
23+#include <glib-object.h>
24+#include <nm-secret-agent.h>
25+#include "secret-agent.h"
26+
27+#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
28+#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
29+#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
30+#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
31+#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
32+#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
33+#define UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentPrivate))
34+
35+#define AGENT_ID "com.canonical.settings.network.nm-agent"
36+
37+static gpointer unity_settings_secret_agent_parent_class = NULL;
38+
39+typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
40+
41+struct _UnitySettingsSecretAgentPrivate {
42+ GQueue *requests;
43+};
44+
45+typedef struct _SecretRequest {
46+ gint id;
47+ NMSecretAgent *agent;
48+ NMConnection *connection;
49+ const char *connection_path;
50+ const char *setting_name;
51+ const char **hints;
52+ NMSecretAgentGetSecretsFlags flags;
53+ NMSecretAgentGetSecretsFunc callback;
54+ gpointer callback_data;
55+} SecretRequest;
56+
57+GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
58+enum {
59+ UNITY_SETTINGS_SECRET_AGENT_DUMMY_PROPERTY
60+};
61+
62+enum {
63+ SECRET_REQUESTED,
64+ REQUEST_CANCELLED,
65+ LAST_SIGNAL
66+};
67+
68+static guint signals[LAST_SIGNAL] = { 0 };
69+
70+UnitySettingsSecretAgent* unity_settings_secret_agent_new (void);
71+UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
72+
73+int
74+secret_request_find (SecretRequest *req,
75+ guint *id)
76+{
77+ if (req->id > *id)
78+ return -1;
79+
80+ if (req->id < *id)
81+ return 1;
82+
83+ return 0;
84+}
85+
86+void
87+unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
88+ guint request,
89+ GHashTable *secrets)
90+{
91+ GList *iter;
92+ SecretRequest *req;
93+ UnitySettingsSecretAgentPrivate *priv = agent->priv;
94+
95+ iter = g_queue_find_custom (priv->requests,
96+ &request,
97+ (GCompareFunc)secret_request_find);
98+
99+ if (iter == NULL || iter->data == NULL)
100+ {
101+ g_warning ("Secret request with id <%d> was not found", (int)request);
102+ return;
103+ }
104+
105+ req = iter->data;
106+
107+ req->callback (NM_SECRET_AGENT (agent),
108+ req->connection,
109+ secrets,
110+ NULL,
111+ req->callback_data);
112+
113+ g_queue_remove_all (priv->requests, req);
114+ g_free (req);
115+ return;
116+}
117+
118+void
119+free_request (SecretRequest *req)
120+{
121+ g_object_unref (req->connection);
122+ g_free (req);
123+}
124+
125+void
126+unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
127+ guint request)
128+{
129+ GList *iter;
130+ SecretRequest *req;
131+ UnitySettingsSecretAgentPrivate *priv = agent->priv;
132+ GError *error;
133+
134+ iter = g_queue_find_custom (priv->requests,
135+ &request,
136+ (GCompareFunc)secret_request_find);
137+
138+ if (iter == NULL || iter->data == NULL)
139+ {
140+ g_warning ("Secret request with id <%d> was not found", (int)request);
141+ return;
142+ }
143+
144+ req = iter->data;
145+ error = g_error_new (NM_SECRET_AGENT_ERROR,
146+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
147+ "This secret request was canceled by the user.");
148+
149+ req->callback (NM_SECRET_AGENT (agent),
150+ req->connection,
151+ NULL,
152+ error,
153+ req->callback_data);
154+
155+ g_queue_remove_all (priv->requests, req);
156+ free_request (req);
157+ return;
158+}
159+
160+static void
161+delete_secrets (NMSecretAgent *agent,
162+ NMConnection *connection,
163+ const char *connection_path,
164+ NMSecretAgentDeleteSecretsFunc callback,
165+ gpointer callback_data)
166+{
167+ g_debug ("delete secrets");
168+}
169+
170+/* If it returns G_MAXUINT it's considered an error */
171+static guint
172+find_available_id (UnitySettingsSecretAgentPrivate *priv)
173+{
174+ guint i = 0;
175+ guint candidate = 0;
176+
177+ if (g_queue_get_length (priv->requests) == G_MAXUINT)
178+ return G_MAXUINT;
179+
180+ while (i < g_queue_get_length (priv->requests))
181+ {
182+ SecretRequest *req = (SecretRequest*)g_queue_peek_nth (priv->requests, i);
183+
184+ if (req->id == candidate)
185+ {
186+ candidate++;
187+ i = 0;
188+ }
189+ else
190+ {
191+ i++;
192+ }
193+ }
194+
195+ return i;
196+}
197+
198+static void
199+get_secrets (NMSecretAgent *agent,
200+ NMConnection *connection,
201+ const char *connection_path,
202+ const char *setting_name,
203+ const char **hints,
204+ NMSecretAgentGetSecretsFlags flags,
205+ NMSecretAgentGetSecretsFunc callback,
206+ gpointer callback_data)
207+{
208+ guint id;
209+ UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
210+ SecretRequest *req = NULL;
211+
212+ if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
213+ {
214+ GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
215+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
216+ "No password found for this connection.");
217+ callback (agent, connection, NULL, error, callback_data);
218+ g_error_free (error);
219+ return;
220+ }
221+
222+ id = find_available_id (priv);
223+ if (id == G_MAXUINT)
224+ {
225+ GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
226+ NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
227+ "Reached maximum number of requests.");
228+ callback (agent, connection, NULL, error, callback_data);
229+ g_error_free (error);
230+ return;
231+ }
232+
233+ /* Adding a request */
234+ req = (SecretRequest*) g_malloc0 (sizeof (SecretRequest));
235+ *req = ((SecretRequest)
236+ { id,
237+ agent,
238+ connection,
239+ connection_path,
240+ setting_name,
241+ hints,
242+ flags,
243+ callback,
244+ callback_data });
245+
246+ g_object_ref (connection);
247+
248+ g_queue_push_tail (priv->requests, req);
249+
250+ g_signal_emit_by_name (agent,
251+ UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
252+ id,
253+ connection,
254+ setting_name,
255+ hints,
256+ flags);
257+}
258+
259+static void
260+save_secrets (NMSecretAgent *agent,
261+ NMConnection *connection,
262+ const char *connection_path,
263+ NMSecretAgentSaveSecretsFunc callback,
264+ gpointer callback_data)
265+{
266+ g_debug ("save secrets");
267+}
268+
269+static void
270+cancel_get_secrets (NMSecretAgent *agent,
271+ const char *connection_path,
272+ const char *setting_name)
273+{
274+ g_debug ("cancel get secrets");
275+}
276+
277+UnitySettingsSecretAgent*
278+unity_settings_secret_agent_construct (GType object_type)
279+{
280+ UnitySettingsSecretAgent * self = NULL;
281+ self = (UnitySettingsSecretAgent*) g_object_new (object_type,
282+ NM_SECRET_AGENT_IDENTIFIER, AGENT_ID,
283+ NULL);
284+ return self;
285+}
286+
287+
288+UnitySettingsSecretAgent*
289+unity_settings_secret_agent_new (void)
290+{
291+ return unity_settings_secret_agent_construct (UNITY_SETTINGS_TYPE_SECRET_AGENT);
292+}
293+
294+static void
295+destroy_pending_request (gpointer data)
296+{
297+ SecretRequest* req = (SecretRequest*)data;
298+ /* Reporting the cancellation of all pending requests */
299+ g_signal_emit_by_name (req->agent,
300+ UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
301+ req->id);
302+
303+ free_request (req);
304+}
305+
306+static void
307+unity_settings_secret_agent_finalize (GObject *agent)
308+{
309+ UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
310+
311+ g_queue_free_full (priv->requests, destroy_pending_request);
312+}
313+
314+static void
315+unity_settings_secret_agent_class_init (UnitySettingsSecretAgentClass *klass)
316+{
317+ unity_settings_secret_agent_parent_class = g_type_class_peek_parent (klass);
318+ NMSecretAgentClass *parent_class = NM_SECRET_AGENT_CLASS (klass);
319+ parent_class->get_secrets = get_secrets;
320+ parent_class->save_secrets = save_secrets;
321+ parent_class->delete_secrets = delete_secrets;
322+ parent_class->cancel_get_secrets = cancel_get_secrets;
323+
324+ g_type_class_add_private (klass, sizeof(UnitySettingsSecretAgentPrivate));
325+ G_OBJECT_CLASS (klass)->finalize = unity_settings_secret_agent_finalize;
326+
327+
328+ signals[SECRET_REQUESTED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
329+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
330+ G_SIGNAL_RUN_FIRST,
331+ G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, secret_requested),
332+ NULL, NULL, NULL,
333+ G_TYPE_NONE, 5,
334+ G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT);
335+
336+ signals[REQUEST_CANCELLED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
337+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
338+ G_SIGNAL_RUN_FIRST,
339+ G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, request_cancelled),
340+ NULL, NULL, NULL,
341+ G_TYPE_NONE, 1,
342+ G_TYPE_UINT);
343+}
344+
345+
346+static void
347+unity_settings_secret_agent_instance_init (UnitySettingsSecretAgent *self)
348+{
349+ self->priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (self);
350+ self->priv->requests = g_queue_new ();
351+}
352+
353+GType
354+unity_settings_secret_agent_get_type (void)
355+{
356+ static volatile gsize unity_settings_secret_agent_type_id__volatile = 0;
357+ if (g_once_init_enter (&unity_settings_secret_agent_type_id__volatile))
358+ {
359+ static const GTypeInfo g_define_type_info =
360+ {
361+ sizeof (UnitySettingsSecretAgentClass),
362+ (GBaseInitFunc) NULL,
363+ (GBaseFinalizeFunc) NULL,
364+ (GClassInitFunc) unity_settings_secret_agent_class_init,
365+ (GClassFinalizeFunc) NULL,
366+ NULL,
367+ sizeof (UnitySettingsSecretAgent),
368+ 0,
369+ (GInstanceInitFunc) unity_settings_secret_agent_instance_init,
370+ NULL
371+ };
372+ GType unity_settings_secret_agent_type_id;
373+ unity_settings_secret_agent_type_id = g_type_register_static (NM_TYPE_SECRET_AGENT,
374+ "UnitySettingsSecretAgent",
375+ &g_define_type_info,
376+ 0);
377+ g_once_init_leave (&unity_settings_secret_agent_type_id__volatile,
378+ unity_settings_secret_agent_type_id);
379+ }
380+
381+ return unity_settings_secret_agent_type_id__volatile;
382+}
plugins/Unity/IndicatorsLegacy/Network/secret-agent.hnew file+102
@@ -0,0 +1,102 @@
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+ * Alberto Ruiz <alberto.ruiz@canonical.com>
18+ * Renato Araujo Oliveira Filho <renato@canonical.com>
19+ */
20+
21+#ifndef __SECRET_AGENT_H__
22+#define __SECRET_AGENT_H__
23+
24+#include <glib.h>
25+#include <glib-object.h>
26+#include <nm-secret-agent.h>
27+
28+/*
29+ * This class is a basic implementation of the NetworkManager SecretAgent base class.
30+ *
31+ * The purpose of this class is to handle credential requests from the network,
32+ * for example, from a WiFi hotspot or a VPN network.
33+ *
34+ * It queues requests objects (SecretRequest) on a GQueue in the private struct
35+ * of the class. And notifies the consumer of the class through the "secret-request"
36+ * and the "request-cancelled" signals with the following callback prototypes:
37+ *
38+ * void (*secret_requested) (UnitySettingsSecretAgent *self,
39+ * guint id,
40+ * NMConnection *connection,
41+ * const char *setting_name,
42+ * const char **hints,
43+ * NMSecretAgentGetSecretsFlags flags,
44+ * gpointer user_data);
45+ *
46+ * void (*request_cancelled) (UnitySettingsSecretAgent *self,
47+ * guint id,
48+ * gpointer user_data);
49+ *
50+ */
51+
52+
53+G_BEGIN_DECLS
54+
55+
56+#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
57+#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
58+#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
59+#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
60+#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
61+#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
62+
63+#define UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED "secret-requested"
64+#define UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED "request-cancelled"
65+
66+typedef struct _UnitySettingsSecretAgent UnitySettingsSecretAgent;
67+typedef struct _UnitySettingsSecretAgentClass UnitySettingsSecretAgentClass;
68+typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
69+
70+struct _UnitySettingsSecretAgent {
71+ NMSecretAgent parent_instance;
72+ UnitySettingsSecretAgentPrivate * priv;
73+};
74+
75+struct _UnitySettingsSecretAgentClass {
76+ NMSecretAgentClass parent_class;
77+
78+ void (*secret_requested) (UnitySettingsSecretAgent *self,
79+ guint id,
80+ NMConnection *connection,
81+ const char *setting_name,
82+ const char **hints,
83+ NMSecretAgentGetSecretsFlags flags);
84+
85+ void (*request_cancelled) (UnitySettingsSecretAgent *self,
86+ guint id);
87+};
88+
89+
90+GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
91+UnitySettingsSecretAgent* unity_settings_secret_agent_new (void);
92+UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
93+
94+void unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
95+ guint request,
96+ GHashTable *secrets);
97+void unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
98+ guint request);
99+
100+G_END_DECLS
101+
102+#endif
plugins/Unity/Indicators/flatmenuproxymodel.cpp → plugins/Unity/IndicatorsLegacy/flatmenuproxymodel.cpprenamed+13
@@ -80,6 +80,19 @@ void FlatMenuProxyModel::setSourceModel(QAbstractItemModel *source)
80 SIGNAL(modelReset()),
80 SIGNAL(modelReset()),
81 SLOT(onModelReset()), Qt::QueuedConnection);
81 SLOT(onModelReset()), Qt::QueuedConnection);
82
82
83+ //Connection args
84+ connect(source,
85+ SIGNAL(busTypeChanged(DBusEnums::BusType)),
86+ SIGNAL(busTypeChanged()));
87+
88+ connect(source,
89+ SIGNAL(busNameChanged(const QString&)),
90+ SIGNAL(busNameChanged()));
91+
92+ connect(source,
93+ SIGNAL(objectPathChanged(const QString&)),
94+ SIGNAL(objectPathChanged()));
95+
83 connect(source,
96 connect(source,
84 SIGNAL(statusChanged(DBusEnums::ConnectionStatus)),
97 SIGNAL(statusChanged(DBusEnums::ConnectionStatus)),
85 SIGNAL(statusChanged()), Qt::QueuedConnection);
98 SIGNAL(statusChanged()), Qt::QueuedConnection);
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/IndicatorsLegacy/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 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/Launcher/backend/launcherbackend.cpp+1−1
@@ -101,7 +101,7 @@ bool LauncherBackend::isPinned(const QString &appId) const
101{
101{
102 // TODO: return app's pinned state from settings
102 // TODO: return app's pinned state from settings
103 Q_UNUSED(appId)
103 Q_UNUSED(appId)
104− return true;
104+ return false;
105}
105}
106
106
107void LauncherBackend::setPinned(const QString &appId, bool pinned)
107void LauncherBackend::setPinned(const QString &appId, bool pinned)
plugins/Unity/Launcher/common/quicklistentry.cpp+5
@@ -52,3 +52,8 @@ void QuickListEntry::setIcon(const QString &icon)
52{
52{
53 m_icon = icon;
53 m_icon = icon;
54}
54}
55+
56+bool QuickListEntry::clickable() const
57+{
58+ return !m_actionId.isEmpty();
59+}
plugins/Unity/Launcher/common/quicklistentry.h+2
@@ -35,6 +35,8 @@ public:
35 QString icon() const;
35 QString icon() const;
36 void setIcon(const QString &icon);
36 void setIcon(const QString &icon);
37
37
38+ bool clickable() const;
39+
38private:
40private:
39 QString m_actionId;
41 QString m_actionId;
40 QString m_text;
42 QString m_text;
plugins/Unity/Launcher/launcheritem.cpp+11−1
@@ -33,7 +33,13 @@ LauncherItem::LauncherItem(const QString &appId, const QString &desktopFile, con
33 m_count(0),
33 m_count(0),
34 m_quickList(new QuickListModel(this))
34 m_quickList(new QuickListModel(this))
35{
35{
36−
36+ QuickListEntry nameAction;
37+ nameAction.setText(m_name);
38+ m_quickList->appendAction(nameAction);
39+ QuickListEntry pinningAction;
40+ pinningAction.setActionId("pin_item");
41+ pinningAction.setText("Pin to Launcher");
42+ m_quickList->appendAction(pinningAction);
37}
43}
38
44
39QString LauncherItem::appId() const
45QString LauncherItem::appId() const
@@ -65,6 +71,10 @@ void LauncherItem::setPinned(bool pinned)
65{
71{
66 if (m_pinned != pinned) {
72 if (m_pinned != pinned) {
67 m_pinned = pinned;
73 m_pinned = pinned;
74+ QuickListEntry entry;
75+ entry.setActionId("pin_item");
76+ entry.setText(pinned ? "Remove from Launcher": "Pin to Launcher");
77+ m_quickList->updateAction(entry);
68 Q_EMIT pinnedChanged(pinned);
78 Q_EMIT pinnedChanged(pinned);
69 }
79 }
70}
80}
plugins/Unity/Launcher/launchermodel.cpp+34−4
@@ -82,8 +82,25 @@ unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) con
82
82
83void LauncherModel::move(int oldIndex, int newIndex)
83void LauncherModel::move(int oldIndex, int newIndex)
84{
84{
85− // Perform the move in our list
85+ // Make sure its not moved outside the lists
86+ if (newIndex < 0) {
87+ newIndex = 0;
88+ }
89+ if (newIndex >= m_list.count()) {
90+ newIndex = m_list.count()-1;
91+ }
92+
93+ // Nothing to do?
94+ if (oldIndex == newIndex) {
95+ return;
96+ }
97+
98+ // QList's and QAbstractItemModel's move implementation differ when moving an item up the list :/
99+ // While QList needs the index in the resulting list, beginMoveRows expects it to be in the current list
100+ // adjust the model's index by +1 in case we're moving upwards
101+ int newModelIndex = newIndex > oldIndex ? newIndex+1 : newIndex;
102+
86− beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
103+ beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newModelIndex);
87 m_list.move(oldIndex, newIndex);
104 m_list.move(oldIndex, newIndex);
88 endMoveRows();
105 endMoveRows();
89
106
@@ -140,10 +157,23 @@ void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex
140 return;
157 return;
141 }
158 }
142
159
160+ LauncherItem *item = m_list.at(index);
143− QuickListModel *model = qobject_cast<QuickListModel*>(m_list.at(index)->quickList());
161+ QuickListModel *model = qobject_cast<QuickListModel*>(item->quickList());
144 if (model) {
162 if (model) {
145 QString actionId = model->get(actionIndex).actionId();
163 QString actionId = model->get(actionIndex).actionId();
164+
165+ // Check if this is one of the launcher actions we handle ourselves
166+ if (actionId == "pin_item") {
167+ if (item->pinned()) {
168+ requestRemove(appId);
169+ } else {
170+ pin(appId);
171+ }
172+
173+ // Nope, we don't know this action, let the backend forward it to the application
174+ } else {
146− m_backend->triggerQuickListAction(appId, actionId);
175+ m_backend->triggerQuickListAction(appId, actionId);
176+ }
147 }
177 }
148}
178}
149
179
plugins/Unity/Launcher/plugin.cpp+2
@@ -41,7 +41,9 @@ void UnityLauncherPlugin::registerTypes(const char *uri)
41
41
42 qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated.");
42 qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated.");
43 qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated.");
43 qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated.");
44+ qmlRegisterUncreatableType<QuickListModelInterface>(uri, 0, 1, "QuickListInterface", "Abstract Interface. Cannot be instantiated.");
44
45
45 qmlRegisterSingletonType<LauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
46 qmlRegisterSingletonType<LauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
46 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create new Launcher Items in QML. Get them from the LauncherModel.");
47 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", "Can't create new Launcher Items in QML. Get them from the LauncherModel.");
48+ qmlRegisterUncreatableType<QuickListModel>(uri, 0, 1, "QuickListModel", "Can't create a QuickListModel in QML. Get them from the LauncherItems.");
47}
49}
plugins/Unity/Launcher/quicklistmodel.cpp+13
@@ -37,6 +37,17 @@ void QuickListModel::appendAction(const QuickListEntry &entry)
37 endInsertRows();
37 endInsertRows();
38}
38}
39
39
40+void QuickListModel::updateAction(const QuickListEntry &entry)
41+{
42+ for (int i = 0; i < m_list.count(); ++i) {
43+ if (m_list.at(i).actionId() == entry.actionId()) {
44+ m_list.replace(i, entry);
45+ Q_EMIT dataChanged(index(i), index(i));
46+ return;
47+ }
48+ }
49+}
50+
40QuickListEntry QuickListModel::get(int index) const
51QuickListEntry QuickListModel::get(int index) const
41{
52{
42 return m_list.at(index);
53 return m_list.at(index);
@@ -55,6 +66,8 @@ QVariant QuickListModel::data(const QModelIndex &index, int role) const
55 return m_list.at(index.row()).text();
66 return m_list.at(index.row()).text();
56 case RoleIcon:
67 case RoleIcon:
57 return m_list.at(index.row()).icon();
68 return m_list.at(index.row()).icon();
69+ case RoleClickable:
70+ return m_list.at(index.row()).clickable();
58 }
71 }
59 return QVariant();
72 return QVariant();
60}
73}
plugins/Unity/Launcher/quicklistmodel.h+10
@@ -36,6 +36,16 @@ public:
36 ~QuickListModel();
36 ~QuickListModel();
37
37
38 void appendAction(const QuickListEntry &entry);
38 void appendAction(const QuickListEntry &entry);
39+
40+ /**
41+ * @brief Update an existing action
42+ * @param entry The new, updated entry
43+ *
44+ * This will only do something if entry.actionId is found in the model.
45+ * To add a new entry, use appendAction().
46+ */
47+ void updateAction(const QuickListEntry &entry);
48+
39 QuickListEntry get(int index) const;
49 QuickListEntry get(int index) const;
40
50
41 int rowCount(const QModelIndex &parent = QModelIndex()) const;
51 int rowCount(const QModelIndex &parent = QModelIndex()) const;
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+72
@@ -39,6 +39,7 @@ Categories::Categories(QObject* parent)
39 m_roles[Categories::RoleIcon] = "icon";
39 m_roles[Categories::RoleIcon] = "icon";
40 m_roles[Categories::RoleRenderer] = "renderer";
40 m_roles[Categories::RoleRenderer] = "renderer";
41 m_roles[Categories::RoleContentType] = "contentType";
41 m_roles[Categories::RoleContentType] = "contentType";
42+ m_roles[Categories::RoleProgressSource] = "progressSource";
42 m_roles[Categories::RoleHints] = "hints";
43 m_roles[Categories::RoleHints] = "hints";
43 m_roles[Categories::RoleResults] = "results";
44 m_roles[Categories::RoleResults] = "results";
44 m_roles[Categories::RoleCount] = "count";
45 m_roles[Categories::RoleCount] = "count";
@@ -104,6 +105,25 @@ Categories::onCountChanged()
104 }
105 }
105}
106}
106
107
108+void Categories::onRowCountChanged()
109+{
110+ QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
111+ // find the corresponding category index
112+ for (auto iter = m_overriddenCategories.begin(); iter != m_overriddenCategories.end(); ++iter) {
113+ if (iter.value() == model) {
114+ for (int i = 0; i < rowCount(); i++) {
115+ auto id = data(index(i), RoleCategoryId).toString();
116+ if (id != iter.key()) continue;
117+ QVector<int> roles;
118+ roles.append(RoleCount);
119+ QModelIndex changedIndex = index(i);
120+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
121+ break;
122+ }
123+ }
124+ }
125+}
126+
107void
127void
108Categories::onEmitCountChanged()
128Categories::onEmitCountChanged()
109{
129{
@@ -123,6 +143,41 @@ Categories::roleNames() const
123 return m_roles;
143 return m_roles;
124}
144}
125
145
146+void Categories::onOverrideModelDestroyed()
147+{
148+ QObject* model = sender();
149+ auto iter = m_overriddenCategories.begin();
150+ while (iter != m_overriddenCategories.end()) {
151+ if (iter.value() == model) {
152+ iter = m_overriddenCategories.erase(iter);
153+ continue;
154+ }
155+ ++iter;
156+ }
157+}
158+
159+void Categories::overrideResults(const QString& categoryId, QAbstractItemModel* model)
160+{
161+ m_overriddenCategories[categoryId] = model;
162+ // watch the model
163+ connect(model, &QObject::destroyed, this, &Categories::onOverrideModelDestroyed);
164+ connect(model, &QAbstractItemModel::rowsInserted, this, &Categories::onRowCountChanged);
165+ connect(model, &QAbstractItemModel::rowsRemoved, this, &Categories::onRowCountChanged);
166+ connect(model, &QAbstractItemModel::modelReset, this, &Categories::onRowCountChanged);
167+
168+ // emit the dataChanged signal if the category is already in the model
169+ for (int i = 0; i < rowCount(); i++) {
170+ auto id = data(index(i), RoleCategoryId).toString();
171+ if (id != categoryId) continue;
172+ QVector<int> roles;
173+ roles.append(RoleCount);
174+ roles.append(RoleResults);
175+ QModelIndex changedIndex = index(i);
176+ Q_EMIT dataChanged(changedIndex, changedIndex, roles);
177+ break;
178+ }
179+}
180+
126QVariant
181QVariant
127Categories::data(const QModelIndex& index, int role) const
182Categories::data(const QModelIndex& index, int role) const
128{
183{
@@ -144,11 +199,28 @@ Categories::data(const QModelIndex& index, int role) const
144 auto hints = DeeListModel::data(index, CategoryColumn::HINTS).toHash();
199 auto hints = DeeListModel::data(index, CategoryColumn::HINTS).toHash();
145 return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
200 return hints.contains("content-type") ? hints["content-type"] : QVariant(QString("default"));
146 }
201 }
202+ case RoleProgressSource:
203+ {
204+ auto hints = DeeListModel::data(index, CategoryColumn::HINTS).toHash();
205+ return hints.contains("progress-source") ? hints["progress-source"] : QVariant();
206+ }
147 case RoleHints:
207 case RoleHints:
148 return DeeListModel::data(index, CategoryColumn::HINTS);
208 return DeeListModel::data(index, CategoryColumn::HINTS);
149 case RoleResults:
209 case RoleResults:
210+ if (m_overriddenCategories.size() > 0)
211+ {
212+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
213+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
214+ return QVariant::fromValue(m_overriddenCategories[id]);
215+ }
150 return QVariant::fromValue(getResults(index.row()));
216 return QVariant::fromValue(getResults(index.row()));
151 case RoleCount:
217 case RoleCount:
218+ if (m_overriddenCategories.size() > 0)
219+ {
220+ auto id = DeeListModel::data(index, CategoryColumn::ID).toString();
221+ if (m_overriddenCategories.find(id) != m_overriddenCategories.end())
222+ return QVariant::fromValue(m_overriddenCategories[id]->rowCount());
223+ }
152 return QVariant::fromValue(getResults(index.row())->rowCount());
224 return QVariant::fromValue(getResults(index.row())->rowCount());
153 case RoleCategoryIndex:
225 case RoleCategoryIndex:
154 return QVariant::fromValue(index.row());
226 return QVariant::fromValue(index.row());
plugins/Unity/categories.h+6
@@ -47,12 +47,15 @@ public:
47 RoleIcon,
47 RoleIcon,
48 RoleRenderer,
48 RoleRenderer,
49 RoleContentType,
49 RoleContentType,
50+ RoleProgressSource,
50 RoleHints,
51 RoleHints,
51 RoleResults,
52 RoleResults,
52 RoleCount,
53 RoleCount,
53 RoleCategoryIndex
54 RoleCategoryIndex
54 };
55 };
55
56
57+ Q_INVOKABLE void overrideResults(const QString& categoryId, QAbstractItemModel* model);
58+
56 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
59 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
57
60
58 QHash<int, QByteArray> roleNames() const;
61 QHash<int, QByteArray> roleNames() const;
@@ -62,7 +65,9 @@ public:
62
65
63private Q_SLOTS:
66private Q_SLOTS:
64 void onCountChanged();
67 void onCountChanged();
68+ void onRowCountChanged();
65 void onEmitCountChanged();
69 void onEmitCountChanged();
70+ void onOverrideModelDestroyed();
66
71
67private:
72private:
68 void onCategoriesModelChanged(unity::glib::Object<DeeModel> model);
73 void onCategoriesModelChanged(unity::glib::Object<DeeModel> model);
@@ -73,6 +78,7 @@ private:
73 QTimer m_timer;
78 QTimer m_timer;
74 QSet<int> m_updatedCategories;
79 QSet<int> m_updatedCategories;
75 QHash<int, QByteArray> m_roles;
80 QHash<int, QByteArray> m_roles;
81+ QMap<QString, QAbstractItemModel*> m_overriddenCategories;
76 mutable QMap<int, DeeListModel*> m_results;
82 mutable QMap<int, DeeListModel*> m_results;
77 sigc::connection m_categoriesChangedConnection;
83 sigc::connection m_categoriesChangedConnection;
78};
84};
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+165
@@ -0,0 +1,165 @@
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+#include "genericoptionsmodel.h"
27+
28+// Qt
29+#include <QDebug>
30+
31+Filters::Filters(unity::dash::Filters::Ptr unityFilters, QObject *parent) :
32+ QAbstractListModel(parent), m_unityFilters(unityFilters)
33+{
34+ for (unsigned int i=0; i<m_unityFilters->count(); i++) {
35+ unity::dash::Filter::Ptr unityFilter = m_unityFilters->FilterAtIndex(i);
36+ addFilter(unityFilter, i);
37+ }
38+ m_unityFilters->filter_added.connect(sigc::mem_fun(this, &Filters::onFilterAdded));
39+ m_unityFilters->filter_changed.connect(sigc::mem_fun(this, &Filters::onFilterChanged));
40+ m_unityFilters->filter_removed.connect(sigc::mem_fun(this, &Filters::onFilterRemoved));
41+}
42+
43+Filters::~Filters()
44+{
45+ while (!m_filters.isEmpty()) {
46+ delete m_filters.takeFirst();
47+ }
48+}
49+
50+int Filters::rowCount(const QModelIndex& parent) const
51+{
52+ Q_UNUSED(parent)
53+
54+ return m_unityFilters->count();
55+}
56+
57+QVariant Filters::data(const QModelIndex& index, int role) const
58+{
59+ if (!index.isValid()) {
60+ return QVariant();
61+ }
62+
63+ Filter* filter = m_filters.at(index.row());
64+ switch (role)
65+ {
66+ case Filters::RoleId:
67+ return filter->id();
68+ case Filters::RoleName:
69+ case Qt::DisplayRole:
70+ return filter->name();
71+ case Filters::RoleIconHint:
72+ return filter->iconHint();
73+ case Filters::RoleRendererName:
74+ return filter->rendererName();
75+ case Filters::RoleVisible:
76+ return filter->visible();
77+ case Filters::RoleCollapsed:
78+ return filter->collapsed();
79+ case Filters::RoleFiltering:
80+ return filter->filtering();
81+ case Filters::RoleOptions:
82+ return QVariant::fromValue(filter->options());
83+ default:
84+ break;
85+ }
86+ return QVariant();
87+}
88+
89+QHash<int, QByteArray> Filters::roleNames() const
90+{
91+ QHash<int, QByteArray> roles;
92+ roles[Filters::RoleId] = "id";
93+ roles[Filters::RoleName] = "name";
94+ roles[Filters::RoleIconHint] = "iconHint";
95+ roles[Filters::RoleRendererName] = "rendererName";
96+ roles[Filters::RoleVisible] = "visible";
97+ roles[Filters::RoleCollapsed] = "collapsed";
98+ roles[Filters::RoleFiltering] = "filtering";
99+ roles[Filters::RoleOptions] = "options";
100+ return roles;
101+}
102+
103+Filter* Filters::getFilter(const QString& id) const
104+{
105+ Q_FOREACH (Filter* filter, m_filters) {
106+ if (filter->id() == id) {
107+ return filter;
108+ }
109+ }
110+ return nullptr;
111+}
112+
113+void Filters::onFilterAdded(unity::dash::Filter::Ptr unityFilter)
114+{
115+ if (unityFilter == nullptr) {
116+ return;
117+ }
118+
119+ int index = m_filters.count();
120+ addFilter(unityFilter, index);
121+}
122+
123+void Filters::onFilterChanged(unity::dash::Filter::Ptr unityFilter)
124+{
125+ if (unityFilter == nullptr) {
126+ return;
127+ }
128+
129+ QModelIndex filterIndex = index(indexForFilter(unityFilter));
130+ Q_EMIT dataChanged(filterIndex, filterIndex);
131+}
132+
133+void Filters::onFilterRemoved(unity::dash::Filter::Ptr unityFilter)
134+{
135+ removeFilter(indexForFilter(unityFilter));
136+}
137+
138+void Filters::addFilter(unity::dash::Filter::Ptr unityFilter, int index)
139+{
140+ beginInsertRows(QModelIndex(), index, index);
141+ Filter* filter = Filter::newFromUnityFilter(unityFilter);
142+ if (filter != nullptr) {
143+ m_filters.insert(index, filter);
144+ }
145+ endInsertRows();
146+}
147+
148+void Filters::removeFilter(int index)
149+{
150+ beginRemoveRows(QModelIndex(), index, index);
151+ Filter* filter = m_filters.takeAt(index);
152+ delete filter;
153+ endRemoveRows();
154+}
155+
156+int Filters::indexForFilter(unity::dash::Filter::Ptr unityFilter)
157+{
158+ for (int index=0; index<m_filters.count(); index++) {
159+ if (m_filters[index]->hasUnityFilter(unityFilter)) {
160+ return index;
161+ }
162+ }
163+ qWarning() << "Filter" << QString::fromStdString(unityFilter->name()) << "not found in local cache.";
164+ return -1;
165+}
plugins/Unity/filters.hnew file+77
@@ -0,0 +1,77 @@
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+ RoleOptions
53+ };
54+
55+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
56+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
57+ QHash<int, QByteArray> roleNames() const override;
58+
59+ Filter* getFilter(const QString& id) const;
60+
61+private:
62+ void onFilterAdded(unity::dash::Filter::Ptr unityFilter);
63+ void onFilterChanged(unity::dash::Filter::Ptr unityFilter);
64+ void onFilterRemoved(unity::dash::Filter::Ptr unityFilter);
65+
66+ void addFilter(unity::dash::Filter::Ptr unityFilter, int index);
67+ void removeFilter(int index);
68+
69+ int indexForFilter(unity::dash::Filter::Ptr unityFilter);
70+
71+ unity::dash::Filters::Ptr m_unityFilters;
72+ QList<Filter*> m_filters;
73+};
74+
75+Q_DECLARE_METATYPE(Filters*)
76+
77+#endif // FILTERS_H
plugins/Unity/genericoptionsmodel.cppnew file+170
@@ -0,0 +1,170 @@
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+void GenericOptionsModel::setActive(QVector<AbstractFilterOption *>::size_type idx, bool value)
80+{
81+ if (idx < m_options.size())
82+ {
83+ m_options[idx]->setActive(value);
84+ }
85+}
86+
87+void GenericOptionsModel::setActive(const QString &id, bool value)
88+{
89+ Q_FOREACH(auto opt, m_options) {
90+ if (opt->id() == id) {
91+ opt->setActive(value);
92+ break;
93+ }
94+ }
95+}
96+
97+AbstractFilterOption* GenericOptionsModel::getRawOption(QVector<AbstractFilterOption *>::size_type idx) const
98+{
99+ if (idx < m_options.size())
100+ {
101+ return m_options[idx];
102+ }
103+ return nullptr;
104+}
105+
106+void GenericOptionsModel::ensureTheOnlyActive(AbstractFilterOption *activeOption)
107+{
108+ if (activeOption->active()) {
109+ // disable all other options
110+ Q_FOREACH(auto opt, m_options) {
111+ if (opt != activeOption && opt->active()) {
112+ opt->setActive(false);
113+ }
114+ }
115+ }
116+}
117+
118+void GenericOptionsModel::addOption(AbstractFilterOption *option, int index)
119+{
120+ m_options.insert(index, option);
121+
122+ connect(option, SIGNAL(idChanged(const QString &)), this, SLOT(onOptionChanged()));
123+ connect(option, SIGNAL(nameChanged(const QString &)), this, SLOT(onOptionChanged()));
124+ connect(option, SIGNAL(iconHintChanged(const QString &)), this, SLOT(onOptionChanged()));
125+ connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onOptionChanged()));
126+ connect(option, SIGNAL(activeChanged(bool)), this, SLOT(onActiveChanged()));
127+}
128+
129+void GenericOptionsModel::removeOption(int index)
130+{
131+ m_options[index]->deleteLater();
132+ m_options.remove(index);
133+}
134+
135+int GenericOptionsModel::indexOf(const QString &option_id)
136+{
137+ int row = 0;
138+ Q_FOREACH(auto opt, m_options)
139+ {
140+ if (opt->id() == option_id)
141+ {
142+ return row;
143+ }
144+ ++row;
145+ }
146+ return -1;
147+}
148+
149+void GenericOptionsModel::onOptionChanged()
150+{
151+ AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
152+ if (option)
153+ {
154+ int idx = indexOf(option->id());
155+ if (idx >= 0)
156+ {
157+ QModelIndex optionIndex = index(idx);
158+ Q_EMIT dataChanged(optionIndex, optionIndex);
159+ }
160+ }
161+}
162+
163+void GenericOptionsModel::onActiveChanged()
164+{
165+ AbstractFilterOption *option = dynamic_cast<AbstractFilterOption*>(QObject::sender());
166+ if (option)
167+ {
168+ Q_EMIT activeChanged(option);
169+ }
170+}
plugins/Unity/genericoptionsmodel.hnew file+77
@@ -0,0 +1,77 @@
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+ Q_INVOKABLE void setActive(QVector<AbstractFilterOption *>::size_type idx, bool value);
53+ Q_INVOKABLE void setActive(const QString &id, bool value);
54+
55+ AbstractFilterOption* getRawOption(QVector<AbstractFilterOption *>::size_type idx) const;
56+
57+public Q_SLOTS:
58+ virtual void ensureTheOnlyActive(AbstractFilterOption *activeOption);
59+
60+Q_SIGNALS:
61+ void activeChanged(AbstractFilterOption *option);
62+
63+protected Q_SLOTS:
64+ void onOptionChanged();
65+ void onActiveChanged();
66+
67+protected:
68+ void addOption(AbstractFilterOption *option, int index);
69+ void removeOption(int index);
70+ int indexOf(const QString &option_id);
71+
72+ QVector<AbstractFilterOption *> m_options;
73+};
74+
75+Q_DECLARE_METATYPE(GenericOptionsModel*)
76+
77+#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+30−11
@@ -35,9 +35,10 @@
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
39−Scope::Scope(QObject *parent) :
40+Scope::Scope(QObject *parent) : QObject(parent)
40− QObject(parent)
41+ , m_formFactor("phone")
41{
42{
42 m_categories.reset(new Categories(this));
43 m_categories.reset(new Categories(this));
43}
44}
@@ -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
@@ -128,6 +134,7 @@ void Scope::setFormFactor(const QString& form_factor) {
128 m_formFactor = form_factor;
134 m_formFactor = form_factor;
129 if (m_unityScope) {
135 if (m_unityScope) {
130 m_unityScope->form_factor = m_formFactor.toStdString();
136 m_unityScope->form_factor = m_formFactor.toStdString();
137+ synchronizeStates(); // will trigger a re-search
131 }
138 }
132 Q_EMIT formFactorChanged();
139 Q_EMIT formFactorChanged();
133 }
140 }
@@ -208,18 +215,11 @@ void Scope::onPreviewReady(unity::dash::LocalResult const& /* result */, unity::
208
215
209void Scope::fallbackActivate(const QString& uri)
216void Scope::fallbackActivate(const QString& uri)
210{
217{
211− /* FIXME: stripping all content before the first column because for some
212− reason the scopes give uri with junk content at their beginning.
213− */
214− QString tweakedUri = uri;
215− int firstColumnAt = tweakedUri.indexOf(":");
216− tweakedUri.remove(0, firstColumnAt+1);
217−
218 /* 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'.
219 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
220 Qt to open the uri.
220 Qt to open the uri.
221 */
221 */
222− QUrl url(tweakedUri);
222+ QUrl url(uri);
223 if (url.scheme() == "file") {
223 if (url.scheme() == "file") {
224 /* 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
225 manager to handle opening folders, not the dash.
225 manager to handle opening folders, not the dash.
@@ -230,7 +230,25 @@ void Scope::fallbackActivate(const QString& uri)
230 return;
230 return;
231 }
231 }
232 if (url.scheme() == "application") {
232 if (url.scheme() == "application") {
233− // 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+ }
234 return;
252 return;
235 }
253 }
236
254
@@ -245,6 +263,7 @@ void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
245 m_unityScope = scope;
263 m_unityScope = scope;
246
264
247 m_categories->setUnityScope(m_unityScope);
265 m_categories->setUnityScope(m_unityScope);
266+ m_filters.reset(new Filters(m_unityScope->filters, this));
248
267
249 m_unityScope->form_factor = m_formFactor.toStdString();
268 m_unityScope->form_factor = m_formFactor.toStdString();
250 /* 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/qlimitproxymodelqml.cpp+90−4
@@ -25,6 +25,8 @@ QLimitProxyModelQML::QLimitProxyModelQML(QObject *parent)
25 , m_limit(-1)
25 , m_limit(-1)
26 , m_sourceInserting(false)
26 , m_sourceInserting(false)
27 , m_sourceRemoving(false)
27 , m_sourceRemoving(false)
28+ , m_dataChangedBegin(-1)
29+ , m_dataChangedEnd(-1)
28{
30{
29 connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
31 connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
30 connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
32 connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
@@ -130,8 +132,45 @@ QLimitProxyModelQML::sourceRowsAboutToBeInserted(const QModelIndex &parent, int
130 beginInsertRows(mapFromSource(parent), start, end);
132 beginInsertRows(mapFromSource(parent), start, end);
131 m_sourceInserting = true;
133 m_sourceInserting = true;
132 } else if (start < m_limit) {
134 } else if (start < m_limit) {
135+ const int nSourceAddedItems = end - start + 1;
136+ const int currentCount = QIdentityProxyModel::rowCount();
137+ if (currentCount + nSourceAddedItems <= m_limit) {
138+ // After Inserting items we will be under the limit
139+ // so just proceed with the insertion normally
133− beginInsertRows(mapFromSource(parent), start, qMin(m_limit - 1, end));
140+ beginInsertRows(mapFromSource(parent), start, end);
141+ m_sourceInserting = true;
142+ } else if (currentCount >= m_limit) {
143+ // We are already over the limit so to our users we are not adding items, just
144+ // changing it's data, i.e we had something like
145+ // A B C D E
146+ // with a limit of 5
147+ // after inserting (let's say three 'F' at position 1) we will have
148+ // A F F F B
149+ // so we just need to signal a dataChanged from 1 to 4
150+ m_dataChangedBegin = start;
151+ m_dataChangedEnd = m_limit - 1;
152+ } else { // currentCount < m_limit && currentCount + nSourceAddedItems > m_limit
153+ // We have less items than the limit but after adding them we will be over
154+ // To our users this means we need to insert some items and change the
155+ // data of some others, i.e we had something like
156+ // A B C
157+ // with a limit of 5
158+ // after inserting (let's say three 'F' at position 1) we will have
159+ // A F F F B
160+ // so we need to signal an insetion from position 1 to 2, instead of from
161+ // position 1 to 3 and a after that a data changed from 3 to 4
162+ const int nItemsToInsert = m_limit - currentCount;
163+ beginInsertRows(mapFromSource(parent), start, start + nItemsToInsert - 1);
134− m_sourceInserting = true;
164+ m_sourceInserting = true;
165+ m_dataChangedBegin = start + nItemsToInsert;
166+ m_dataChangedEnd = m_limit - 1;
167+ if (m_dataChangedBegin > m_dataChangedEnd) {
168+ // Just in case we were empty and insert 6 items with a limit of 5
169+ // We don't want to signal a dataChanged from 5 to 4
170+ m_dataChangedBegin = -1;
171+ m_dataChangedEnd = -1;
172+ }
173+ }
135 }
174 }
136}
175}
137
176
@@ -142,8 +181,45 @@ QLimitProxyModelQML::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int s
142 beginRemoveRows(mapFromSource(parent), start, end);
181 beginRemoveRows(mapFromSource(parent), start, end);
143 m_sourceRemoving = true;
182 m_sourceRemoving = true;
144 } else if (start < m_limit) {
183 } else if (start < m_limit) {
184+ const int nSourceRemovedItems = end - start + 1;
185+ const int currentCount = QIdentityProxyModel::rowCount();
186+ if (currentCount <= m_limit) {
187+ // We are already under the limit so
188+ // so just proceed with the removal normally
145− beginRemoveRows(mapFromSource(parent), start, qMin(m_limit - 1, end));
189+ beginRemoveRows(mapFromSource(parent), start, end);
190+ m_sourceRemoving = true;
191+ } else if (currentCount - nSourceRemovedItems >= m_limit) {
192+ // Even after removing items we will be at or over the limit
193+ // So to our users we are not removing anything, just changing the data
194+ // i.e. we had a internal model with
195+ // A B C D E F G H
196+ // and a limit of 5, our users just see
197+ // A B C D E
198+ // so if we remove 3 items starting at 1 we have to expose
199+ // A E F G H
200+ // that is, a dataChanged from 1 to 4
201+ m_dataChangedBegin = start;
202+ m_dataChangedEnd = m_limit - 1;
203+ } else { // currentCount > m_limit && currentCount - nSourceRemovedItems < m_limit
204+ // We have more items than the limit but after removing we will be below it
205+ // So to our users we both removing and changing the data
206+ // i.e. we had a internal model with
207+ // A B C D E F G
208+ // and a limit of 5, our users just see
209+ // A B C D E
210+ // so if we remove items from 1 to 3 we have to expose
211+ // A E F G
212+ // that is, a remove from 4 to 4 and a dataChanged from 1 to 3
213+ const int nItemsToRemove = m_limit - (currentCount - nSourceRemovedItems);
214+ beginRemoveRows(mapFromSource(parent), m_limit - nItemsToRemove, m_limit - 1);
146− m_sourceRemoving = true;
215+ m_sourceRemoving = true;
216+ m_dataChangedBegin = start;
217+ m_dataChangedEnd = m_limit - nItemsToRemove - 1;
218+ if (m_dataChangedBegin > m_dataChangedEnd) {
219+ m_dataChangedBegin = -1;
220+ m_dataChangedEnd = -1;
221+ }
222+ }
147 }
223 }
148}
224}
149
225
@@ -154,6 +230,11 @@ QLimitProxyModelQML::sourceRowsInserted(const QModelIndex & /*parent*/, int /*st
154 endInsertRows();
230 endInsertRows();
155 m_sourceInserting = false;
231 m_sourceInserting = false;
156 }
232 }
233+ if (m_dataChangedBegin != -1 && m_dataChangedEnd != -1) {
234+ dataChanged(index(m_dataChangedBegin, 0), index(m_dataChangedEnd, 0));
235+ m_dataChangedBegin = -1;
236+ m_dataChangedEnd = -1;
237+ }
157}
238}
158
239
159void
240void
@@ -163,4 +244,9 @@ QLimitProxyModelQML::sourceRowsRemoved(const QModelIndex & /*parent*/, int /*sta
163 endRemoveRows();
244 endRemoveRows();
164 m_sourceRemoving = false;
245 m_sourceRemoving = false;
165 }
246 }
247+ if (m_dataChangedBegin != -1 && m_dataChangedEnd != -1) {
248+ dataChanged(index(m_dataChangedBegin, 0), index(m_dataChangedEnd, 0));
249+ m_dataChangedBegin = -1;
250+ m_dataChangedEnd = -1;
251+ }
166}
252}
plugins/Utils/qlimitproxymodelqml.h+2
@@ -55,6 +55,8 @@ private:
55 int m_limit;
55 int m_limit;
56 bool m_sourceInserting;
56 bool m_sourceInserting;
57 bool m_sourceRemoving;
57 bool m_sourceRemoving;
58+ int m_dataChangedBegin;
59+ int m_dataChangedEnd;
58};
60};
59
61
60#endif // QLIMITPROXYMODELQML_H
62#endif // QLIMITPROXYMODELQML_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+54−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr "ويكيبيديا"
85msgid "YouTube"
87msgid "YouTube"
86msgstr "يوتيوب"
88msgstr "يوتيوب"
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 "البرامج المُشغّلة"
@@ -105,23 +141,23 @@ msgstr "مُثبّتة"
105msgid "Available for download"
141msgid "Available for download"
106msgstr "متوفرة للتنزيل"
142msgstr "متوفرة للتنزيل"
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "تطبيقات"
146msgstr "تطبيقات"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr "تطبيقات مألوفة"
150msgstr "تطبيقات مألوفة"
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr "آخر الصوتيات المشغلة"
154msgstr "آخر الصوتيات المشغلة"
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr "فيديوهات رائجة على الإنترنت"
158msgstr "فيديوهات رائجة على الإنترنت"
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "الرئيسية"
162msgstr "الرئيسية"
127
163
@@ -141,7 +177,7 @@ msgstr "الإصدارات الجديدة"
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr ""
178msgstr ""
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "موسيقى"
182msgstr "موسيقى"
147
183
@@ -149,25 +185,25 @@ msgstr "موسيقى"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr "الشائع على الإنترنت"
186msgstr "الشائع على الإنترنت"
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170−msgstr "مكالمة طوارئ"
206+msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
209#, qt-format
@@ -198,23 +234,15 @@ msgstr "تكلم الآن..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "تتكلم الآن..."
235msgstr "تتكلم الآن..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "الجهاز"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "نمط الطيران"
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "ابحث"
239msgstr "ابحث"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "عذراً، لا يوجد ما يطابق بحثك."
243msgstr "عذراً، لا يوجد ما يطابق بحثك."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr ""
248msgstr ""
po/az.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Tətbiqlər"
145msgstr "Tətbiqlər"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Ev"
161msgstr "Ev"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Musiqi"
181msgstr "Musiqi"
147
182
@@ -149,24 +184,24 @@ msgstr "Musiqi"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Söyləyin..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Söylənilir..."
234msgstr "Söylənilir..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Axtar"
238msgstr "Axtar"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
242msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/bg.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -86,10 +87,44 @@ msgstr "Уикипедия"
86msgid "YouTube"
87msgid "YouTube"
87msgstr "YouTube"
88msgstr "YouTube"
88
89
89−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 ""
@@ -106,23 +141,23 @@ msgstr "Инсталирани"
106msgid "Available for download"
141msgid "Available for download"
107msgstr ""
142msgstr ""
108
143
109−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
110msgid "Apps"
145msgid "Apps"
111msgstr "Приложения"
146msgstr "Приложения"
112
147
113−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
114msgid "Frequent Apps"
149msgid "Frequent Apps"
115msgstr ""
150msgstr ""
116
151
117−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
118msgid "Recent Music"
153msgid "Recent Music"
119msgstr ""
154msgstr ""
120
155
121−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
122msgid "Videos Popular Online"
157msgid "Videos Popular Online"
123msgstr ""
158msgstr ""
124
159
125−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
126msgid "Home"
161msgid "Home"
127msgstr "Начало"
162msgstr "Начало"
128
163
@@ -142,7 +177,7 @@ msgstr ""
142msgid "Top Charting"
177msgid "Top Charting"
143msgstr ""
178msgstr ""
144
179
145−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
146msgid "Music"
181msgid "Music"
147msgstr "Музика"
182msgstr "Музика"
148
183
@@ -150,24 +185,24 @@ msgstr "Музика"
150msgid "Popular Online"
185msgid "Popular Online"
151msgstr ""
186msgstr ""
152
187
153−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
169#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
170−msgid "Emergency call"
205+msgid "Emergency Call"
171msgstr ""
206msgstr ""
172
207
173#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
@@ -199,23 +234,15 @@ msgstr ""
199msgid "Speaking..."
234msgid "Speaking..."
200msgstr ""
235msgstr ""
201
236
202−#: Panel/MenuContent.qml:192
203−msgid "Device"
204−msgstr "Устройство"
205−
206−#: Panel/Menus/Overview/FlightModeWidget.qml:42
207−msgid "Flight mode"
208−msgstr ""
209−
210−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
211msgid "Search"
238msgid "Search"
212msgstr "Търсене"
239msgstr "Търсене"
213
240
214−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
215msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
216msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
243msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
217
244
218−#: Shell.qml:383
245+#: Shell.qml:399
219#, qt-format
246#, qt-format
220msgid "Please enter %1"
247msgid "Please enter %1"
221msgstr ""
248msgstr ""
po/ca.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Instal·lades"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Disponibles per baixar"
141msgstr "Disponibles per baixar"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Aplicacions"
145msgstr "Aplicacions"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Aplicacions freqüents"
149msgstr "Aplicacions freqüents"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Música recent"
153msgstr "Música recent"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Vídeos populars en línia"
157msgstr "Vídeos populars en línia"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Inici"
161msgstr "Inici"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Música"
181msgstr "Música"
147
182
@@ -149,24 +184,24 @@ msgstr "Música"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Parleu..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "S'està parlant..."
234msgstr "S'està parlant..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Dispositiu"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Mode d'avió"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Cerca"
238msgstr "Cerca"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "No hi ha res que coincideixi amb la cerca"
242msgstr "No hi ha res que coincideixi amb la cerca"
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/de.po+53−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "Wikipedia"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Installiert"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Zum Herunterladen verfügbar"
141msgstr "Zum Herunterladen verfügbar"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Anwendungen"
145msgstr "Anwendungen"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Häufig genutzte Anwendungen"
149msgstr "Häufig genutzte Anwendungen"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Zuletzt gehörte Musik"
153msgstr "Zuletzt gehörte Musik"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Beliebte Online-Videos"
157msgstr "Beliebte Online-Videos"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Start"
161msgstr "Start"
127
162
@@ -141,7 +176,7 @@ msgstr "Neue Veröffentlichungen"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr "Top Tabellenplatz"
177msgstr "Top Tabellenplatz"
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Musik"
181msgstr "Musik"
147
182
@@ -149,25 +184,25 @@ msgstr "Musik"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "Online Beliebt"
185msgstr "Online Beliebt"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr "Notruf"
205+msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
@@ -198,23 +233,15 @@ msgstr "Sprechen Sie jetzt …"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Sie sprechen …"
234msgstr "Sie sprechen …"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Gerät"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Flugmodus"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Suchen"
238msgstr "Suchen"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Entschuldigung, es wurden keine Treffer erzielt."
242msgstr "Entschuldigung, es wurden keine Treffer erzielt."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/el.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Εφαρμογές"
145msgstr "Εφαρμογές"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Αρχή"
161msgstr "Αρχή"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Μουσική"
181msgstr "Μουσική"
147
182
@@ -149,24 +184,24 @@ msgstr "Μουσική"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Μιλήστε τώρα..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Ομιλία..."
234msgstr "Ομιλία..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Αναζήτηση"
238msgstr "Αναζήτηση"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
242msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/en_AU.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "Wikipedia"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Installed"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Available for download"
141msgstr "Available for download"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Apps"
145msgstr "Apps"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Frequent Apps"
149msgstr "Frequent Apps"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Recent Music"
153msgstr "Recent Music"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Videos Popular Online"
157msgstr "Videos Popular Online"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Home"
161msgstr "Home"
127
162
@@ -141,7 +176,7 @@ msgstr "New Releases"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr "Top Charting"
177msgstr "Top Charting"
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Music"
181msgstr "Music"
147
182
@@ -149,24 +184,24 @@ msgstr "Music"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "Popular Online"
185msgstr "Popular Online"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Speak Now..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Speaking..."
234msgstr "Speaking..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Device"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Flight mode"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Search"
238msgstr "Search"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Sorry, there is nothing that matches your search."
242msgstr "Sorry, there is nothing that matches your search."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/en_GB.po+53−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "Wikipedia"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Installed"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Available for download"
141msgstr "Available for download"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Apps"
145msgstr "Apps"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Frequent Apps"
149msgstr "Frequent Apps"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Recent Music"
153msgstr "Recent Music"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Videos Popular Online"
157msgstr "Videos Popular Online"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Home"
161msgstr "Home"
127
162
@@ -141,7 +176,7 @@ msgstr "New Releases"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr "Top Charting"
177msgstr "Top Charting"
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Music"
181msgstr "Music"
147
182
@@ -149,25 +184,25 @@ msgstr "Music"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "Popular Online"
185msgstr "Popular Online"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr "Emergency call"
205+msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
@@ -198,23 +233,15 @@ msgstr "Speak Now..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Speaking..."
234msgstr "Speaking..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Device"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Flight mode"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Search"
238msgstr "Search"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Sorry, there is nothing that matches your search."
242msgstr "Sorry, there is nothing that matches your search."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr "Please enter %1"
247msgstr "Please enter %1"
po/eo.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr ""
181msgstr ""
147
182
@@ -149,24 +184,24 @@ msgstr ""
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/es.po+53−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "Wikipedia"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Instaladas"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Disponibles para descargar"
141msgstr "Disponibles para descargar"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Aplicaciones"
145msgstr "Aplicaciones"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Aplicaciones frecuentes"
149msgstr "Aplicaciones frecuentes"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Música reciente"
153msgstr "Música reciente"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Vídeos populares en línea"
157msgstr "Vídeos populares en línea"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Inicio"
161msgstr "Inicio"
127
162
@@ -141,7 +176,7 @@ msgstr "Lanzamientos nuevos"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr "Mejor posicionadas"
177msgstr "Mejor posicionadas"
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Música"
181msgstr "Música"
147
182
@@ -149,25 +184,25 @@ msgstr "Música"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "Populares en línea"
185msgstr "Populares en línea"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr "Llamada de emergencia"
205+msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
@@ -198,23 +233,15 @@ msgstr "Hable ahora…"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Hablando…"
234msgstr "Hablando…"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Dispositivo"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Modo de vuelo"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Buscar"
238msgstr "Buscar"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "No hay nada que coincida con su búsqueda."
242msgstr "No hay nada que coincida con su búsqueda."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr "Introduzca %1"
247msgstr "Introduzca %1"
po/fi.po+59−32
@@ -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-06-26 22:58+0200\n"
10+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
11−"PO-Revision-Date: 2013-06-27 02:43+0000\n"
11+"PO-Revision-Date: 2013-08-12 17:45+0000\n"
12−"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "Wikipedia"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Asennetut"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Ladattavissa"
141msgstr "Ladattavissa"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Sovellukset"
145msgstr "Sovellukset"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Yleisimmät sovellukset"
149msgstr "Yleisimmät sovellukset"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Viimeisin musiikki"
153msgstr "Viimeisin musiikki"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Suositut verkkovideot"
157msgstr "Suositut verkkovideot"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Kotinäyttö"
161msgstr "Kotinäyttö"
127
162
@@ -141,7 +176,7 @@ msgstr "Uudet julkaisut"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr "Nousukiidossa"
177msgstr "Nousukiidossa"
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Musiikki"
181msgstr "Musiikki"
147
182
@@ -149,34 +184,34 @@ msgstr "Musiikki"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "Suosittua verkossa"
185msgstr "Suosittua verkossa"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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:"
166−msgstr "Laatinut:"
201+msgstr "Tekijä:"
167
202
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr ""
205+msgstr "Hätäpuhelu"
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
174msgid "Hello %1"
209msgid "Hello %1"
175−msgstr ""
210+msgstr "Hei %1!"
176
211
177#: Greeter/PassphraseLockscreen.qml:59
212#: Greeter/PassphraseLockscreen.qml:59
178msgid "Hello"
213msgid "Hello"
179−msgstr ""
214+msgstr "Hei"
180
215
181#: Hud/HudParametrizedActionsPage.qml:132
216#: Hud/HudParametrizedActionsPage.qml:132
182msgid "Confirm"
217msgid "Confirm"
@@ -188,7 +223,7 @@ msgstr "Kirjoita tai sano komento"
188
223
189#: Hud/Hud.qml:84
224#: Hud/Hud.qml:84
190msgid "Loading. Please Wait..."
225msgid "Loading. Please Wait..."
191−msgstr "Ladataan, odota hetki..."
226+msgstr "Ladataan, pieni hetki..."
192
227
193#: Hud/Hud.qml:89
228#: Hud/Hud.qml:89
194msgid "Speak Now..."
229msgid "Speak Now..."
@@ -198,23 +233,15 @@ msgstr "Puhu nyt..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Puhutaan..."
234msgstr "Puhutaan..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Laite"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Lentokonetila"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Hae"
238msgstr "Hae"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Hakuun täsmääviä tuloksia ei löydy."
242msgstr "Hakuun täsmääviä tuloksia ei löydy."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/fo.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Nýtsluskipanir"
145msgstr "Nýtsluskipanir"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Heim"
161msgstr "Heim"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Tónleikur"
181msgstr "Tónleikur"
147
182
@@ -149,24 +184,24 @@ msgstr "Tónleikur"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Snakka nú..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Snakkar..."
234msgstr "Snakkar..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Leita"
238msgstr "Leita"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
242msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/fr.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Applications"
145msgstr "Applications"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Musique"
181msgstr "Musique"
147
182
@@ -149,24 +184,24 @@ msgstr "Musique"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/gl.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Instalado"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Dispoñíbel para descargar"
141msgstr "Dispoñíbel para descargar"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Aplicativos"
145msgstr "Aplicativos"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Aplicativos frecuentes"
149msgstr "Aplicativos frecuentes"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Música recente"
153msgstr "Música recente"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Vídeos populares en liña"
157msgstr "Vídeos populares en liña"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Cartafol persoal"
161msgstr "Cartafol persoal"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Música"
181msgstr "Música"
147
182
@@ -149,24 +184,24 @@ msgstr "Música"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Fale agora…"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Falando…"
234msgstr "Falando…"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Dispositivo"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Modo de voo"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Buscar"
238msgstr "Buscar"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Sentímolo, non hai nada que coincida con esta busca."
242msgstr "Sentímolo, non hai nada que coincida con esta busca."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/he.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "יישומים"
145msgstr "יישומים"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "בית"
161msgstr "בית"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "מוזיקה"
181msgstr "מוזיקה"
147
182
@@ -149,24 +184,24 @@ msgstr "מוזיקה"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "יש לדבר כעת..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "מושמע דיבור..."
234msgstr "מושמע דיבור..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "חיפוש"
238msgstr "חיפוש"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
242msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/hr.po+53−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr ""
85msgid "YouTube"
87msgid "YouTube"
86msgstr ""
88msgstr ""
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +141,23 @@ msgstr ""
105msgid "Available for download"
141msgid "Available for download"
106msgstr ""
142msgstr ""
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Aplikacije"
146msgstr "Aplikacije"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr ""
150msgstr ""
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr ""
154msgstr ""
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr ""
158msgstr ""
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Početna"
162msgstr "Početna"
127
163
@@ -141,7 +177,7 @@ msgstr ""
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr ""
178msgstr ""
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Glazba"
182msgstr "Glazba"
147
183
@@ -149,24 +185,24 @@ msgstr "Glazba"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr ""
186msgstr ""
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170msgstr ""
206msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +234,15 @@ msgstr "Recite..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Govor..."
235msgstr "Govor..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Pretraživanje"
239msgstr "Pretraživanje"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
243msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr ""
248msgstr ""
po/hu.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Telepített"
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Alkalmazások"
145msgstr "Alkalmazások"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Kezdőoldal"
161msgstr "Kezdőoldal"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Zene"
181msgstr "Zene"
147
182
@@ -149,24 +184,24 @@ msgstr "Zene"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Beszéljen most…"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Beszéd…"
234msgstr "Beszéd…"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Eszköz"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Keresés"
238msgstr "Keresés"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Elnézést, nincs találat a keresésre."
242msgstr "Elnézést, nincs találat a keresésre."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/hy.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 "Բացած ծրագրեր"
@@ -105,23 +140,23 @@ msgstr "Տեղադրված"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Հասանելի ծրագրեր"
141msgstr "Հասանելի ծրագրեր"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Ծրագրեր"
145msgstr "Ծրագրեր"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Հաճախակի ծրագրերը"
149msgstr "Հաճախակի ծրագրերը"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "Վերջին երգերը"
153msgstr "Վերջին երգերը"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Հայտնի օնլայն վիդեոներ"
157msgstr "Հայտնի օնլայն վիդեոներ"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Տուն"
161msgstr "Տուն"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Երգեր"
181msgstr "Երգեր"
147
182
@@ -149,24 +184,24 @@ msgstr "Երգեր"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Խոսի՛ր"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Խոսում եմ..."
234msgstr "Խոսում եմ..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Սարք"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Անկապ րեժիմ"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Որոնում"
238msgstr "Որոնում"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
242msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/id.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr ""
181msgstr ""
147
182
@@ -149,24 +184,24 @@ msgstr ""
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/it.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Applicazioni"
145msgstr "Applicazioni"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Home"
161msgstr "Home"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Musica"
181msgstr "Musica"
147
182
@@ -149,24 +184,24 @@ msgstr "Musica"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Parla ora..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Sto parlando..."
234msgstr "Sto parlando..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Cerca"
238msgstr "Cerca"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Nessun risultato corrispondente alla ricerca."
242msgstr "Nessun risultato corrispondente alla ricerca."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/ja.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr ""
181msgstr ""
147
182
@@ -149,24 +184,24 @@ msgstr ""
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/kn.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"
145msgstr "ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "ಮನೆ (Home)"
161msgstr "ಮನೆ (Home)"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "ಸಂಗೀತ"
181msgstr "ಸಂಗೀತ"
147
182
@@ -149,24 +184,24 @@ msgstr "ಸಂಗೀತ"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "ಈಗ ಮಾತನಾಡಿ ..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "ಮಾತನಾಡುತಿದ್ದೀರಿ"
234msgstr "ಮಾತನಾಡುತಿದ್ದೀರಿ"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "ಹುಡುಕು"
238msgstr "ಹುಡುಕು"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
242msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/ko.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 "돌아가고 있는 앱"
@@ -105,23 +140,23 @@ msgstr "깔림"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "내려받을 수 있음"
141msgstr "내려받을 수 있음"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "앱"
145msgstr "앱"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "자주 쓰는 앱"
149msgstr "자주 쓰는 앱"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "요즈음 찾는 음악"
153msgstr "요즈음 찾는 음악"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "음악"
181msgstr "음악"
147
182
@@ -149,24 +184,24 @@ msgstr "음악"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "찾기"
238msgstr "찾기"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/ky.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Тиркемелер"
145msgstr "Тиркемелер"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Үй папкасы"
161msgstr "Үй папкасы"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Музыка"
181msgstr "Музыка"
147
182
@@ -149,24 +184,24 @@ msgstr "Музыка"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Азыр сүйлөңүз..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Сүйлөнүүдө..."
234msgstr "Сүйлөнүүдө..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Издөө"
238msgstr "Издөө"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
242msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/lv.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Lietotnes"
145msgstr "Lietotnes"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Mājas"
161msgstr "Mājas"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Mūzika"
181msgstr "Mūzika"
147
182
@@ -149,24 +184,24 @@ msgstr "Mūzika"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Runajiet Tagad"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Runa..."
234msgstr "Runa..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Meklēt"
238msgstr "Meklēt"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
242msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/my.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Apps"
145msgstr "Apps"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "ပင်မ"
161msgstr "ပင်မ"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "တေးဂီတ"
181msgstr "တေးဂီတ"
147
182
@@ -149,24 +184,24 @@ msgstr "တေးဂီတ"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "ယခုပြောပါ"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "ပြောနေသည်"
234msgstr "ပြောနေသည်"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "ရှာဖွေ"
238msgstr "ရှာဖွေ"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
242msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/nb.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr "Installert"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "Tilgjengelig for nedlasting"
141msgstr "Tilgjengelig for nedlasting"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Programmer"
145msgstr "Programmer"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Hjem"
161msgstr "Hjem"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Musikk"
181msgstr "Musikk"
147
182
@@ -149,24 +184,24 @@ msgstr "Musikk"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Snakk nå …"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Snakker …"
234msgstr "Snakker …"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Enhet"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Flymodus"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Søk"
238msgstr "Søk"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Søket ga ingen treff."
242msgstr "Søket ga ingen treff."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/nl.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Apps"
145msgstr "Apps"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Hoofdvenster"
161msgstr "Hoofdvenster"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Muziek"
181msgstr "Muziek"
147
182
@@ -149,24 +184,24 @@ msgstr "Muziek"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Nu inspreken…"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Inspreken…"
234msgstr "Inspreken…"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Zoeken"
238msgstr "Zoeken"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
242msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/pl.po+54−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr "Wikipedia"
85msgid "YouTube"
87msgid "YouTube"
86msgstr "YouTube"
88msgstr "YouTube"
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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"
@@ -105,23 +141,23 @@ msgstr "Zainstalowane"
105msgid "Available for download"
141msgid "Available for download"
106msgstr "Dostępne do pobrania"
142msgstr "Dostępne do pobrania"
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Aplikacje"
146msgstr "Aplikacje"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr "Często używane aplikacje"
150msgstr "Często używane aplikacje"
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr "Najnowsza muzyka"
154msgstr "Najnowsza muzyka"
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr "Wideo popularne online"
158msgstr "Wideo popularne online"
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Dom"
162msgstr "Dom"
127
163
@@ -141,7 +177,7 @@ msgstr "Premiery"
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr "Przeboje"
178msgstr "Przeboje"
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Muzyka"
182msgstr "Muzyka"
147
183
@@ -149,25 +185,25 @@ msgstr "Muzyka"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr "Popularne w sieci"
186msgstr "Popularne w sieci"
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170−msgstr "Telefon alarmowy"
206+msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
209#, qt-format
@@ -198,23 +234,15 @@ msgstr "Mów teraz..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Rozpoznanie..."
235msgstr "Rozpoznanie..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Urządzenie"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Tryb samolotowy"
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Szukaj"
239msgstr "Szukaj"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "Nie znaleziono pasujących wyników."
243msgstr "Nie znaleziono pasujących wyników."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr "Wprowadź %1"
248msgstr "Wprowadź %1"
po/pt_BR.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Aplicativos"
145msgstr "Aplicativos"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Início"
161msgstr "Início"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Músicas"
181msgstr "Músicas"
147
182
@@ -149,24 +184,24 @@ msgstr "Músicas"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "Fale agora..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Falando..."
234msgstr "Falando..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Pesquisar"
238msgstr "Pesquisar"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
242msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/ro.po+53−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr ""
85msgid "YouTube"
87msgid "YouTube"
86msgstr ""
88msgstr ""
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +141,23 @@ msgstr ""
105msgid "Available for download"
141msgid "Available for download"
106msgstr ""
142msgstr ""
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Aplicații"
146msgstr "Aplicații"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr ""
150msgstr ""
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr ""
154msgstr ""
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr ""
158msgstr ""
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Acasă"
162msgstr "Acasă"
127
163
@@ -141,7 +177,7 @@ msgstr ""
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr ""
178msgstr ""
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Muzică"
182msgstr "Muzică"
147
183
@@ -149,24 +185,24 @@ msgstr "Muzică"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr ""
186msgstr ""
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170msgstr ""
206msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
@@ -198,24 +234,16 @@ msgstr "Vorbiți acum..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Vorbire..."
235msgstr "Vorbire..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Căutare"
239msgstr "Căutare"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr ""
243msgstr ""
216"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
244"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
217
245
218−#: Shell.qml:383
246+#: Shell.qml:399
219#, qt-format
247#, qt-format
220msgid "Please enter %1"
248msgid "Please enter %1"
221msgstr ""
249msgstr ""
po/ru.po+54−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr "Википедия"
85msgid "YouTube"
87msgid "YouTube"
86msgstr "YouTube"
88msgstr "YouTube"
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 "Запущенные приложения"
@@ -105,23 +141,23 @@ msgstr "Установленные"
105msgid "Available for download"
141msgid "Available for download"
106msgstr "Доступно для загрузки"
142msgstr "Доступно для загрузки"
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Приложения"
146msgstr "Приложения"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr "Часто используемые приложения"
150msgstr "Часто используемые приложения"
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr "Недавно прослушанная музыка"
154msgstr "Недавно прослушанная музыка"
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr "Популярные видео из сети"
158msgstr "Популярные видео из сети"
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Главная"
162msgstr "Главная"
127
163
@@ -141,7 +177,7 @@ msgstr "Новые релизы"
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr ""
178msgstr ""
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Музыка"
182msgstr "Музыка"
147
183
@@ -149,25 +185,25 @@ msgstr "Музыка"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr ""
186msgstr ""
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170−msgstr "Экстренный вызов"
206+msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
209#, qt-format
@@ -198,23 +234,15 @@ msgstr "Говорите..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Говорите..."
235msgstr "Говорите..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Устройство"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Режим полета"
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Поиск"
239msgstr "Поиск"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "Извините, поиск не дал результатов."
243msgstr "Извините, поиск не дал результатов."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr "Пожалуйста, введите %1"
248msgstr "Пожалуйста, введите %1"
po/si.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr ""
181msgstr ""
147
182
@@ -149,24 +184,24 @@ msgstr ""
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/sl.po+54−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr "Wikipedija"
85msgid "YouTube"
87msgid "YouTube"
86msgstr "YouTube"
88msgstr "YouTube"
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +141,23 @@ msgstr "Nameščeno"
105msgid "Available for download"
141msgid "Available for download"
106msgstr "Na voljo za prejem"
142msgstr "Na voljo za prejem"
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Programi"
146msgstr "Programi"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr "Pogosto uporabljani programi"
150msgstr "Pogosto uporabljani programi"
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr "Nedavna glasba"
154msgstr "Nedavna glasba"
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr ""
158msgstr ""
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Domov"
162msgstr "Domov"
127
163
@@ -141,7 +177,7 @@ msgstr "Nove izdaje"
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr "Najvišje na lestvici"
178msgstr "Najvišje na lestvici"
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Glasba"
182msgstr "Glasba"
147
183
@@ -149,25 +185,25 @@ msgstr "Glasba"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr "Priljubljeno na spletu"
186msgstr "Priljubljeno na spletu"
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170−msgstr "Klic v sili"
206+msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
209#, qt-format
@@ -198,23 +234,15 @@ msgstr "Govorite zdaj ..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Govorjenje ..."
235msgstr "Govorjenje ..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Naprava"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Način letenja"
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Iskanje"
239msgstr "Iskanje"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "Nič se ne ujema z vašim iskalnim nizom."
243msgstr "Nič se ne ujema z vašim iskalnim nizom."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr ""
248msgstr ""
po/sr.po+53−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr ""
85msgid "YouTube"
87msgid "YouTube"
86msgstr ""
88msgstr ""
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +141,23 @@ msgstr ""
105msgid "Available for download"
141msgid "Available for download"
106msgstr ""
142msgstr ""
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Програми"
146msgstr "Програми"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr ""
150msgstr ""
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr ""
154msgstr ""
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr ""
158msgstr ""
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Почетна"
162msgstr "Почетна"
127
163
@@ -141,7 +177,7 @@ msgstr ""
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr ""
178msgstr ""
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Музика"
182msgstr "Музика"
147
183
@@ -149,24 +185,24 @@ msgstr "Музика"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr ""
186msgstr ""
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170msgstr ""
206msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +234,15 @@ msgstr "Изговорите сада..."
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Говор..."
235msgstr "Говор..."
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Претрага"
239msgstr "Претрага"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "Нажалост, претрага није наишла на икакво подударање."
243msgstr "Нажалост, претрага није наишла на икакво подударање."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr ""
248msgstr ""
po/sv.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr ""
181msgstr ""
147
182
@@ -149,24 +184,24 @@ msgstr ""
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/te.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "నివాసం"
161msgstr "నివాసం"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "సంగీతం"
181msgstr "సంగీతం"
147
182
@@ -149,24 +184,24 @@ msgstr "సంగీతం"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/tr.po+53−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "Vikipedi"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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"
@@ -105,23 +140,23 @@ msgstr "Yüklenenler"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "İndirilebilir durumda"
141msgstr "İndirilebilir durumda"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "Uygulamalar"
145msgstr "Uygulamalar"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "Sıkça Kullanılan Uygulamalar"
149msgstr "Sıkça Kullanılan Uygulamalar"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "En Son Müzik"
153msgstr "En Son Müzik"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "Çevrimiçi Yaygın Videolar"
157msgstr "Çevrimiçi Yaygın Videolar"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "Ana Sayfa"
161msgstr "Ana Sayfa"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "Müzik"
181msgstr "Müzik"
147
182
@@ -149,25 +184,25 @@ msgstr "Müzik"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "Genellikle Çevrimiçi"
185msgstr "Genellikle Çevrimiçi"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr "Acil Arama"
205+msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
@@ -198,23 +233,15 @@ msgstr "Şimdi Konuşun..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "Konuşuyor..."
234msgstr "Konuşuyor..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Aygıt"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Uçak Modu"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "Ara"
238msgstr "Ara"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
242msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/ug.po+53−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "ۋىكىپېدىيە"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 "ئىجرا بولۇۋاتقان ئەپلەر"
@@ -105,23 +140,23 @@ msgstr "ئورنىتىلغانلىرى"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "چۈشۈرگىلى بولىدىغانلىرى"
141msgstr "چۈشۈرگىلى بولىدىغانلىرى"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "ئەپلەر"
145msgstr "ئەپلەر"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "دائىم ئىشلىتىلىدىغان ئەپلەر"
149msgstr "دائىم ئىشلىتىلىدىغان ئەپلەر"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "يېقىندا ئاڭلىغان مۇزىكىلار"
153msgstr "يېقىندا ئاڭلىغان مۇزىكىلار"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "توردىكى ئالقىشقا ئېرىشكەن سىنلار"
157msgstr "توردىكى ئالقىشقا ئېرىشكەن سىنلار"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "ماكان"
161msgstr "ماكان"
127
162
@@ -141,7 +176,7 @@ msgstr "يېڭى ئېلان قىلىنغانلىرى"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "مۇزىكا"
181msgstr "مۇزىكا"
147
182
@@ -149,25 +184,25 @@ msgstr "مۇزىكا"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr "جىددىي تېلېفون"
205+msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
@@ -198,23 +233,15 @@ msgstr "ئەمدى سۆزلەڭ…"
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "سۆزلەۋاتىسىز…"
234msgstr "سۆزلەۋاتىسىز…"
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "ئۈسكۈنە"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "ئايروپىلاندا"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "ئىزدە"
238msgstr "ئىزدە"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
242msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/uk.po+54−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +87,44 @@ msgstr "Вікіпедія"
85msgid "YouTube"
87msgid "YouTube"
86msgstr "YouTube"
88msgstr "YouTube"
87
89
88−#: Components/PageHeader.qml:300
90+#: Components/PageHeader.qml:298
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 "Запущені програми"
@@ -105,23 +141,23 @@ msgstr "Встановлені"
105msgid "Available for download"
141msgid "Available for download"
106msgstr "Доступно до завантаження"
142msgstr "Доступно до завантаження"
107
143
108−#: Dash/DashApps.qml:178
144+#: Dash/DashApps.qml:168
109msgid "Apps"
145msgid "Apps"
110msgstr "Програми"
146msgstr "Програми"
111
147
112−#: Dash/DashHome.qml:40
148+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
149msgid "Frequent Apps"
114msgstr "Часто використовувані програми"
150msgstr "Часто використовувані програми"
115
151
116−#: Dash/DashHome.qml:43
152+#: Dash/DashHome.qml:44
117msgid "Recent Music"
153msgid "Recent Music"
118msgstr "Нещодавно прослухана музика"
154msgstr "Нещодавно прослухана музика"
119
155
120−#: Dash/DashHome.qml:46
156+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
157msgid "Videos Popular Online"
122msgstr "Популярні в мережі відео"
158msgstr "Популярні в мережі відео"
123
159
124−#: Dash/DashHome.qml:175
160+#: Dash/DashHome.qml:151
125msgid "Home"
161msgid "Home"
126msgstr "Домівка"
162msgstr "Домівка"
127
163
@@ -141,7 +177,7 @@ msgstr "Нові випуски"
141msgid "Top Charting"
177msgid "Top Charting"
142msgstr "З високими оцінками"
178msgstr "З високими оцінками"
143
179
144−#: Dash/DashMusic.qml:99
180+#: Dash/DashMusic.qml:91
145msgid "Music"
181msgid "Music"
146msgstr "Музика"
182msgstr "Музика"
147
183
@@ -149,25 +185,25 @@ msgstr "Музика"
149msgid "Popular Online"
185msgid "Popular Online"
150msgstr "Популярне у мережі"
186msgstr "Популярне у мережі"
151
187
152−#: Dash/DashVideos.qml:155
188+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
204#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
205+msgid "Emergency Call"
170−msgstr "Екстрений виклик"
206+msgstr ""
171
207
172#: Greeter/PassphraseLockscreen.qml:59
208#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
209#, qt-format
@@ -198,23 +234,15 @@ msgstr "Можна говорити…"
198msgid "Speaking..."
234msgid "Speaking..."
199msgstr "Мовлення…"
235msgstr "Мовлення…"
200
236
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "Пристрій"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "Автономний режим"
208−
209−#: Panel/SearchIndicator.qml:26
237+#: Panel/SearchIndicator.qml:27
210msgid "Search"
238msgid "Search"
211msgstr "Пошук"
239msgstr "Пошук"
212
240
213−#: plugins/Unity/scope.cpp:268
241+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
242msgid "Sorry, there is nothing that matches your search."
215msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
243msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
216
244
217−#: Shell.qml:383
245+#: Shell.qml:399
218#, qt-format
246#, qt-format
219msgid "Please enter %1"
247msgid "Please enter %1"
220msgstr "Будь ласка, введіть %1"
248msgstr "Будь ласка, введіть %1"
po/unity8.pot+51−24
@@ -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-06-26 22:58+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"
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 ""
@@ -105,23 +140,23 @@ msgstr ""
105msgid "Available for download"
140msgid "Available for download"
106msgstr ""
141msgstr ""
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr ""
145msgstr ""
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr ""
149msgstr ""
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr ""
153msgstr ""
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr ""
157msgstr ""
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr ""
161msgstr ""
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr ""
181msgstr ""
147
182
@@ -149,24 +184,24 @@ msgstr ""
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr ""
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr ""
234msgstr ""
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr ""
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr ""
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr ""
238msgstr ""
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr ""
242msgstr ""
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/update-unity-pot+1
@@ -20,6 +20,7 @@ xgettext \
20 --qt --c++ \
20 --qt --c++ \
21 --add-comments=TRANSLATORS \
21 --add-comments=TRANSLATORS \
22 --keyword=tr \
22 --keyword=tr \
23+ --keyword=tr:1,2 \
23 --package-name="unity8" \
24 --package-name="unity8" \
24 --copyright-holder="Canonical Ltd."
25 --copyright-holder="Canonical Ltd."
25
26
po/zh_CN.po+53−26
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr "维基百科"
85msgid "YouTube"
86msgid "YouTube"
86msgstr "YouTube"
87msgstr "YouTube"
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 "正在运行的应用程序"
@@ -105,23 +140,23 @@ msgstr "已安装"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "可供下载"
141msgstr "可供下载"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "应用程序"
145msgstr "应用程序"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "常用软件"
149msgstr "常用软件"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "近期听过的音乐"
153msgstr "近期听过的音乐"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "热门在线视频"
157msgstr "热门在线视频"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "主页"
161msgstr "主页"
127
162
@@ -141,7 +176,7 @@ msgstr "新版本"
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr "排行榜图"
177msgstr "排行榜图"
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "音乐"
181msgstr "音乐"
147
182
@@ -149,25 +184,25 @@ msgstr "音乐"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr "经常在线"
185msgstr "经常在线"
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170−msgstr "紧急呼救"
205+msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
173#, qt-format
208#, qt-format
@@ -198,23 +233,15 @@ msgstr "现在请讲..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "讲话中..."
234msgstr "讲话中..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "设备"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "飞行模式"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "搜索"
238msgstr "搜索"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "对不起,没有找到您想要的结果。"
242msgstr "对不起,没有找到您想要的结果。"
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
po/zh_TW.po+52−25
@@ -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-06-26 22:58+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-08 05:15+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
@@ -85,10 +86,44 @@ msgstr ""
85msgid "YouTube"
86msgid "YouTube"
86msgstr ""
87msgstr ""
87
88
88−#: Components/PageHeader.qml:300
89+#: Components/PageHeader.qml:298
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 "執行中的程式"
@@ -105,23 +140,23 @@ msgstr "已安裝"
105msgid "Available for download"
140msgid "Available for download"
106msgstr "可供下載"
141msgstr "可供下載"
107
142
108−#: Dash/DashApps.qml:178
143+#: Dash/DashApps.qml:168
109msgid "Apps"
144msgid "Apps"
110msgstr "程式"
145msgstr "程式"
111
146
112−#: Dash/DashHome.qml:40
147+#: Dash/DashHome.qml:41
113msgid "Frequent Apps"
148msgid "Frequent Apps"
114msgstr "常用的程式"
149msgstr "常用的程式"
115
150
116−#: Dash/DashHome.qml:43
151+#: Dash/DashHome.qml:44
117msgid "Recent Music"
152msgid "Recent Music"
118msgstr "最近聽過的音樂"
153msgstr "最近聽過的音樂"
119
154
120−#: Dash/DashHome.qml:46
155+#: Dash/DashHome.qml:47
121msgid "Videos Popular Online"
156msgid "Videos Popular Online"
122msgstr "線上熱門的影片"
157msgstr "線上熱門的影片"
123
158
124−#: Dash/DashHome.qml:175
159+#: Dash/DashHome.qml:151
125msgid "Home"
160msgid "Home"
126msgstr "家屋"
161msgstr "家屋"
127
162
@@ -141,7 +176,7 @@ msgstr ""
141msgid "Top Charting"
176msgid "Top Charting"
142msgstr ""
177msgstr ""
143
178
144−#: Dash/DashMusic.qml:99
179+#: Dash/DashMusic.qml:91
145msgid "Music"
180msgid "Music"
146msgstr "音樂"
181msgstr "音樂"
147
182
@@ -149,24 +184,24 @@ msgstr "音樂"
149msgid "Popular Online"
184msgid "Popular Online"
150msgstr ""
185msgstr ""
151
186
152−#: Dash/DashVideos.qml:155
187+#: Dash/DashVideos.qml:146
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
168#: Greeter/Lockscreen.qml:133
203#: Greeter/Lockscreen.qml:133
169−msgid "Emergency call"
204+msgid "Emergency Call"
170msgstr ""
205msgstr ""
171
206
172#: Greeter/PassphraseLockscreen.qml:59
207#: Greeter/PassphraseLockscreen.qml:59
@@ -198,23 +233,15 @@ msgstr "請說..."
198msgid "Speaking..."
233msgid "Speaking..."
199msgstr "說話中..."
234msgstr "說話中..."
200
235
201−#: Panel/MenuContent.qml:192
202−msgid "Device"
203−msgstr "裝置"
204−
205−#: Panel/Menus/Overview/FlightModeWidget.qml:42
206−msgid "Flight mode"
207−msgstr "飛航模式"
208−
209−#: Panel/SearchIndicator.qml:26
236+#: Panel/SearchIndicator.qml:27
210msgid "Search"
237msgid "Search"
211msgstr "搜尋"
238msgstr "搜尋"
212
239
213−#: plugins/Unity/scope.cpp:268
240+#: plugins/Unity/scope.cpp:298
214msgid "Sorry, there is nothing that matches your search."
241msgid "Sorry, there is nothing that matches your search."
215msgstr "很抱歉,找不到符合您想搜尋的結果。"
242msgstr "很抱歉,找不到符合您想搜尋的結果。"
216
243
217−#: Shell.qml:383
244+#: Shell.qml:399
218#, qt-format
245#, qt-format
219msgid "Please enter %1"
246msgid "Please enter %1"
220msgstr ""
247msgstr ""
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/CMakeLists.txt−4
@@ -1,9 +1,5 @@
1file(GLOB INDICATOR_SERVICE_FILES
1file(GLOB INDICATOR_SERVICE_FILES
2− ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.battery
3 ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.messages
2 ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.messages
4− ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicator.time
5− ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.settings.network
6− ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.settings.sound
7)
3)
8
4
9# copy indicators files into build directory for shadow builds
5# copy indicators files into build directory for shadow builds
src/Panel/Indicators/servicefiles/com.canonical.indicator.batterydeleted−9
@@ -1,9 +0,0 @@
1−[Indicator Service]
2−Name=indicator-battery
3−ObjectPath=/com/canonical/indicator/battery
4−
5−[phone]
6−ObjectPath=/com/canonical/indicator/battery/phone
7−
8−[desktop]
9−ObjectPath=/com/canonical/indicator/battery/phone
src/Panel/Indicators/servicefiles/com.canonical.indicator.messages+2−1
@@ -1,6 +1,7 @@
1[Indicator Service]
1[Indicator Service]
2−Name=indicator-messaging
2+Name=indicator-messages
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.timedeleted−9
@@ -1,9 +0,0 @@
1−[Indicator Service]
2−Name=indicator-time
3−ObjectPath=/com/canonical/indicator/time
4−
5−[phone]
6−ObjectPath=/com/canonical/indicator/time/phone
7−
8−[desktop]
9−ObjectPath=/com/canonical/indicator/time/desktop
src/Panel/Indicators/servicefiles/com.canonical.settings.networkdeleted−9
@@ -1,9 +0,0 @@
1−[Indicator Service]
2−Name=indicator-network
3−ObjectPath=/com/canonical/settings/network
4−
5−[phone]
6−ObjectPath=/com/canonical/settings/network/phone
7−
8−[desktop]
9−ObjectPath=/com/canonical/settings/network/desktop
src/Panel/Indicators/servicefiles/com.canonical.settings.sounddeleted−9
@@ -1,9 +0,0 @@
1−[Indicator Service]
2−Name=indicator-sound
3−ObjectPath=/com/canonical/settings/sound
4−
5−[phone]
6−ObjectPath=/com/canonical/settings/sound/phone
7−
8−[desktop]
9−ObjectPath=/com/canonical/settings/sound/desktop
tests/autopilot/unity8/indicators_client/tests/test_battery.py+14−8
@@ -15,11 +15,21 @@ from unity8.indicators_client.tests import IndicatorsTestCase
15from time import sleep
15from time import sleep
16import random
16import random
17import math
17import math
18+import unittest
18
19
19class TestDisplayMenus(IndicatorsTestCase):
20class TestDisplayMenus(IndicatorsTestCase):
20 def setUp(self):
21 def setUp(self):
21 super(TestDisplayMenus, self).setUp(self.geometry, self.grid_unit)
22 super(TestDisplayMenus, self).setUp(self.geometry, self.grid_unit)
22
23
24+ def tearDown(self):
25+ # self.main_window.get_indicators_client().reset()
26+ super(TestDisplayMenus, self).tearDown()
27+
28+ # START SECTION
29+ # We need to move these to emulators once autopilot supports emulators for
30+ # applications started with AutopilotTestCase.launch_test_application
31+
32+ def open_battery_menu(self):
23 # This opens the messaging menu so you don't have to do that in
33 # This opens the messaging menu so you don't have to do that in
24 # every test case
34 # every test case
25 self.assertThat(lambda: self.main_window.get_battery_menu(), Eventually(NotEquals(None)));
35 self.assertThat(lambda: self.main_window.get_battery_menu(), Eventually(NotEquals(None)));
@@ -31,14 +41,6 @@ class TestDisplayMenus(IndicatorsTestCase):
31 page_loader = fn_loader();
41 page_loader = fn_loader();
32 self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
42 self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
33
43
34− def tearDown(self):
35− # self.main_window.get_indicators_client().reset()
36− super(TestDisplayMenus, self).tearDown()
37−
38− # START SECTION
39− # We need to move these to emulators once autopilot supports emulators for
40− # applications started with AutopilotTestCase.launch_test_application
41−
42 def switch_auto_brightness(self, auto_brightness):
44 def switch_auto_brightness(self, auto_brightness):
43 ab_switch = auto_brightness.select_single("CheckBox");
45 ab_switch = auto_brightness.select_single("CheckBox");
44 self.assertThat(ab_switch, NotEquals(None))
46 self.assertThat(ab_switch, NotEquals(None))
@@ -65,8 +67,10 @@ class TestDisplayMenus(IndicatorsTestCase):
65
67
66 old_ab_value = brightness_slider.value
68 old_ab_value = brightness_slider.value
67
69
70+ @unittest.skip("Battery indicator has been removed.")
68 def test_auto_bright_switch(self):
71 def test_auto_bright_switch(self):
69 """Test the auto-bright switch"""
72 """Test the auto-bright switch"""
73+ self.open_battery_menu()
70
74
71 # wait for the switch menu item
75 # wait for the switch menu item
72 fn_auto_brightness = lambda: self.app.select_single("SwitchMenuItem", objectName="auto-brightness");
76 fn_auto_brightness = lambda: self.app.select_single("SwitchMenuItem", objectName="auto-brightness");
@@ -84,8 +88,10 @@ class TestDisplayMenus(IndicatorsTestCase):
84 # TODO - should check backend when it's introspectable.
88 # TODO - should check backend when it's introspectable.
85 self.assertThat(auto_brightness.checked, Eventually(NotEquals(old_ab_value)))
89 self.assertThat(auto_brightness.checked, Eventually(NotEquals(old_ab_value)))
86
90
91+ @unittest.skip("Battery indicator has been removed.")
87 def test_brightness_slider(self):
92 def test_brightness_slider(self):
88 """Test the auto-bright switch"""
93 """Test the auto-bright switch"""
94+ self.open_battery_menu()
89
95
90 fn_brightness_menu = lambda: self.app.select_single("SliderMenuItem", objectName="brightness");
96 fn_brightness_menu = lambda: self.app.select_single("SliderMenuItem", objectName="brightness");
91 # FIXME: this should go away when we switch to indicator-power
97 # FIXME: this should go away when we switch to indicator-power
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/backgrounds/blue.pngnew file

Binary file not shown.

tests/data/unity/backgrounds/red.pngnew file

Binary file not shown.

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+3−1
@@ -1,6 +1,8 @@
1+add_subdirectory(GSettings.1.0)
2+add_subdirectory(HudClient)
1add_subdirectory(liblightdm)
3add_subdirectory(liblightdm)
2add_subdirectory(libusermetrics)
4add_subdirectory(libusermetrics)
5+add_subdirectory(Powerd)
3add_subdirectory(QMenuModel)
6add_subdirectory(QMenuModel)
4add_subdirectory(Ubuntu)
7add_subdirectory(Ubuntu)
5add_subdirectory(Unity)
8add_subdirectory(Unity)
6−add_subdirectory(HudClient)
tests/mocks/GSettings.1.0/CMakeLists.txtnew file+23
@@ -0,0 +1,23 @@
1+include_directories(
2+ ${CMAKE_CURRENT_BINARY_DIR}
3+ ${Qt5Core_INCLUDE_DIRS}
4+ ${Qt5Quick_INCLUDE_DIRS}
5+)
6+
7+set(GSettingsQML_SOURCES
8+ fake_gsettings.cpp
9+ plugin.cpp
10+)
11+
12+add_library(FakeGSettingsQml MODULE ${GSettingsQML_SOURCES})
13+target_link_libraries(FakeGSettingsQml
14+ ${Qt5Core_LIBRARIES}
15+ ${Qt5Quick_LIBRARIES}
16+)
17+
18+qt5_use_modules(FakeGSettingsQml Qml)
19+
20+# copy qmldir file into build directory for shadow builds
21+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
22+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
23+ )
tests/mocks/GSettings.1.0/fake_gsettings.cppnew file+102
@@ -0,0 +1,102 @@
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+#include "fake_gsettings.h"
18+
19+#include <QList>
20+
21+GSettingsControllerQml* GSettingsControllerQml::s_controllerInstance = 0;
22+
23+GSettingsControllerQml::GSettingsControllerQml() {
24+}
25+
26+GSettingsControllerQml::~GSettingsControllerQml() {
27+ s_controllerInstance = 0;
28+}
29+
30+GSettingsControllerQml* GSettingsControllerQml::instance() {
31+ if (!s_controllerInstance) {
32+ s_controllerInstance = new GSettingsControllerQml();
33+ }
34+ return s_controllerInstance;
35+}
36+
37+void GSettingsControllerQml::registerSettingsObject(GSettingsQml *obj) {
38+ m_registeredGSettings.append(obj);
39+}
40+
41+void GSettingsControllerQml::unRegisterSettingsObject(GSettingsQml *obj) {
42+ m_registeredGSettings.removeOne(obj);
43+}
44+
45+void GSettingsControllerQml::setPictureUri(const QString &str) {
46+ Q_FOREACH (GSettingsQml *obj, m_registeredGSettings) {
47+ obj->setPictureUri(str);
48+ }
49+}
50+
51+GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent) {
52+}
53+
54+QByteArray GSettingsSchemaQml::id() const {
55+ return m_id;
56+}
57+
58+void GSettingsSchemaQml::setId(const QByteArray &id) {
59+ if (m_id.isEmpty()) {
60+ qWarning("GSettings.schema.id may only be set on construction");
61+ return;
62+ }
63+
64+ m_id = id;
65+}
66+
67+QByteArray GSettingsSchemaQml::path() const {
68+ return m_path;
69+}
70+
71+void GSettingsSchemaQml::setPath(const QByteArray &path) {
72+ if (m_path.isEmpty()) {
73+ qWarning("GSettings.schema.path may only be set on construction");
74+ return;
75+ }
76+
77+ m_path = path;
78+}
79+
80+GSettingsQml::GSettingsQml(QObject *parent): QObject(parent) {
81+ m_schema = new GSettingsSchemaQml(this);
82+ GSettingsControllerQml::instance()->registerSettingsObject(this);
83+}
84+
85+GSettingsQml::~GSettingsQml() {
86+ GSettingsControllerQml::instance()->unRegisterSettingsObject(this);
87+}
88+
89+GSettingsSchemaQml * GSettingsQml::schema() const {
90+ return m_schema;
91+}
92+
93+QString GSettingsQml::pictureUri() const {
94+ return m_pictureUri;
95+}
96+
97+void GSettingsQml::setPictureUri(const QString &str) {
98+ if (str != m_pictureUri) {
99+ m_pictureUri = str;
100+ Q_EMIT pictureUriChanged(m_pictureUri);
101+ }
102+}
tests/mocks/GSettings.1.0/fake_gsettings.hnew file+90
@@ -0,0 +1,90 @@
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+#ifndef FAKE_GSETTINGS_H
18+#define FAKE_GSETTINGS_H
19+
20+#include <QList>
21+#include <QtQml>
22+
23+class GSettingsSchemaQml: public QObject
24+{
25+ Q_OBJECT
26+
27+ Q_PROPERTY(QByteArray id READ id WRITE setId)
28+
29+public:
30+ GSettingsSchemaQml(QObject *parent = NULL);
31+
32+ QByteArray id() const;
33+ void setId(const QByteArray &id);
34+
35+ QByteArray path() const;
36+ void setPath(const QByteArray &path);
37+
38+private:
39+ QByteArray m_id;
40+ QByteArray m_path;
41+};
42+
43+class GSettingsQml: public QObject
44+{
45+ Q_OBJECT
46+
47+ Q_PROPERTY(GSettingsSchemaQml* schema READ schema NOTIFY schemaChanged)
48+ Q_PROPERTY(QString pictureUri READ pictureUri WRITE setPictureUri NOTIFY pictureUriChanged)
49+
50+public:
51+ GSettingsQml(QObject *parent = NULL);
52+ ~GSettingsQml();
53+
54+ GSettingsSchemaQml * schema() const;
55+ QString pictureUri() const;
56+
57+ void setPictureUri(const QString &str);
58+
59+Q_SIGNALS:
60+ void schemaChanged();
61+ void pictureUriChanged(const QString&);
62+
63+private:
64+ GSettingsSchemaQml* m_schema;
65+
66+ QString m_pictureUri;
67+
68+ friend class GSettingsSchemaQml;
69+};
70+
71+class GSettingsControllerQml: public QObject
72+{
73+ Q_OBJECT
74+
75+public:
76+ static GSettingsControllerQml* instance();
77+ ~GSettingsControllerQml();
78+
79+ void registerSettingsObject(GSettingsQml *obj);
80+ void unRegisterSettingsObject(GSettingsQml *obj);
81+ Q_INVOKABLE void setPictureUri(const QString &str);
82+
83+private:
84+ GSettingsControllerQml();
85+
86+ static GSettingsControllerQml* s_controllerInstance;
87+ QList<GSettingsQml *> m_registeredGSettings;
88+};
89+
90+#endif // FAKE_GSETTINGS_H
tests/mocks/GSettings.1.0/plugin.cppnew file+33
@@ -0,0 +1,33 @@
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 "fake_gsettings.h"
19+
20+#include <QtQml>
21+
22+static QObject* controllerProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
23+{
24+ return GSettingsControllerQml::instance();
25+}
26+
27+void FakeGSettingsQmlPlugin::registerTypes(const char *uri)
28+{
29+ qmlRegisterSingletonType<GSettingsControllerQml>(uri, 1, 0, "GSettingsController", controllerProvider);
30+ qmlRegisterType<GSettingsQml>(uri, 1, 0, "GSettings");
31+ qmlRegisterUncreatableType<GSettingsSchemaQml>(uri, 1, 0, "GSettingsSchema",
32+ "GSettingsSchema can only be used inside of a GSettings component");
33+}
tests/mocks/GSettings.1.0/plugin.hnew file+31
@@ -0,0 +1,31 @@
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 <QtQml/QQmlExtensionPlugin>
21+
22+class FakeGSettingsQmlPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+
27+public:
28+ void registerTypes(const char *uri);
29+};
30+
31+#endif // PLUGIN_H
tests/mocks/GSettings.1.0/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module GSettings
2+plugin FakeGSettingsQml
tests/mocks/HudClient/CMakeLists.txt−5
@@ -1,8 +1,3 @@
1−set(CMAKE_AUTOMOC ON)
2−
3−include(FindPkgConfig)
4−find_package(Qt5Core REQUIRED)
5−find_package(Qt5Quick REQUIRED)
6pkg_search_module(DEE dee-1.0 REQUIRED)
1pkg_search_module(DEE dee-1.0 REQUIRED)
7pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
2pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
8pkg_search_module(HUDCLIENT hud-client-2 REQUIRED)
3pkg_search_module(HUDCLIENT hud-client-2 REQUIRED)
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/Application/ApplicationInfo.cpp+1
@@ -23,6 +23,7 @@
23
23
24ApplicationInfo::ApplicationInfo(QObject *parent)
24ApplicationInfo::ApplicationInfo(QObject *parent)
25 : QObject(parent)
25 : QObject(parent)
26+ ,m_handle(0)
26 ,m_stage(MainStage)
27 ,m_stage(MainStage)
27 ,m_state(Starting)
28 ,m_state(Starting)
28 ,m_fullscreen(false)
29 ,m_fullscreen(false)
tests/mocks/Ubuntu/Application/CMakeLists.txt−6
@@ -1,9 +1,3 @@
1−set(CMAKE_AUTOMOC ON)
2−
3−include(FindPkgConfig)
4−find_package(Qt5Core REQUIRED)
5−find_package(Qt5Quick REQUIRED)
6−
7set(FakeUbuntuApplicationQml_SOURCES
1set(FakeUbuntuApplicationQml_SOURCES
8 plugin.cpp
2 plugin.cpp
9 ApplicationInfo.cpp
3 ApplicationInfo.cpp
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/CMakeLists.txt−5
@@ -1,10 +1,5 @@
1−set(CMAKE_AUTOMOC ON)
2−
3add_subdirectory(Indicators)
1add_subdirectory(Indicators)
4
2
5−include(FindPkgConfig)
6−find_package(Qt5Core REQUIRED)
7−find_package(Qt5Quick REQUIRED)
8pkg_search_module(DEE dee-1.0 REQUIRED)
3pkg_search_module(DEE dee-1.0 REQUIRED)
9pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
4pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
10pkg_search_module(DEEQT libdee-qt5 REQUIRED)
5pkg_search_module(DEEQT libdee-qt5 REQUIRED)
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/MockLauncherItem.cpp+2−2
@@ -31,8 +31,8 @@ MockLauncherItem::MockLauncherItem(const QString &appId, const QString& desktopF
31 m_pinned(false),
31 m_pinned(false),
32 m_running(false),
32 m_running(false),
33 m_recent(false),
33 m_recent(false),
34− m_progress(8),
34+ m_progress(-1),
35− m_count(8),
35+ m_count(0),
36 m_quickList(new MockQuickListModel(this))
36 m_quickList(new MockQuickListModel(this))
37{
37{
38
38
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+42−18
@@ -22,34 +22,40 @@
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+ item->setProgress(0);
26 m_list.append(item);
27 m_list.append(item);
27− item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera");
28+ item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera", this);
29+ item->setProgress(10);
28 m_list.append(item);
30 m_list.append(item);
29− item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery");
31+ item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);
32+ item->setProgress(50);
30 m_list.append(item);
33 m_list.append(item);
31− item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook");
34+ item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook", this);
35+ item->setProgress(150);
32 m_list.append(item);
36 m_list.append(item);
33− item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser");
37+ item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this);
38+ item->setCount(1);
34 m_list.append(item);
39 m_list.append(item);
35− item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter");
40+ item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this);
41+ item->setCount(12);
36 m_list.append(item);
42 m_list.append(item);
37− item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail");
43+ item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this);
44+ item->setCount(123);
38 m_list.append(item);
45 m_list.append(item);
39− item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather");
46+ item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this);
47+ item->setCount(1234567890);
40 m_list.append(item);
48 m_list.append(item);
41− item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad");
49+ item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this);
50+ item->setProgress(50);
51+ item->setCount(5);
42 m_list.append(item);
52 m_list.append(item);
43− item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar");
53+ item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar", this);
44 m_list.append(item);
54 m_list.append(item);
45}
55}
46
56
47MockLauncherModel::~MockLauncherModel()
57MockLauncherModel::~MockLauncherModel()
48{
58{
49− while (!m_list.empty())
50− {
51− m_list.takeFirst()->deleteLater();
52− }
53}
59}
54
60
55int MockLauncherModel::rowCount(const QModelIndex& parent) const
61int MockLauncherModel::rowCount(const QModelIndex& parent) const
@@ -95,9 +101,29 @@ unity::shell::launcher::LauncherItemInterface *MockLauncherModel::get(int index)
95
101
96void MockLauncherModel::move(int oldIndex, int newIndex)
102void MockLauncherModel::move(int oldIndex, int newIndex)
97{
103{
104+ // Make sure its not moved outside the lists
105+ if (newIndex < 0) {
106+ newIndex = 0;
107+ }
108+ if (newIndex >= m_list.count()) {
109+ newIndex = m_list.count()-1;
110+ }
111+
112+ // Nothing to do?
113+ if (oldIndex == newIndex) {
114+ return;
115+ }
116+
117+ // QList's and QAbstractItemModel's move implementation differ when moving an item up the list :/
118+ // While QList needs the index in the resulting list, beginMoveRows expects it to be in the current list
119+ // adjust the model's index by +1 in case we're moving upwards
120+ int newModelIndex = newIndex > oldIndex ? newIndex+1 : newIndex;
121+
98− beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
122+ beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newModelIndex);
99 m_list.move(oldIndex, newIndex);
123 m_list.move(oldIndex, newIndex);
100 endMoveRows();
124 endMoveRows();
125+
126+ pin(m_list.at(newIndex)->appId());
101}
127}
102
128
103void MockLauncherModel::pin(const QString &appId, int index)
129void MockLauncherModel::pin(const QString &appId, int index)
@@ -135,9 +161,7 @@ void MockLauncherModel::requestRemove(const QString &appId)
135
161
136void MockLauncherModel::quickListActionInvoked(const QString &appId, int actionIndex)
162void MockLauncherModel::quickListActionInvoked(const QString &appId, int actionIndex)
137{
163{
138− Q_UNUSED(appId)
164+ Q_EMIT quickListTriggered(appId, actionIndex);
139− Q_UNUSED(actionIndex)
140− // Nothing to mock yet...
141}
165}
142
166
143int MockLauncherModel::findApp(const QString &appId)
167int MockLauncherModel::findApp(const QString &appId)
tests/mocks/Unity/Launcher/MockLauncherModel.h+3
@@ -44,6 +44,9 @@ public:
44 Q_INVOKABLE void requestRemove(const QString &appId);
44 Q_INVOKABLE void requestRemove(const QString &appId);
45 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
45 Q_INVOKABLE void quickListActionInvoked(const QString &appId, int actionIndex);
46
46
47+Q_SIGNALS:
48+ void quickListTriggered(const QString &appId, int index);
49+
47private:
50private:
48 int findApp(const QString &appId);
51 int findApp(const QString &appId);
49
52
tests/mocks/Unity/Launcher/MockQuickListModel.cpp+2
@@ -35,6 +35,8 @@ QVariant MockQuickListModel::data(const QModelIndex &index, int role) const
35 return QLatin1String("test menu entry ") + QString::number(index.row());
35 return QLatin1String("test menu entry ") + QString::number(index.row());
36 case RoleIcon:
36 case RoleIcon:
37 return QLatin1String("copy.png");
37 return QLatin1String("copy.png");
38+ case RoleClickable:
39+ return index.row() == 1 ? false : true;
38 }
40 }
39 return QVariant();
41 return QVariant();
40}
42}
tests/mocks/Unity/Launcher/plugin.cpp+3
@@ -20,6 +20,7 @@
20#include "plugin.h"
20#include "plugin.h"
21#include "MockLauncherModel.h"
21#include "MockLauncherModel.h"
22#include "MockLauncherItem.h"
22#include "MockLauncherItem.h"
23+#include "MockQuickListModel.h"
23
24
24#include <unity/shell/launcher/LauncherModelInterface.h>
25#include <unity/shell/launcher/LauncherModelInterface.h>
25#include <unity/shell/launcher/LauncherItemInterface.h>
26#include <unity/shell/launcher/LauncherItemInterface.h>
@@ -39,7 +40,9 @@ void TestLauncherPlugin::registerTypes(const char* uri)
39 // @uri Unity.Launcher
40 // @uri Unity.Launcher
40 qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated.");
41 qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated.");
41 qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated.");
42 qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated.");
43+ qmlRegisterUncreatableType<QuickListModelInterface>(uri, 0, 1, "QuickListModelInterface", "Abstract Interface. Cannot be instantiated.");
42
44
43 qmlRegisterSingletonType<MockLauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
45 qmlRegisterSingletonType<MockLauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
44 qmlRegisterUncreatableType<MockLauncherItem>(uri, 0, 1, "LauncherItem", "Can't create LauncherItems in QML. Get them from the LauncherModel");
46 qmlRegisterUncreatableType<MockLauncherItem>(uri, 0, 1, "LauncherItem", "Can't create LauncherItems in QML. Get them from the LauncherModel");
47+ qmlRegisterUncreatableType<MockQuickListModel>(uri, 0, 1, "QuickListModel", "Can't create QuickLists in QML. Get them from the LauncherItems");
45}
48}
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+44−1
@@ -19,6 +19,7 @@
19#include <QAbstractItemModel>
19#include <QAbstractItemModel>
20#include <QQmlEngine>
20#include <QQmlEngine>
21#include <QQuickView>
21#include <QQuickView>
22+#include <QSignalSpy>
22#include <QtTestGui>
23#include <QtTestGui>
23#pragma GCC diagnostic push
24#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-pedantic"
25#pragma GCC diagnostic ignored "-pedantic"
@@ -1521,7 +1522,7 @@ private Q_SLOTS:
1521 QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1522 QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1522 verifyItem(0, -458., 1000., false);
1523 verifyItem(0, -458., 1000., false);
1523 verifyItem(1, 542., 350., true);
1524 verifyItem(1, 542., 350., true);
1524− QCOMPARE(lvwph->m_minYExtent, 362.5);
1525+ QCOMPARE(lvwph->m_minYExtent, 525.);
1525 QCOMPARE(lvwph->m_clipItem->y(), 658.);
1526 QCOMPARE(lvwph->m_clipItem->y(), 658.);
1526 QCOMPARE(lvwph->m_clipItem->clip(), false);
1527 QCOMPARE(lvwph->m_clipItem->clip(), false);
1527 QCOMPARE(lvwph->m_headerItem->y(), 0.);
1528 QCOMPARE(lvwph->m_headerItem->y(), 0.);
@@ -1612,6 +1613,48 @@ private Q_SLOTS:
1612 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1613 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1613 }
1614 }
1614
1615
1616+ void testMaximizeVisibleAreaWithItemResize()
1617+ {
1618+ model->setProperty(0, "size", 1000);
1619+
1620+ bool res = lvwph->maximizeVisibleArea(1);
1621+ QVERIFY(res);
1622+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1623+
1624+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
1625+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1626+ verifyItem(0, -658., 1000., false);
1627+ verifyItem(1, 342., 200., false);
1628+ verifyItem(2, 542, 350., true);
1629+ QCOMPARE(lvwph->m_minYExtent, 0.);
1630+ QCOMPARE(lvwph->m_clipItem->y(), 708.);
1631+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1632+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1633+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1634+ QCOMPARE(lvwph->contentY(), 708.);
1635+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1636+ }
1637+
1638+ void addingRemoveItemsShouldNotChangeContentY()
1639+ {
1640+ QSignalSpy spy(lvwph, SIGNAL(contentYChanged()));
1641+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 150));
1642+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 6));
1643+
1644+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
1645+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1646+ verifyItem(0, 50., 150., false);
1647+ QCOMPARE(lvwph->m_minYExtent, 0.);
1648+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1649+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1650+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1651+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1652+ QCOMPARE(lvwph->contentY(), 0.);
1653+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1654+
1655+ QCOMPARE(spy.count(), 0);
1656+ }
1657+
1615private:
1658private:
1616 QQuickView *view;
1659 QQuickView *view;
1617 ListViewWithPageHeader *lvwph;
1660 ListViewWithPageHeader *lvwph;
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+44−1
@@ -19,6 +19,7 @@
19#include <QAbstractItemModel>
19#include <QAbstractItemModel>
20#include <QQmlEngine>
20#include <QQmlEngine>
21#include <QQuickView>
21#include <QQuickView>
22+#include <QSignalSpy>
22#include <QtTestGui>
23#include <QtTestGui>
23#pragma GCC diagnostic push
24#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-pedantic"
25#pragma GCC diagnostic ignored "-pedantic"
@@ -1875,7 +1876,7 @@ private Q_SLOTS:
1875 QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1876 QCOMPARE(lvwph->m_firstVisibleIndex, 1);
1876 verifyItem(0, -498., 1040., false, "Regular", true);
1877 verifyItem(0, -498., 1040., false, "Regular", true);
1877 verifyItem(1, 542., 390., true, "Mild", true);
1878 verifyItem(1, 542., 390., true, "Mild", true);
1878− QCOMPARE(lvwph->m_minYExtent, 1250/3.);
1879+ QCOMPARE(lvwph->m_minYExtent, 525.);
1879 QCOMPARE(lvwph->m_clipItem->y(), 738.);
1880 QCOMPARE(lvwph->m_clipItem->y(), 738.);
1880 QCOMPARE(lvwph->m_clipItem->clip(), false);
1881 QCOMPARE(lvwph->m_clipItem->clip(), false);
1881 QCOMPARE(lvwph->m_headerItem->y(), 0.);
1882 QCOMPARE(lvwph->m_headerItem->y(), 0.);
@@ -2033,6 +2034,48 @@ private Q_SLOTS:
2033 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
2034 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
2034 }
2035 }
2035
2036
2037+ void testMaximizeVisibleAreaWithItemResize()
2038+ {
2039+ model->setProperty(0, "size", 1000);
2040+
2041+ bool res = lvwph->maximizeVisibleArea(1);
2042+ QVERIFY(res);
2043+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
2044+
2045+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 3);
2046+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2047+ verifyItem(0, -738., 1040., false, "Agressive", true);
2048+ verifyItem(1, 302., 240., false, "Regular", false);
2049+ verifyItem(2, 542, 390., true, "Mild", true);
2050+ QCOMPARE(lvwph->m_minYExtent, 0.);
2051+ QCOMPARE(lvwph->m_clipItem->y(), 788.);
2052+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2053+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
2054+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
2055+ QCOMPARE(lvwph->contentY(), 788.);
2056+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2057+ }
2058+
2059+ void addingRemoveItemsShouldNotChangeContentY()
2060+ {
2061+ QSignalSpy spy(lvwph, SIGNAL(contentYChanged()));
2062+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 150), Q_ARG(QVariant, "Agressive"));
2063+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 6));
2064+
2065+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 1);
2066+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
2067+ verifyItem(0, 50., 190., false, "Agressive", false);
2068+ QCOMPARE(lvwph->m_minYExtent, 0.);
2069+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
2070+ QCOMPARE(lvwph->m_clipItem->clip(), false);
2071+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
2072+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
2073+ QCOMPARE(lvwph->contentY(), 0.);
2074+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
2075+
2076+ QCOMPARE(spy.count(), 0);
2077+ }
2078+
2036private:
2079private:
2037 QQuickView *view;
2080 QQuickView *view;
2038 ListViewWithPageHeader *lvwph;
2081 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/plugins/Utils/qlimitproxymodeltest.cpp+133−8

This diff is too big to show here.

tests/qmltests/CMakeLists.txt+3−1

This diff is too big to show here.

tests/qmltests/Components/tst_FilterGrid.qml−35

This diff is too big to show here.

tests/qmltests/Dash/Apps/tst_AppPreview.qmlnew file+166

This diff is too big to show here.

tests/qmltests/Dash/Video/tst_VideoPreview.qmlnew file+63

This diff is too big to show here.

tests/qmltests/Dash/tst_DashPreview.qml+2−23

This diff is too big to show here.

tests/qmltests/Greeter/tst_Clock.qml+1−1

This diff is too big to show here.

tests/qmltests/Launcher/tst_Launcher.qml+155

This diff is too big to show here.

tests/qmltests/Panel/tst_MenuContent.qml+32−47

This diff is too big to show here.

tests/qmltests/tst_Shell.qml+73−18

This diff is too big to show here.

tests/utils/modules/Unity/Test/CMakeLists.txt−4

This diff is too big to show here.