on xenial help sign in
merge trunk
340d352Michał Sawicz
debian/changelog+138
@@ -1,3 +1,141 @@
1+unity8 (7.84+14.04.20140129-0ubuntu1) trusty; urgency=low
2+
3+ [ Nick Dedekind ]
4+ * Added Panel/VisibleIndicatorsModel for use with both indicator row &
5+ menuContent. This removes the need to hide indicators in the row and
6+ map inicator indexes between row & content. Fixes the indicator
7+ highlight line offset not bound by listView position.
8+ * Ported indicators to using ubuntu-settings-components
9+
10+ [ Albert Astals ]
11+ * Prepend /sbin/ to initctl calls My phablet user does not have /sbin/
12+ in path and thus this calls fail
13+ * Call updateDelegateCreationRange when it's needed It depends on
14+ other variables than the ones we were using to call it, so need to
15+ call it if these change too Device manual test, go to apps scope,
16+ scroll down so that only part of the installed apps collapsed
17+ category is shown, expand it, see how previously some icons were not
18+ painted and now they are
19+
20+ [ Mirco Müller ]
21+ * Fixed the failure of notification autopilot-test
22+ test_sd_incoming_call.
23+
24+ [ Andrea Cimitan ]
25+ * Add AP test for policykit/network manager, which was causing issues
26+ with nested mir
27+
28+ [ CI bot ]
29+ * Resync trunk
30+
31+ [ Michał Karnicki ]
32+ * Don't display artShape when artImage source not set.
33+ * Fix FilterGrid rendering issues.
34+
35+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 29 Jan 2014 16:11:20 +0000
36+
37+unity8 (7.84+14.04.20140128-0ubuntu1) trusty; urgency=low
38+
39+ [ Michal Hruby ]
40+ * Added unity-scope-tool, which will help when developing scopes.
41+
42+ [ Michał Sawicz ]
43+ * Added unity-scope-tool, which will help when developing scopes.
44+ * Use full DashContent, not just GenericScopeView in ScopeTool.qml.
45+ * Bring Card and CardHeader over from new-scopes.
46+ * Work around bug #1268578. (LP: #1268578)
47+ * Drop unnecessary version dependencies.
48+ * Return null instead of undefined from findChild and
49+ findInvisibleChild.
50+ * Fix CardHeader and Card heights (empty Label does have non-zero
51+ height apparently). Also improve test robustness and reduce future
52+ diffs.
53+
54+ [ Albert Astals ]
55+ * Do not assert if the item we are removing was not created yet
56+ (because e.g. it's not in the viewport).
57+ * Position correctly the pointer of the search history box .
58+ * Make test_filter_expand_expand less unstable in CI VMs Make sure
59+ header0 is the header0 we want to click On the CI VM stuff is a bit
60+ slower than on real hw and we were clicking in the wrong place.
61+ * Add TabBar to the Dash header navigation Changes this comes with: *
62+ DashBar at the bottom is gone * PageHeader doesn't have a Label
63+ anymore, it has the childItem property where you add which thing it
64+ has to contain * New: PageHeaderLabel mimics the old behaviour of
65+ PageHeader * The header of the LVWPH of GenericScopeView is now fake
66+ and only used for positioning. There is a single global floating
67+ header in DashContent (which is a PageHeader with a TabBar as
68+ childItem) * The GenericScopeView previewLoader and OpenEffect have
69+ been also moved to the DashContent so that the openEffect includes
70+ the floating header in the "animation" .
71+ * Introduce the HorizontalJournal.
72+ * If there are no items m_firstVisibleIndex has to be -1 .
73+ * Add some more documentation about tests to the CODING file.
74+ * Fixes to the journal cmake tests code * Output to the correct
75+ filename for the test * Don't output stuff from the tryXYZ targets.
76+ * Adapt to findChild return value changes .
77+ * Organic Grid for the Dash View.
78+ * Misc journal fixes Don't init *modelIndex to INT_MAX Makes no sense
79+ since we're not doing any qMin and the calling function also accepts
80+ any index >= 0 as valid so in some cases it may end up wanting to
81+ create an index that doesn't exist Don't refill if height() < 0,
82+ that gives bad ranges for from/to and the code gets confused .
83+
84+ [ Michał Karnicki ]
85+ * Fix grid view column count.
86+ * Add test for minimum number of items in a carousel.
87+
88+ [ Allan LeSage ]
89+ * Add stubs for indicators autopilot tests.
90+
91+ [ Andrea Cimitan ]
92+ * Avoid input falling through notifications onto surfaces below, thus
93+ fixing LP: #1257312. (LP: #1257312)
94+
95+ [ Leo Arias ]
96+ * Close the Touch devices after the tests. (LP: #1267600)
97+ * Added methods to scroll to other scopes on autopilot tests.
98+ * Added autopilot helpers for the app scope and the app preview.
99+ Install the fake scopes in order to use them on the tests. (LP:
100+ #1269114)
101+ * On autopilot helpers, wait for the scope category to appear.
102+
103+ [ Nick Dedekind ]
104+ * Visual updates for indicator panel highlight and opening opacity.
105+ * Added inidcator tests for page & item factories.
106+ * Fixes visible indicator misalignment in indicator items/menus
107+ (lp#1264678). (LP: #1264678)
108+
109+ [ Mirco Müller ]
110+ * Fixed the failure of notification autopilot-test
111+ test_sd_incoming_call.
112+
113+ [ Michael Zanetti ]
114+ * clean up fullscreen notifications code.
115+ * import qml files into cmake, drop qmlproject.
116+ * also add qml files in tests directory.
117+ * Added autopilot helpers for the app scope and the app preview.
118+ Install the fake scopes in order to use them on the tests. (LP:
119+ #1269114)
120+
121+ [ Michael Terry ]
122+ * Fix failure to build when using the ./build script with ninja-build
123+ installed. (LP: #1268525)
124+ * Point DBus-activated processes at unity8's MIR_SOCKET rather than
125+ the system socket.
126+
127+ [ Daniel d'Andrada ]
128+ * DragHandle: Never restart hinting animation while still pressed (LP:
129+ #1269022)
130+
131+ [ Bill Filler ]
132+ * fix for lp:1259294, turn off auto capitalization for wifi password
133+ field. (LP: #1259294)
134+ * disable predictive text in Dash search field as it interferes with
135+ built-in search (LP: #1273643)
136+
137+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 28 Jan 2014 15:58:45 +0000
138+
1unity8 (7.84+14.04.20131220-0ubuntu1) trusty; urgency=low
139unity8 (7.84+14.04.20131220-0ubuntu1) trusty; urgency=low
2
140
3 [ Michał Sawicz ]
141 [ Michał Sawicz ]
debian/control+2
@@ -37,6 +37,7 @@ Build-Depends: cmake,
37 qtdeclarative5-private-dev,
37 qtdeclarative5-private-dev,
38 qtdeclarative5-qtquick2-plugin,
38 qtdeclarative5-qtquick2-plugin,
39 qtdeclarative5-test-plugin,
39 qtdeclarative5-test-plugin,
40+ qtdeclarative5-ubuntu-settings-components,
40 qtdeclarative5-ubuntu-ui-toolkit-plugin,
41 qtdeclarative5-ubuntu-ui-toolkit-plugin,
41 qtdeclarative5-xmllistmodel-plugin,
42 qtdeclarative5-xmllistmodel-plugin,
42 libqt5xmlpatterns5-dev,
43 libqt5xmlpatterns5-dev,
@@ -76,6 +77,7 @@ Depends: gsettings-desktop-schemas,
76 qmenumodel-qml (>= 0.2.7),
77 qmenumodel-qml (>= 0.2.7),
77 qtdeclarative5-dee-plugin,
78 qtdeclarative5-dee-plugin,
78 qtdeclarative5-gsettings1.0,
79 qtdeclarative5-gsettings1.0,
80+ qtdeclarative5-ubuntu-settings-components,
79 qtdeclarative5-ubuntu-ui-toolkit-plugin,
81 qtdeclarative5-ubuntu-ui-toolkit-plugin,
80 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
82 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
81 qtdeclarative5-xmllistmodel-plugin,
83 qtdeclarative5-xmllistmodel-plugin,
plugins/Unity/Indicators/CMakeLists.txt−2
@@ -12,8 +12,6 @@ find_package(Qt5Core REQUIRED)
12find_package(Qt5Quick REQUIRED)
12find_package(Qt5Quick REQUIRED)
13
13
14add_subdirectory(qml)
14add_subdirectory(qml)
15−add_subdirectory(Messaging)
16−add_subdirectory(Network)
17
15
18include_directories(
16include_directories(
19 ${CMAKE_CURRENT_SOURCE_DIR}
17 ${CMAKE_CURRENT_SOURCE_DIR}
plugins/Unity/Indicators/Messaging/CMakeLists.txtdeleted−1
@@ -1 +0,0 @@
1−add_subdirectory(qml)
plugins/Unity/Indicators/Messaging/qml/ActionTextField.qmldeleted−69
@@ -1,69 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−
24−Item {
25− id: textField
26− property alias text: replyField.text
27− property alias buttonText: sendButton.text
28− property bool activateEnabled: false
29−
30− signal activate(var value)
31−
32− TextField {
33− id: replyField
34−
35− anchors {
36− top: parent.top
37− bottom: parent.bottom
38− left: parent.left
39− right: sendButton.left
40− rightMargin: units.gu(1)
41− }
42− placeholderText: "Reply"
43− hasClearButton: false
44−
45− onEnabledChanged: {
46− //Make sure that the component lost focus when enabled = false,
47− //otherwise it will get focus again when enable = true
48− if (!enabled) {
49− focus = false;
50− }
51− }
52− }
53−
54− Button {
55− id: sendButton
56− anchors {
57− top: parent.top
58− bottom: parent.bottom
59− right: parent.right
60− }
61− width: units.gu(9)
62− enabled: replyField.text !== "" && textField.activateEnabled
63− color: enabled ? "#c94212" : "#bababa"
64−
65− onClicked: {
66− textField.activate(replyField.text);
67− }
68− }
69−}
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/Messaging/qml/GroupedMessage.qmldeleted−91
@@ -1,91 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−Indicators.BaseMenuItem {
26− id: groupedMessage
27−
28− property alias title: __title.text
29− property alias count: label.text
30− property string appIcon: "qrc:/indicators/artwork/messaging/default_app.svg"
31−
32− signal activateApp()
33− signal dismiss()
34−
35− implicitHeight: units.gu(10)
36−
37− Row {
38− anchors.fill: parent
39− anchors.margins: units.gu(2)
40− spacing: units.gu(4)
41−
42− UbuntuShape {
43− height: units.gu(6)
44− width: units.gu(6)
45− image: Image {
46− source: groupedMessage.appIcon
47− fillMode: Image.PreserveAspectFit
48− }
49− }
50−
51− Label {
52− id: __title
53− anchors.verticalCenter: parent.verticalCenter
54− color: "#e8e1d0"
55− font.weight: Font.DemiBold
56− fontSize: "medium"
57− }
58−
59− Label {
60− id: label
61− anchors.verticalCenter: parent.verticalCenter
62− width: parent.width - x
63− horizontalAlignment: Text.AlignRight
64− color: "#e8e1d0"
65− font.weight: Font.DemiBold
66− fontSize: "medium"
67− text: "0"
68− }
69− }
70−
71− Indicators.HLine {
72− anchors.top: parent.top
73− color: "#403b37"
74− }
75−
76− Indicators.HLine {
77− anchors.bottom: parent.bottom
78− color: "#060606"
79− }
80−
81− MouseArea {
82− anchors.fill: parent
83− onClicked: {
84− groupedMessage.activateApp();
85− }
86− }
87−
88− onItemRemoved: {
89− groupedMessage.dismiss();
90− }
91−}
plugins/Unity/Indicators/Messaging/qml/HeroMessage.qmldeleted−123
@@ -1,123 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−Indicators.BaseMenuItem {
26− id: heroMessage
27−
28− property alias heroMessageHeader: __heroMessageHeader
29− property real collapsedHeight: heroMessageHeader.y + heroMessageHeader.bodyBottom + units.gu(2)
30− property real expandedHeight: collapsedHeight
31−
32− property alias avatar: __heroMessageHeader.avatar
33− property alias appIcon: __heroMessageHeader.icon
34−
35− signal activateApp
36− signal dismiss
37−
38− removable: state !== "expanded"
39− implicitHeight: collapsedHeight
40−
41− Rectangle {
42− id: background
43− property real alpha: 0.0
44− anchors.fill: parent
45− color: Qt.rgba(1.0, 1.0, 1.0, alpha)
46− z: -1
47− }
48−
49− HeroMessageHeader {
50− id: __heroMessageHeader
51−
52− anchors.top: parent.top
53− anchors.left: parent.left
54− anchors.right: parent.right
55−
56− avatar: "qrc:/indicators/artwork/messaging/default_contact.png"
57− appIcon: icon
58−
59− state: heroMessage.state
60−
61− onAppIconClicked: {
62− deselectMenu();
63− heroMessage.activateApp();
64− }
65− }
66−
67− onClicked: {
68− if (menuSelected) {
69− deselectMenu();
70− } else {
71− selectMenu();
72− }
73− }
74−
75− Indicators.HLine {
76− id: __topHLine
77− anchors.top: parent.top
78− color: "#403b37"
79− }
80−
81− Indicators.HLine {
82− id: __bottomHLine
83− anchors.bottom: parent.bottom
84− color: "#060606"
85− }
86−
87− states: State {
88− name: "expanded"
89− when: menuSelected
90−
91− PropertyChanges {
92− target: heroMessage
93− implicitHeight: heroMessage.expandedHeight
94− }
95− PropertyChanges {
96− target: background
97− alpha: 0.05
98− }
99− PropertyChanges {
100− target: __topHLine
101− opacity: 0.0
102− }
103− PropertyChanges {
104− target: __bottomHLine
105− opacity: 0.0
106− }
107− }
108−
109− transitions: Transition {
110− ParallelAnimation {
111− NumberAnimation {
112− properties: "opacity,implicitHeight"
113− duration: 200
114− easing.type: Easing.OutQuad
115− }
116− ColorAnimation {}
117− }
118− }
119−
120− onItemRemoved: {
121− heroMessage.dismiss();
122− }
123−}
plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qmldeleted−161
@@ -1,161 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−
24−Item {
25− id: heroMessageHeader
26−
27− property alias avatar: avatarImage.source
28− property alias icon: iconImage.source
29− property alias appIcon: appIconImage.source
30− property alias titleText: __titleText
31− property alias subtitleText: __subtitleText
32− property alias bodyText: __bodyText
33− property real bodyBottom: bodyText.y + bodyText.height
34−
35− signal appIconClicked()
36−
37− height: units.gu(9)
38−
39− UbuntuShape {
40− id: avatarImageContainer
41− anchors {
42− top: parent.top
43− topMargin: units.gu(2)
44− left: parent.left
45− leftMargin: units.gu(2)
46− }
47− height: units.gu(6)
48− width: units.gu(6)
49− image: Image {
50− id: avatarImage
51− fillMode: Image.PreserveAspectFit
52− }
53− }
54−
55− Image {
56− id: iconImage
57− anchors {
58− top: parent.top
59− topMargin: units.gu(2)
60− left: avatarImageContainer.right
61− leftMargin: units.gu(1)
62− }
63− height: units.gu(1.5)
64− width: units.gu(2)
65− horizontalAlignment: Image.AlignHCenter
66− verticalAlignment: Image.AlignBottom
67− fillMode: Image.PreserveAspectFit
68− }
69−
70− Label {
71− id: __titleText
72− anchors {
73− baseline: iconImage.bottom
74− left: iconImage.right
75− leftMargin: units.gu(1)
76− right: __appIcon.left
77− rightMargin: units.gu(2)
78− }
79− elide: Text.ElideRight
80− color: "#e8e1d0"
81− font.weight: Font.DemiBold
82− fontSize: "medium"
83− }
84−
85− Label {
86− id: __subtitleText
87− anchors {
88− baseline: __titleText.baseline
89− baselineOffset: units.gu(2.5)
90− left: __titleText.left
91− right: __titleText.right
92− }
93− elide: Text.ElideRight
94− color: "#8f8f88"
95− fontSize: "small"
96− }
97−
98− Label {
99− id: __bodyText
100− anchors {
101− baseline: __subtitleText.baseline
102− baselineOffset: units.gu(2.5)
103− left: __titleText.left
104− right: parent.right
105− rightMargin: units.gu(2)
106− }
107− maximumLineCount: 2
108− wrapMode: Text.WordWrap
109− elide: Text.ElideRight
110− color: "#e8e1d0"
111− fontSize: "small"
112− }
113−
114− Item {
115− id: __appIcon
116− width: units.gu(7)
117− height: units.gu(7)
118− anchors {
119− top: parent.top
120− right: parent.right
121− }
122− opacity: 0.0
123− enabled: heroMessageHeader.state === "expanded"
124−
125− Image {
126− id: appIconImage
127− height: width
128− anchors {
129− left: parent.left
130− leftMargin: units.gu(2)
131− right: parent.right
132− rightMargin: units.gu(2)
133− topMargin: units.gu(1)
134− verticalCenter: parent.verticalCenter
135− }
136− fillMode: Image.PreserveAspectFit
137− }
138−
139− MouseArea {
140− anchors.fill: parent
141− onClicked: heroMessageHeader.appIconClicked()
142− }
143− }
144−
145− states: State {
146− name: "expanded"
147−
148− PropertyChanges {
149− target: __appIcon
150− opacity: 1.0
151− }
152− }
153−
154− transitions: Transition {
155− NumberAnimation {
156− property: "opacity"
157− duration: 200
158− easing.type: Easing.OutQuad
159− }
160− }
161−}
plugins/Unity/Indicators/Messaging/qml/QuickReply.qmldeleted−165
@@ -1,165 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−Item {
26− id: quickReply
27− property alias buttonText: actionTextField.buttonText
28− property real expandedHeight: childrenRect.height
29− property alias messages : messagelistRepeater.model
30− property alias replyEnabled: actionTextField.activateEnabled
31−
32− signal reply(var value)
33−
34− Item {
35− id: header
36− anchors.top: parent.top
37− anchors.left: parent.left
38− anchors.right: parent.right
39− height: units.gu(4)
40−
41− Row {
42− anchors {
43− fill: parent
44− leftMargin: units.gu(2)
45− rightMargin: units.gu(2)
46− topMargin: units.gu(1)
47− bottomMargin: units.gu(1)
48− }
49− spacing: units.gu(1)
50−
51− Image {
52− width: units.gu(2)
53− height: width
54− fillMode: Image.PreserveAspectFit
55− source: "qrc:/indicators/artwork/messaging/message_sms01_54px.png"
56− }
57−
58− Label {
59− height: parent.height
60− verticalAlignment: Text.AlignVCenter
61− fontSize: "small"
62− color: "#8f8f88"
63− text: "Quick reply with:"
64− }
65− }
66−
67− Indicators.HLine {
68− anchors.bottom: parent.bottom
69− color: "#20201F"
70− }
71− }
72−
73− Column {
74− id: messagelist
75− anchors {
76− left: parent.left
77− right: parent.right
78− top: header.bottom
79− }
80− height: childrenRect.height
81−
82− Repeater {
83− id: messagelistRepeater
84−
85− height: childrenRect.height
86−
87− Item {
88− width: messagelist.width
89− height: units.gu(5)
90−
91− Label {
92− id: __label
93−
94− anchors {
95− fill: parent
96− leftMargin: units.gu(2)
97− rightMargin: units.gu(2)
98− }
99− verticalAlignment: Text.AlignVCenter
100− fontSize: "medium"
101− color: "#e8e1d0"
102− text: modelData
103− }
104−
105− Indicators.HLine {
106− anchors.top: parent.top
107− color: "#464543"
108− }
109−
110− Indicators.HLine {
111− anchors.bottom: parent.bottom
112− color: "#20201F"
113− }
114−
115− MouseArea {
116− id: __mouseArea
117−
118− anchors.fill: parent
119− onClicked: {
120− actionTextField.text = modelData;
121− }
122− }
123−
124− Rectangle {
125− id: __mask
126−
127− anchors.fill: parent
128− color: "black"
129− opacity: __mouseArea.pressed ? 0.3 : 0.0
130− Behavior on opacity {
131− NumberAnimation {
132− duration: 200
133− easing.type: Easing.OutQuad
134− }
135− }
136− }
137− }
138−
139− }
140− }
141−
142− Item {
143− anchors.top: messagelist.bottom
144− anchors.left: parent.left
145− anchors.right: parent.right
146− height: units.gu(6)
147−
148− ActionTextField {
149− id: actionTextField
150−
151− anchors.fill: parent
152− anchors.margins: units.gu(1)
153− activateEnabled: replyEnabled
154−
155− onActivate: {
156− quickReply.reply(value)
157− }
158− }
159−
160− Indicators.HLine {
161− anchors.top: parent.top
162− color: "#464543"
163− }
164− }
165−}
plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qmldeleted−108
@@ -1,108 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1
24−import Utils 0.1 as Utils
25−
26−HeroMessage {
27− id: __heroMessage
28−
29− property string title: ""
30− property var time
31− property string message: ""
32−
33− property alias footer: footerLoader.sourceComponent
34−
35− expandedHeight: fullMessage.y + fullMessage.height + units.gu(2)
36− heroMessageHeader.titleText.text: title
37− heroMessageHeader.subtitleText.text: timeFormatter.timeString
38− heroMessageHeader.bodyText.text: message
39−
40− Item {
41− id: fullMessage
42−
43− anchors {
44− left: parent.left
45− leftMargin: units.gu(2)
46− right: parent.right
47− rightMargin: units.gu(2)
48− top: heroMessageHeader.bottom
49− }
50− height: childrenRect.height
51− opacity: 0.0
52− enabled: false
53−
54− Utils.TimeFormatter {
55− id: timeFormatter
56− time: __heroMessage.time
57− format: "hh:mm - MMM dd"
58− }
59−
60− Label {
61− id: bodyText
62− anchors {
63− top: parent.top
64− left: parent.left
65− right: parent.right
66− }
67− wrapMode: Text.WordWrap
68− elide: Text.ElideRight
69− color: "#e8e1d0"
70− fontSize: "medium"
71− text: heroMessageHeader.bodyText.text
72− }
73−
74− Loader {
75− id: footerLoader
76−
77− anchors {
78− top: bodyText.bottom
79− topMargin: units.gu(2)
80− left: parent.left
81− right: parent.right
82− }
83− height: item != undefined ? units.gu(4) : 0
84− }
85−
86− states: State {
87− name: "expanded"
88− when: __heroMessage.state === "expanded"
89−
90− PropertyChanges {
91− target: heroMessageHeader.bodyText
92− opacity: 0.0
93− }
94−
95− PropertyChanges {
96− target: fullMessage
97− opacity: 1.0
98− enabled: true
99− }
100− }
101− transitions: Transition {
102− NumberAnimation {
103− property: "opacity"
104− duration: 200
105− }
106− }
107− }
108−}
plugins/Unity/Indicators/Messaging/qml/SnapDecision.qmldeleted−167
@@ -1,167 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1
24−import Utils 0.1 as Utils
25−
26−HeroMessage {
27− id: snapDecision
28−
29− property string title: ""
30− property var time
31− property string message: ""
32−
33− property bool activateEnabled: true
34− property alias actionButtonText: actionButton.text
35−
36− property bool replyEnabled: true
37− property alias replyMessages: quickreply.messages
38− property alias replyButtonText: quickreply.buttonText
39−
40− expandedHeight: buttons.y + buttons.height + quickreply.height + units.gu(2)
41− heroMessageHeader.titleText.text: title
42− heroMessageHeader.subtitleText.text: message
43− heroMessageHeader.subtitleText.color: "#e8e1d0"
44− heroMessageHeader.bodyText.text: timeFormatter.timeString
45− heroMessageHeader.bodyText.color: "#8f8f88"
46−
47− signal activate
48− signal reply(string value)
49−
50− Item {
51− id: buttons
52−
53− anchors.left: parent.left
54− anchors.leftMargin: units.gu(2)
55− anchors.right: parent.right
56− anchors.rightMargin: units.gu(2)
57− anchors.top: heroMessageHeader.bottom
58− anchors.topMargin: units.gu(1)
59− height: units.gu(4)
60− opacity: 0.0
61−
62− Utils.TimeFormatter {
63− id: timeFormatter
64− time: snapDecision.time
65− format: "hh:mm - MMM dd"
66− }
67−
68− Button {
69− text: "Message"
70− color: "#bababa"
71− anchors.left: parent.left
72− anchors.top: parent.top
73− anchors.bottom: parent.bottom
74− width: (parent.width - units.gu(1)) / 2
75−
76− onClicked: {
77− if (quickreply.state === "") {
78− quickreply.state = "expanded";
79− } else {
80− quickreply.state = "";
81− }
82− }
83− }
84−
85− Button {
86− id: actionButton
87− text: "Call back"
88− color: enabled ? "#c94212" : "#bababa"
89− anchors.right: parent.right
90− anchors.top: parent.top
91− anchors.bottom: parent.bottom
92− width: (parent.width - units.gu(1)) / 2
93− enabled: snapDecision.activateEnabled
94−
95− onClicked: {
96− snapDecision.activate();
97− }
98− }
99−
100− states: State {
101− name: "expanded"
102− when: snapDecision.state === "expanded"
103−
104− PropertyChanges {
105− target: buttons
106− opacity: 1.0
107− }
108− }
109− transitions: Transition {
110− NumberAnimation {
111− property: "opacity"
112− duration: 200
113− easing.type: Easing.OutQuad
114− }
115− }
116− }
117−
118− QuickReply {
119− id: quickreply
120−
121− onReply: {
122− snapDecision.reply(value);
123− }
124−
125− messages: ""
126− buttonText: "Send"
127− anchors {
128− top: buttons.bottom
129− topMargin: units.gu(2)
130− left: parent.left
131− right: parent.right
132− }
133− height: 0
134− opacity: 0.0
135− enabled: false
136− replyEnabled: snapDecision.replyEnabled
137−
138− states: State {
139− name: "expanded"
140−
141− PropertyChanges {
142− target: quickreply
143− height: expandedHeight
144− opacity: 1.0
145− }
146−
147− PropertyChanges {
148− target: quickreply
149− enabled: true
150− }
151− }
152−
153− transitions: Transition {
154− NumberAnimation {
155− properties: "opacity,height"
156− duration: 200
157− easing.type: Easing.OutQuad
158− }
159− }
160− }
161−
162− onStateChanged: {
163− if (state === "") {
164− quickreply.state = "";
165− }
166− }
167−}
plugins/Unity/Indicators/Messaging/qml/TextMessage.qmldeleted−43
@@ -1,43 +0,0 @@
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− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−SimpleTextMessage {
26− id: simpleMessage
27−
28− property bool replyEnabled: false
29− property string replyButtonText: "Send"
30−
31− signal reply(string value)
32−
33− footer: ActionTextField {
34− anchors.fill: parent
35−
36− activateEnabled: simpleMessage.replyEnabled
37− buttonText: simpleMessage.replyButtonText
38−
39− onActivate: {
40− simpleMessage.reply(value);
41− }
42− }
43−}
plugins/Unity/Indicators/Messaging/qml/qmldirdeleted−12
@@ -1,12 +0,0 @@
1−module Unity.Indicators.Messaging
2−
3−ActionButton 0.1 ActionButton.qml
4−ActionTextField 0.1 ActionTextField.qml
5−GroupedMessage 0.1 GroupedMessage.qml
6−HeroMessage 0.1 HeroMessage.qml
7−HeroMessageHeader 0.1 HeroMessageHeader.qml
8−MessageMenuItemFactory 0.1 MessageMenuItemFactory.qml
9−QuickReply 0.1 QuickReply.qml
10−SimpleTextMessage 0.1 SimpleTextMessage.qml
11−SnapDecision 0.1 SnapDecision.qml
12−TextMessage 0.1 TextMessage.qml
plugins/Unity/Indicators/Network/CMakeLists.txtdeleted−1
@@ -1 +0,0 @@
1−add_subdirectory(qml)
plugins/Unity/Indicators/Network/qml/AccessPoint.qmldeleted−117
@@ -1,117 +0,0 @@
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.Indicators 0.1 as Indicators
24−
25−Indicators.BaseMenuItem {
26− id: menuItem
27− implicitHeight: units.gu(5.5)
28−
29− property bool checked: false
30− property bool secure: false
31− property bool adHoc: false
32− property int signalStrength: 0
33− property alias label: _label.text
34−
35− signal activate()
36−
37− onCheckedChanged: {
38− // Can't rely on binding. Checked is assigned on click.
39− checkBoxActive.checked = checked;
40− }
41−
42− onClicked: {
43− checkBoxActive.clicked();
44− }
45−
46− CheckBox {
47− id: checkBoxActive
48− height: units.gu(3)
49− width: units.gu(3)
50−
51− anchors {
52− left: parent.left
53− leftMargin: menuItem.__contentsMargins
54− verticalCenter: parent.verticalCenter
55− }
56−
57− onClicked: {
58− menuItem.activate();
59− }
60− }
61−
62− Image {
63− id: iconSignal
64−
65− width: height
66− height: Math.min(units.gu(5), parent.height - units.gu(1))
67− anchors {
68− left: checkBoxActive.right
69− leftMargin: units.gu(1)
70− verticalCenter: parent.verticalCenter
71− }
72−
73− source: {
74− var imageName = "nm-signal-100"
75−
76− if (adHoc) {
77− imageName = "nm-adhoc";
78− } else if (signalStrength == 0) {
79− imageName = "nm-signal-00";
80− } else if (signalStrength <= 25) {
81− imageName = "nm-signal-25";
82− } else if (signalStrength <= 50) {
83− imageName = "nm-signal-50";
84− } else if (signalStrength <= 75) {
85− imageName = "nm-signal-75";
86− }
87− return "image://theme/" + imageName;
88− }
89− }
90−
91− Label {
92− id: _label
93− anchors {
94− left: iconSignal.right
95− leftMargin: units.gu(1)
96− verticalCenter: parent.verticalCenter
97− right: iconSecure.visible ? iconSecure.left : parent.right
98− rightMargin: menuItem.__contentsMargins
99− }
100− elide: Text.ElideRight
101− opacity: label.enabled ? 1.0 : 0.5
102− }
103−
104− Image {
105− id: iconSecure
106− visible: secure
107− source: "qrc:/indicators/artwork/network/secure.svg"
108−
109− width: height
110− height: Math.min(units.gu(4), parent.height - units.gu(1))
111− anchors {
112− right: parent.right
113− rightMargin: units.gu(1)
114− verticalCenter: parent.verticalCenter
115− }
116− }
117−}
plugins/Unity/Indicators/Network/qml/CMakeLists.txtdeleted−5
@@ -1,5 +0,0 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
4−# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.Indicators.Network Unity/Indicators/Network)
plugins/Unity/Indicators/Network/qml/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Unity.Indicators.Network
2−
3−AccessPoint 0.1 AccessPoint.qml
plugins/Unity/Indicators/qml/BaseMenuItem.qmldeleted−38
@@ -1,38 +0,0 @@
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 menuSelected: false
28−
29− signal selectMenu()
30− signal deselectMenu()
31−
32− showDivider: false
33− __foregroundColor: "#e8e1d0" // FIXME not in palette yet
34−
35− backgroundIndicator: RemoveBackground {
36− state: baseMenu.swipingState
37− }
38−}
plugins/Unity/Indicators/qml/ButtonMenuItem.qmldeleted−44
@@ -1,44 +0,0 @@
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 Unity.Indicators 0.1 as Indicators
24−
25−BaseMenuItem {
26− id: menuItem
27− implicitHeight: units.gu(7)
28−
29− property alias buttonText: button.text
30−
31− signal activate()
32−
33− Button {
34− id: button
35− anchors.centerIn: parent
36− height: units.gu(4)
37− width: units.gu(16)
38− color: "#1b1817"
39−
40− onClicked: {
41− menuItem.activate();
42− }
43− }
44−}
plugins/Unity/Indicators/qml/DivMenuItem.qmldeleted−26
@@ -1,26 +0,0 @@
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" // FIXME not in palette yet
25− implicitHeight: units.gu(1)
26−}
plugins/Unity/Indicators/qml/FramedMenuItem.qmldeleted−39
@@ -1,39 +0,0 @@
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− implicitHeight: units.gu(7)
27−
28− iconFrame: false
29−
30− HLine {
31− anchors.top: parent.top
32− color: "#403b37" // FIXME not in palette yet
33− }
34−
35− HLine {
36− anchors.bottom: parent.bottom
37− color: "#060606" // FIXME not in palette yet
38− }
39−}
plugins/Unity/Indicators/qml/MenuItemFactory.qml+226−42
@@ -18,11 +18,10 @@
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import Unity.Indicators 0.1 as Indicators
21+import Ubuntu.Settings.Menus 0.1 as Menus
22−import Unity.Indicators.Network 0.1 as ICNetwork
23−import Unity.Indicators.Messaging 0.1 as ICMessaging
24import QMenuModel 0.1 as QMenuModel
22import QMenuModel 0.1 as QMenuModel
23+import Utils 0.1 as Utils
25−import Ubuntu.Components 0.1
24+import Ubuntu.Components.ListItems 0.1 as ListItems
26
25
27Item {
26Item {
28 id: menuFactory
27 id: menuFactory
@@ -33,12 +32,14 @@ Item {
33 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
32 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
34 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
33 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
35
34
36− "com.canonical.indicator.button" : buttonMenu,
35+ "com.canonical.indicator.button" : buttonMenu,
37− "com.canonical.indicator.div" : divMenu,
36+ "com.canonical.indicator.div" : separatorMenu,
38− "com.canonical.indicator.section" : sectionMenu,
37+ "com.canonical.indicator.section" : sectionMenu,
39− "com.canonical.indicator.progress" : progressMenu,
38+ "com.canonical.indicator.progress" : progressMenu,
40− "com.canonical.indicator.slider" : sliderMenu,
39+ "com.canonical.indicator.slider" : sliderMenu,
41− "com.canonical.indicator.switch" : switchMenu,
40+ "com.canonical.indicator.switch" : switchMenu,
41+ "com.canonical.indicator.alarm" : alarmMenu,
42+ "com.canonical.indicator.appointment" : appointmentMenu,
42
43
43 "com.canonical.indicator.messages.messageitem" : messageItem,
44 "com.canonical.indicator.messages.messageitem" : messageItem,
44 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
45 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
@@ -46,6 +47,9 @@ Item {
46 "com.canonical.unity.slider" : sliderMenu,
47 "com.canonical.unity.slider" : sliderMenu,
47 "com.canonical.unity.switch" : switchMenu,
48 "com.canonical.unity.switch" : switchMenu,
48
49
50+ "com.canonical.unity.media-player" : mediaPayerMenu,
51+ "com.canonical.unity.playback-item" : playbackItemMenu,
52+
49 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
53 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
50 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
54 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
51 }
55 }
@@ -58,15 +62,15 @@ Item {
58 }
62 }
59
63
60 Component {
64 Component {
61− id: divMenu;
65+ id: separatorMenu;
62− Indicators.DivMenuItem {
66+ Menus.SeparatorMenu {
63− objectName: "divMenu"
67+ objectName: "separatorMenu"
64 }
68 }
65 }
69 }
66
70
67 Component {
71 Component {
68 id: sliderMenu;
72 id: sliderMenu;
69− Indicators.SliderMenuItem {
73+ Menus.SliderMenu {
70 objectName: "sliderMenu"
74 objectName: "sliderMenu"
71 property QtObject menuData: null
75 property QtObject menuData: null
72 property var menuModel: menuFactory.menuModel
76 property var menuModel: menuFactory.menuModel
@@ -95,12 +99,12 @@ Item {
95 onMenuIndexChanged: {
99 onMenuIndexChanged: {
96 loadAttributes();
100 loadAttributes();
97 }
101 }
98− onChangeState: {
102+ onUpdated: {
99 menuModel.changeState(menuIndex, value);
103 menuModel.changeState(menuIndex, value);
100 }
104 }
101
105
102 function loadAttributes() {
106 function loadAttributes() {
103− if (!menuModel || menuIndex == undefined) return;
107+ if (!menuModel || menuIndex == -1) return;
104 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
108 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
105 'max-value': 'double',
109 'max-value': 'double',
106 'min-icon': 'icon',
110 'min-icon': 'icon',
@@ -111,7 +115,7 @@ Item {
111
115
112 Component {
116 Component {
113 id: buttonMenu;
117 id: buttonMenu;
114− Indicators.ButtonMenuItem {
118+ Menus.ButtonMenu {
115 objectName: "buttonMenu"
119 objectName: "buttonMenu"
116 property QtObject menuData: null
120 property QtObject menuData: null
117 property var menuModel: menuFactory.menuModel
121 property var menuModel: menuFactory.menuModel
@@ -120,7 +124,7 @@ Item {
120 buttonText: menuData && menuData.label || ""
124 buttonText: menuData && menuData.label || ""
121 enabled: menuData && menuData.sensitive || false
125 enabled: menuData && menuData.sensitive || false
122
126
123− onActivate: {
127+ onTriggered: {
124 menuModel.activate(menuIndex);
128 menuModel.activate(menuIndex);
125 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
129 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
126 }
130 }
@@ -128,18 +132,19 @@ Item {
128 }
132 }
129 Component {
133 Component {
130 id: sectionMenu;
134 id: sectionMenu;
131− Indicators.SectionMenuItem {
135+ Menus.SectionMenu {
132 objectName: "sectionMenu"
136 objectName: "sectionMenu"
133 property QtObject menuData: null
137 property QtObject menuData: null
134 property var menuIndex: undefined
138 property var menuIndex: undefined
135
139
136 text: menuData && menuData.label || ""
140 text: menuData && menuData.label || ""
141+ busy: false
137 }
142 }
138 }
143 }
139
144
140 Component {
145 Component {
141 id: progressMenu;
146 id: progressMenu;
142− Indicators.ProgressMenuItem {
147+ Menus.ProgressValueMenu {
143 objectName: "progressMenu"
148 objectName: "progressMenu"
144 property QtObject menuData: null
149 property QtObject menuData: null
145 property int menuIndex: -1
150 property int menuIndex: -1
@@ -153,7 +158,7 @@ Item {
153
158
154 Component {
159 Component {
155 id: standardMenu;
160 id: standardMenu;
156− Indicators.StandardMenuItem {
161+ ListItems.Standard {
157 objectName: "standardMenu"
162 objectName: "standardMenu"
158 property QtObject menuData: null
163 property QtObject menuData: null
159 property int menuIndex: -1
164 property int menuIndex: -1
@@ -161,19 +166,36 @@ Item {
161 text: menuData && menuData.label || ""
166 text: menuData && menuData.label || ""
162 iconSource: menuData && menuData.icon || ""
167 iconSource: menuData && menuData.icon || ""
163 enabled: menuData && menuData.sensitive || false
168 enabled: menuData && menuData.sensitive || false
164− checkable: menuData ? (menuData.isCheck || menuData.isRadio) : false
165− checked: checkable ? menuData.isToggled : false
166
169
167− onActivate: {
170+ onTriggered: {
171+ menuModel.activate(menuIndex);
172+ shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
173+ }
174+ }
175+ }
176+
177+ Component {
178+ id: checkableMenu;
179+ Menus.CheckableMenu {
180+ objectName: "checkableMenu"
181+ property QtObject menuData: null
182+ property int menuIndex: -1
183+
184+ text: menuData && menuData.label || ""
185+ enabled: menuData && menuData.sensitive || false
186+ checked: menuData && menuData.isToggled || false
187+
188+ onTriggered: {
168 menuModel.activate(menuIndex);
189 menuModel.activate(menuIndex);
169 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
190 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
170 }
191 }
171 }
192 }
172 }
193 }
173
194
195+
174 Component {
196 Component {
175 id: switchMenu;
197 id: switchMenu;
176− Indicators.SwitchMenuItem {
198+ Menus.SwitchMenu {
177 objectName: "switchMenu"
199 objectName: "switchMenu"
178 property QtObject menuData: null
200 property QtObject menuData: null
179 property int menuIndex: -1
201 property int menuIndex: -1
@@ -181,18 +203,94 @@ Item {
181 text: menuData && menuData.label || ""
203 text: menuData && menuData.label || ""
182 iconSource: menuData && menuData.icon || ""
204 iconSource: menuData && menuData.icon || ""
183 enabled: menuData && menuData.sensitive || false
205 enabled: menuData && menuData.sensitive || false
184− checked: menuData ? menuData.isToggled : false
206+ checked: menuData && menuData.isToggled || false
185
207
186− onActivate: {
208+ onTriggered: {
187 menuModel.activate(menuIndex);
209 menuModel.activate(menuIndex);
188 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
210 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
189 }
211 }
190 }
212 }
191 }
213 }
192
214
215+ Component {
216+ id: alarmMenu;
217+ Menus.EventMenu {
218+ objectName: "alarmMenu"
219+ property QtObject menuData: null
220+ property var menuModel: menuFactory.menuModel
221+ property int menuIndex: -1
222+ property var extendedData: menuData && menuData.ext || undefined
223+ // TODO - bug #1260728
224+ property var timeFormatter: Utils.GDateTimeFormatter {
225+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
226+ format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
227+ }
228+
229+ text: menuData && menuData.label || ""
230+ iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
231+ time: timeFormatter.timeString
232+ enabled: menuData && menuData.sensitive || false
233+
234+ onMenuModelChanged: {
235+ loadAttributes();
236+ }
237+ onMenuIndexChanged: {
238+ loadAttributes();
239+ }
240+ onTriggered: {
241+ menuModel.activate(menuIndex);
242+ }
243+
244+ function loadAttributes() {
245+ if (!menuModel || menuIndex == -1) return;
246+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
247+ 'x-canonical-time-format': 'string'});
248+ }
249+ }
250+ }
251+
252+ Component {
253+ id: appointmentMenu;
254+ Menus.EventMenu {
255+ objectName: "appointmentMenu"
256+ property QtObject menuData: null
257+ property var menuModel: menuFactory.menuModel
258+ property int menuIndex: -1
259+ property var extendedData: menuData && menuData.ext || undefined
260+ // TODO - bug #1260728
261+ property var timeFormatter: Utils.GDateTimeFormatter {
262+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
263+ format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
264+ }
265+
266+ text: menuData && menuData.label || ""
267+ iconSource: menuData && menuData.icon || "image://theme/calendar"
268+ time: timeFormatter.timeString
269+ eventColor: menu && menu.ext.hasOwnProperty("xCanonicalColor") ? menu.ext.xCanonicalColor : Qt.rgba(0.0, 0.0, 0.0, 0.0)
270+ enabled: menuData && menuData.sensitive || false
271+
272+ onMenuModelChanged: {
273+ loadAttributes();
274+ }
275+ onMenuIndexChanged: {
276+ loadAttributes();
277+ }
278+ onTriggered: {
279+ menuModel.activate(menuIndex);
280+ }
281+
282+ function loadAttributes() {
283+ if (!menuModel || menuIndex == -1) return;
284+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
285+ 'x-canonical-time': 'int64',
286+ 'x-canonical-time-format': 'string'});
287+ }
288+ }
289+ }
290+
193 Component {
291 Component {
194 id: wifiSection;
292 id: wifiSection;
195− Indicators.SectionMenuItem {
293+ Menus.SectionMenu {
196 objectName: "wifiSection"
294 objectName: "wifiSection"
197 property QtObject menuData: null
295 property QtObject menuData: null
198 property var menuModel: menuFactory.menuModel
296 property var menuModel: menuFactory.menuModel
@@ -210,7 +308,7 @@ Item {
210 }
308 }
211
309
212 function loadAttributes() {
310 function loadAttributes() {
213− if (!menuModel || menuIndex == undefined) return;
311+ if (!menuModel || menuIndex == -1) return;
214 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
312 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
215 }
313 }
216 }
314 }
@@ -218,7 +316,7 @@ Item {
218
316
219 Component {
317 Component {
220 id: accessPoint;
318 id: accessPoint;
221− ICNetwork.AccessPoint {
319+ Menus.AccessPointMenu {
222 objectName: "accessPoint"
320 objectName: "accessPoint"
223 property QtObject menuData: null
321 property QtObject menuData: null
224 property var menuModel: menuFactory.menuModel
322 property var menuModel: menuFactory.menuModel
@@ -231,11 +329,11 @@ Item {
231 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
329 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
232 }
330 }
233
331
234− label: menuData && menuData.label || ""
332+ text: menuData && menuData.label || ""
235 enabled: menuData && menuData.sensitive || false
333 enabled: menuData && menuData.sensitive || false
334+ checked: menuData && menuData.isToggled || false
236 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
335 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
237 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
336 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
238− checked: menuData ? menuData.isToggled : false
239 signalStrength: strengthAction.valid ? strengthAction.state : 0
337 signalStrength: strengthAction.valid ? strengthAction.state : 0
240
338
241 onMenuModelChanged: {
339 onMenuModelChanged: {
@@ -244,13 +342,13 @@ Item {
244 onMenuIndexChanged: {
342 onMenuIndexChanged: {
245 loadAttributes();
343 loadAttributes();
246 }
344 }
247− onActivate: {
345+ onTriggered: {
248 menuModel.activate(menuIndex);
346 menuModel.activate(menuIndex);
249 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
347 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
250 }
348 }
251
349
252 function loadAttributes() {
350 function loadAttributes() {
253− if (!menuModel || menuIndex == undefined) return;
351+ if (!menuModel || menuIndex == -1) return;
254 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
352 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
255 'x-canonical-wifi-ap-is-secure': 'bool',
353 'x-canonical-wifi-ap-is-secure': 'bool',
256 'x-canonical-wifi-ap-strength-action': 'string'});
354 'x-canonical-wifi-ap-strength-action': 'string'});
@@ -260,7 +358,7 @@ Item {
260
358
261 Component {
359 Component {
262 id: messageItem
360 id: messageItem
263− ICMessaging.MessageMenuItemFactory {
361+ MessageMenuItemFactory {
264 objectName: "messageItem"
362 objectName: "messageItem"
265 menuModel: menuFactory.menuModel
363 menuModel: menuFactory.menuModel
266 }
364 }
@@ -268,17 +366,18 @@ Item {
268
366
269 Component {
367 Component {
270 id: groupedMessage
368 id: groupedMessage
271− ICMessaging.GroupedMessage {
369+ Menus.GroupedMessageMenu {
272 objectName: "groupedMessage"
370 objectName: "groupedMessage"
273 property QtObject menuData: null
371 property QtObject menuData: null
274 property var menuModel: menuFactory.menuModel
372 property var menuModel: menuFactory.menuModel
275 property int menuIndex: -1
373 property int menuIndex: -1
276 property var extendedData: menuData && menuData.ext || undefined
374 property var extendedData: menuData && menuData.ext || undefined
277
375
278− title: menuData && menuData.label || ""
376+ text: menuData && menuData.label || ""
279− appIcon: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
377+ iconSource: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
280 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
378 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
281 enabled: menuData && menuData.sensitive || false
379 enabled: menuData && menuData.sensitive || false
380+ removable: true
282
381
283 onMenuModelChanged: {
382 onMenuModelChanged: {
284 loadAttributes();
383 loadAttributes();
@@ -286,21 +385,103 @@ Item {
286 onMenuIndexChanged: {
385 onMenuIndexChanged: {
287 loadAttributes();
386 loadAttributes();
288 }
387 }
289− onActivateApp: {
388+ onClicked: {
290 menuModel.activate(menuIndex, true);
389 menuModel.activate(menuIndex, true);
291 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
390 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
292 }
391 }
293− onDismiss: {
392+ onDismissed: {
294 menuModel.activate(menuIndex, false);
393 menuModel.activate(menuIndex, false);
295 }
394 }
296
395
297 function loadAttributes() {
396 function loadAttributes() {
298− if (!menuModel || menuIndex == undefined) return;
397+ if (!menuModel || menuIndex == -1) return;
299 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
398 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
300 }
399 }
301 }
400 }
302 }
401 }
303
402
403+ Component {
404+ id: mediaPayerMenu;
405+ Menus.MediaPlayerMenu {
406+ objectName: "mediaPayerMenu"
407+ property QtObject menuData: null
408+ property var menuModel: menuFactory.menuModel
409+ property int menuIndex: -1
410+ property var actionState: menuData && menuData.actionState || undefined
411+
412+ playerIcon: menuData && menuData.icon || ""
413+ playerName: menuData && menuData.label || ""
414+
415+ albumArt: getExtendedProperty(actionState, "art-url", "")
416+ song: getExtendedProperty(actionState, "title", "unknown")
417+ artist: getExtendedProperty(actionState, "artist", "unknown")
418+ album: getExtendedProperty(actionState, "album", "unknown")
419+ running: getExtendedProperty(actionState, "running", false)
420+ state: getExtendedProperty(actionState, "state", "")
421+ enabled: menuData && menuData.sensitive || false
422+
423+ onTriggered: {
424+ model.activate(modelIndex);
425+ }
426+ }
427+ }
428+
429+ Component {
430+ id: playbackItemMenu;
431+ Menus.PlaybackItemMenu {
432+ objectName: "playbackItemMenu"
433+ property QtObject menuData: null
434+ property var menuModel: menuFactory.menuModel
435+ property int menuIndex: -1
436+ property var extendedData: menuData && menuData.ext || undefined
437+
438+ property var playAction: QMenuModel.UnityMenuAction {
439+ model: menuModel
440+ index: menuIndex
441+ name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
442+ }
443+ property var nextAction: QMenuModel.UnityMenuAction {
444+ model: menuModel
445+ index: menuIndex
446+ name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
447+ }
448+ property var previousAction: QMenuModel.UnityMenuAction {
449+ model: menuModel
450+ index: menuIndex
451+ name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
452+ }
453+
454+ playing: playAction.state === "Playing"
455+ canPlay: playAction.valid
456+ canGoNext: nextAction.valid
457+ canGoPrevious: previousAction.valid
458+ enabled: menuData && menuData.sensitive || false
459+
460+ onPlay: {
461+ playAction.activate();
462+ }
463+ onNext: {
464+ nextAction.activate();
465+ }
466+ onPrevious: {
467+ previousAction.activate();
468+ }
469+ onMenuModelChanged: {
470+ loadAttributes();
471+ }
472+ onMenuIndexChanged: {
473+ loadAttributes();
474+ }
475+
476+ function loadAttributes() {
477+ if (!menuModel || menuIndex == -1) return;
478+ menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
479+ 'x-canonical-next-action': 'string',
480+ 'x-canonical-previous-action': 'string'});
481+ }
482+ }
483+ }
484+
304 function load(modelData) {
485 function load(modelData) {
305 if (modelData.type !== undefined) {
486 if (modelData.type !== undefined) {
306 var component = _map[modelData.type];
487 var component = _map[modelData.type];
@@ -308,8 +489,11 @@ Item {
308 return component;
489 return component;
309 }
490 }
310 }
491 }
492+ if (modelData.isCheck || modelData.isRadio) {
493+ return checkableMenu;
494+ }
311 if (modelData.isSeparator) {
495 if (modelData.isSeparator) {
312− return divMenu;
496+ return separatorMenu;
313 }
497 }
314 return standardMenu;
498 return standardMenu;
315 }
499 }
plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml → plugins/Unity/Indicators/qml/MessageMenuItemFactory.qmlrenamed+69−28
@@ -20,18 +20,29 @@
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 Ubuntu.Settings.Menus 0.1 as Menus
24import QMenuModel 0.1 as QMenuModel
24import QMenuModel 0.1 as QMenuModel
25+import Utils 0.1 as Utils
25
26
26−Indicators.BaseMenuItem {
27+Item {
27 id: messageFactoryItem
28 id: messageFactoryItem
28 property var menuModel: null
29 property var menuModel: null
29 property QtObject menuData: null
30 property QtObject menuData: null
30 property int menuIndex: -1
31 property int menuIndex: -1
31
32
33+ property bool selected: false
34+ signal menuSelected
35+ signal menuDeselected
36+
32 property var extendedData: menuData && menuData.ext || undefined
37 property var extendedData: menuData && menuData.ext || undefined
33 property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
38 property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
34
39
40+ // TODO - bug #1260728
41+ property var timeFormatter: Utils.TimeFormatter {
42+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
43+ format: "hh:mm - MMM dd"
44+ }
45+
35 onMenuModelChanged: {
46 onMenuModelChanged: {
36 loadAttributes();
47 loadAttributes();
37 }
48 }
@@ -40,8 +51,7 @@ Indicators.BaseMenuItem {
40 }
51 }
41
52
42 function loadAttributes() {
53 function loadAttributes() {
43− if (!menuModel || menuIndex == undefined) return;
54+ if (!menuModel || menuIndex == -1) return;
44−
45 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
55 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
46 'x-canonical-text': 'string',
56 'x-canonical-text': 'string',
47 'x-canonical-message-actions': 'variant',
57 'x-canonical-message-actions': 'variant',
@@ -67,34 +77,46 @@ Indicators.BaseMenuItem {
67
77
68 Component {
78 Component {
69 id: simpleTextMessage
79 id: simpleTextMessage
70− SimpleTextMessage {
80+ Menus.SimpleTextMessageMenu {
81+ id: message
71 objectName: "simpleTextMessage"
82 objectName: "simpleTextMessage"
72 // text
83 // text
73 title: menuData && menuData.label || ""
84 title: menuData && menuData.label || ""
74− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
85+ time: timeFormatter.timeString
75 message: getExtendedProperty(extendedData, "xCanonicalText", "")
86 message: getExtendedProperty(extendedData, "xCanonicalText", "")
76 // icons
87 // icons
77 avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
88 avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
78 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
89 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
79 // actions
90 // actions
80 enabled: menuData && menuData.sensitive || false
91 enabled: menuData && menuData.sensitive || false
92+ removable: !selected
93+ selected: messageFactoryItem.selected
81
94
82− onActivateApp: {
95+ onAppActivated: {
83 menuModel.activate(menuIndex, true);
96 menuModel.activate(menuIndex, true);
84 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
97 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
85 }
98 }
86− onDismiss: {
99+ onDismissed: {
87 menuModel.activate(menuIndex, false);
100 menuModel.activate(menuIndex, false);
88 }
101 }
102+ onClicked: {
103+ if (selected) {
104+ menuDeselected();
105+ } else {
106+ menuSelected();
107+ }
108+ }
89
109
90− menuSelected: messageFactoryItem.menuSelected
110+ backgroundIndicator: RemoveBackground {
91− onSelectMenu: messageFactoryItem.selectMenu()
111+ state: message.swipingState
92− onDeselectMenu: messageFactoryItem.deselectMenu()
112+ }
93 }
113 }
94 }
114 }
115+
95 Component {
116 Component {
96 id: textMessage
117 id: textMessage
97− TextMessage {
118+ Menus.TextMessageMenu {
119+ id: message
98 objectName: "textMessage"
120 objectName: "textMessage"
99 property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
121 property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
100
122
@@ -106,7 +128,7 @@ Indicators.BaseMenuItem {
106
128
107 // text
129 // text
108 title: menuData && menuData.label || ""
130 title: menuData && menuData.label || ""
109− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
131+ time: timeFormatter.timeString
110 message: getExtendedProperty(extendedData, "xCanonicalText", "")
132 message: getExtendedProperty(extendedData, "xCanonicalText", "")
111 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
133 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
112 // icons
134 // icons
@@ -115,26 +137,36 @@ Indicators.BaseMenuItem {
115 // actions
137 // actions
116 replyEnabled: replyAction.valid && replyAction.enabled
138 replyEnabled: replyAction.valid && replyAction.enabled
117 enabled: menuData && menuData.sensitive || false
139 enabled: menuData && menuData.sensitive || false
140+ removable: !selected
141+ selected: messageFactoryItem.selected
118
142
119− onActivateApp: {
143+ onAppActivated: {
120 menuModel.activate(menuIndex, true);
144 menuModel.activate(menuIndex, true);
121 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
145 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
122 }
146 }
123− onDismiss: {
147+ onDismissed: {
124 menuModel.activate(menuIndex, false);
148 menuModel.activate(menuIndex, false);
125 }
149 }
126− onReply: {
150+ onReplied: {
127 replyAction.activate(value);
151 replyAction.activate(value);
128 }
152 }
153+ onClicked: {
154+ if (selected) {
155+ menuDeselected();
156+ } else {
157+ menuSelected();
158+ }
159+ }
129
160
130− menuSelected: messageFactoryItem.menuSelected
161+ backgroundIndicator: RemoveBackground {
131− onSelectMenu: messageFactoryItem.selectMenu()
162+ state: message.swipingState
132− onDeselectMenu: messageFactoryItem.deselectMenu()
163+ }
133 }
164 }
134 }
165 }
135 Component {
166 Component {
136 id: snapDecision
167 id: snapDecision
137− SnapDecision {
168+ Menus.SnapDecisionMenu {
169+ id: message
138 objectName: "snapDecision"
170 objectName: "snapDecision"
139 property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
171 property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
140 property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
172 property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
@@ -152,7 +184,7 @@ Indicators.BaseMenuItem {
152
184
153 // text
185 // text
154 title: menuData && menuData.label || ""
186 title: menuData && menuData.label || ""
155− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
187+ time: timeFormatter.timeString
156 message: getExtendedProperty(extendedData, "xCanonicalText", "")
188 message: getExtendedProperty(extendedData, "xCanonicalText", "")
157 actionButtonText: getExtendedProperty(activateActionDescription, "label", "Call back")
189 actionButtonText: getExtendedProperty(activateActionDescription, "label", "Call back")
158 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
190 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
@@ -164,24 +196,33 @@ Indicators.BaseMenuItem {
164 activateEnabled: activateAction.valid && activateAction.enabled
196 activateEnabled: activateAction.valid && activateAction.enabled
165 replyEnabled: replyAction.valid && replyAction.enabled
197 replyEnabled: replyAction.valid && replyAction.enabled
166 enabled: menuData && menuData.sensitive || false
198 enabled: menuData && menuData.sensitive || false
199+ removable: !selected
200+ selected: messageFactoryItem.selected
167
201
168− onActivateApp: {
202+ onAppActivated: {
169 menuModel.activate(menuIndex, true);
203 menuModel.activate(menuIndex, true);
170 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
204 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
171 }
205 }
172− onDismiss: {
206+ onDismissed: {
173 menuModel.activate(menuIndex, false);
207 menuModel.activate(menuIndex, false);
174 }
208 }
175− onActivate: {
209+ onActivated: {
176 activateAction.activate();
210 activateAction.activate();
177 }
211 }
178− onReply: {
212+ onReplied: {
179 replyAction.activate(value);
213 replyAction.activate(value);
180 }
214 }
215+ onClicked: {
216+ if (selected) {
217+ menuDeselected();
218+ } else {
219+ menuSelected();
220+ }
221+ }
181
222
182− menuSelected: messageFactoryItem.menuSelected
223+ backgroundIndicator: RemoveBackground {
183− onSelectMenu: messageFactoryItem.selectMenu()
224+ state: message.swipingState
184− onDeselectMenu: messageFactoryItem.deselectMenu()
225+ }
185 }
226 }
186 }
227 }
187 }
228 }
plugins/Unity/Indicators/qml/ProgressMenuItem.qmldeleted−38
@@ -1,38 +0,0 @@
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−import Unity.Indicators 0.1 as Indicators
23−
24−FramedMenuItem {
25− id: menuItem
26−
27− property int value : 0.0
28−
29− control: Label {
30− id: progress
31− anchors.verticalCenter: parent.verticalCenter
32− anchors.right: parent.right
33−
34− text: menuItem.value + " %"
35− fontSize: "medium"
36− color: "#e8e1d0"
37− }
38−}
plugins/Unity/Indicators/qml/SectionMenuItem.qmldeleted−54
@@ -1,54 +0,0 @@
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−BaseMenuItem {
25− id: menuItem
26− property alias text: header.text
27− property bool busy: false
28−
29− implicitHeight: text !== "" ? header.height : 0
30−
31− ListItem.Header {
32− id: header
33−
34− height: units.gu(4)
35− anchors {
36− left: parent.left
37− right: parent.right
38− top: parent.top
39− }
40− visible: text != ""
41−
42− ActivityIndicator {
43− id: indicator
44− running: busy
45− anchors {
46− margins: units.gu(0.5)
47− right: parent.right
48− }
49− height: parent.height - (anchors.margins * 2)
50− width: height
51− anchors.verticalCenter: parent.verticalCenter
52− }
53− }
54−}
plugins/Unity/Indicators/qml/SliderMenuItem.qmldeleted−106
@@ -1,106 +0,0 @@
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−import Unity.Indicators 0.1 as Indicators
24−
25−FramedMenuItem {
26− id: menuItem
27−
28− property alias minimumValue: slider.minimumValue
29− property alias maximumValue: slider.maximumValue
30− property double value: 0.0
31−
32− property alias minIcon: leftImage.source
33− property alias maxIcon: rightImage.source
34−
35− property QtObject d: QtObject {
36− property bool enableValueConnection: true
37− }
38−
39− signal changeState(real value)
40−
41− onValueChanged: {
42− // TODO: look into adding a component to manage bi-directional bindings.
43− var oldEnable = d.enableValueConnection
44− d.enableValueConnection = false;
45−
46− // Can't rely on binding. Slider value is assigned by user slide.
47− slider.value = value;
48−
49− d.enableValueConnection = oldEnable;
50− }
51−
52− control: Item {
53− id: row
54− width: menuItem.text ? units.gu(20) : menuItem.width - (2 * menuItem.__contentsMargins)
55− height: slider.height
56−
57− Image {
58− id: leftImage
59− visible: status === Image.Ready
60− anchors.left: row.left
61− anchors.verticalCenter: row.verticalCenter
62− height: units.gu(4)
63− width: height
64− }
65−
66− Components.Slider {
67− id: slider
68− anchors {
69− left: leftImage.visible ? leftImage.right : row.left
70− right: rightImage.visible ? rightImage.left : row.right
71− leftMargin: leftImage.visible ? units.gu(0.5) : 0
72− rightMargin: rightImage.visible ? units.gu(0.5) : 0
73− }
74− live: true
75−
76− Component.onCompleted: {
77− value = menuItem.value
78− }
79−
80− minimumValue: 0.0
81− maximumValue: 0.1
82−
83− // FIXME - to be deprecated in Ubuntu.Components.
84− // Use this to disable the label, since there is not way to do it on the component.
85− function formatValue(v) {
86− return "";
87− }
88−
89− Connections {
90− target: d.enableValueConnection ? slider : null
91− onValueChanged: {
92− menuItem.changeState(slider.value);
93− }
94− }
95− }
96−
97− Image {
98− id: rightImage
99− visible: status === Image.Ready
100− anchors.right: row.right
101− anchors.verticalCenter: row.verticalCenter
102− height: units.gu(4)
103− width: height
104− }
105− }
106−}
plugins/Unity/Indicators/qml/StandardMenuItem.qmldeleted−71
@@ -1,71 +0,0 @@
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−
27− property bool checkable: false
28− property bool checked: false
29−
30− signal activate()
31−
32− // FIXME : need a radio button from sdk
33− // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211866
34− onCheckableChanged: {
35− if (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−}
plugins/Unity/Indicators/qml/SwitchMenuItem.qmldeleted−53
@@ -1,53 +0,0 @@
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 Unity.Indicators 0.1 as Indicators
24−
25−FramedMenuItem {
26− id: menuItem
27−
28− property bool checked: false
29−
30− signal activate()
31−
32− onCheckedChanged: {
33− // Can't rely on binding. Checked is assigned on click.
34− switcher.checked = checked;
35− }
36−
37− control: Switch {
38− id: switcher
39−
40− Component.onCompleted: {
41− checked = menuItem.checked;
42− }
43−
44− anchors.verticalCenter: parent.verticalCenter
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− }
52− }
53−}
plugins/Unity/Indicators/qml/qmldir+1−12
@@ -2,20 +2,9 @@ module Unity.Indicators
2plugin IndicatorsQml
2plugin IndicatorsQml
3typeinfo plugin.qmltypes
3typeinfo plugin.qmltypes
4
4
5−BaseMenuItem 0.1 BaseMenuItem.qml
6−ButtonMenuItem 0.1 ButtonMenuItem.qml
7CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
5CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
8−DivMenuItem 0.1 DivMenuItem.qml
9−FramedMenuItem 0.1 FramedMenuItem.qml
10−HLine 0.1 HLine.qml
11IndicatorBase 0.1 IndicatorBase.qml
6IndicatorBase 0.1 IndicatorBase.qml
12−MenuActionBinding 0.1 MenuActionBinding.qml
13MenuItemFactory 0.1 MenuItemFactory.qml
7MenuItemFactory 0.1 MenuItemFactory.qml
14−ProgressMenuItem 0.1 ProgressMenuItem.qml
8+MessageMenuItemFactory 0.1 MessageMenuItemFactory.qml
15−SectionMenuItem 0.1 SectionMenuItem.qml
16−SliderMenuItem 0.1 SliderMenuItem.qml
17−StandardMenuItem 0.1 StandardMenuItem.qml
18−SwitchMenuItem 0.1 SwitchMenuItem.qml
19−
20
9
21internal RemoveBackground RemoveBackground.qml
10internal RemoveBackground RemoveBackground.qml
plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.pngdeleted

Binary file not shown.

plugins/Unity/Indicators/resources/artwork/network/secure.svgdeleted−71
@@ -1,71 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<!-- Created with Inkscape (http://www.inkscape.org/) -->
3−
4−<svg
5− xmlns:dc="http://purl.org/dc/elements/1.1/"
6− xmlns:cc="http://creativecommons.org/ns#"
7− xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8− xmlns:svg="http://www.w3.org/2000/svg"
9− xmlns="http://www.w3.org/2000/svg"
10− xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11− xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12− width="64"
13− height="64"
14− id="svg2986"
15− version="1.1"
16− inkscape:version="0.48.4 r9939"
17− sodipodi:docname="secure.svg">
18− <defs
19− id="defs2988" />
20− <sodipodi:namedview
21− id="base"
22− pagecolor="#ffffff"
23− bordercolor="#666666"
24− borderopacity="1.0"
25− inkscape:pageopacity="0.0"
26− inkscape:pageshadow="2"
27− inkscape:zoom="7.9180415"
28− inkscape:cx="7.5048745"
29− inkscape:cy="29.401628"
30− inkscape:current-layer="layer1"
31− showgrid="true"
32− inkscape:grid-bbox="true"
33− inkscape:document-units="px"
34− inkscape:snap-grids="false"
35− inkscape:window-width="1549"
36− inkscape:window-height="876"
37− inkscape:window-x="51"
38− inkscape:window-y="24"
39− inkscape:window-maximized="1">
40− <inkscape:grid
41− type="xygrid"
42− id="grid3012"
43− empspacing="5"
44− visible="true"
45− enabled="true"
46− snapvisiblegridlinesonly="true" />
47− </sodipodi:namedview>
48− <metadata
49− id="metadata2991">
50− <rdf:RDF>
51− <cc:Work
52− rdf:about="">
53− <dc:format>image/svg+xml</dc:format>
54− <dc:type
55− rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
56− <dc:title />
57− </cc:Work>
58− </rdf:RDF>
59− </metadata>
60− <g
61− id="layer1"
62− inkscape:label="Layer 1"
63− inkscape:groupmode="layer"
64− transform="translate(0,32)">
65− <path
66− inkscape:connector-curvature="0"
67− d="M 29.999999,-18 C 25.568001,-18 22,-14.432 22,-10 v 6 h -2 c -1.107999,0 -2,0.892 -2,2 v 18 c 0,1.108 0.892001,2 2,2 h 24 c 1.108,0 2,-0.892 2,-2 V -2 c 0,-1.108 -0.892,-2 -2,-2 h -2 v -6 c 0,-4.432 -3.568001,-8 -8.000001,-8 h -4 z m 0,4 h 4 c 2.216,0 4,1.784 4,4 v 6 H 26.000001 v -6 c 0,-2.216 1.784,-4 3.999998,-4 z"
68− style="fill:#dfdbd2;fill-rule:evenodd"
69− id="path8" />
70− </g>
71−</svg>
plugins/Unity/Indicators/resources/indicators.qrc−2
@@ -1,8 +1,6 @@
1<RCC>
1<RCC>
2 <qresource prefix="/indicators">
2 <qresource prefix="/indicators">
3− <file>artwork/network/secure.svg</file>
4 <file>artwork/messaging/default_contact.png</file>
3 <file>artwork/messaging/default_contact.png</file>
5 <file>artwork/messaging/default_app.svg</file>
4 <file>artwork/messaging/default_app.svg</file>
6− <file>artwork/messaging/message_sms01_54px.png</file>
7 </qresource>
5 </qresource>
8</RCC>
6</RCC>
po/bg.po+39−31
@@ -8,113 +8,121 @@ msgstr ""
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-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-06-27 00:06+0000\n"
11+"PO-Revision-Date: 2014-01-28 19:22+0000\n"
12−"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
12+"Last-Translator: Atanas Kovachki <Unknown>\n"
13−"<miroslav.hadzhiev@gmail.com>\n"
14"Language-Team: Bulgarian <bg@li.org>\n"
13"Language-Team: Bulgarian <bg@li.org>\n"
15"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
18"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-29 06:08+0000\n"
20−"X-Generator: Launchpad (build 16877)\n"
19+"X-Generator: Launchpad (build 16916)\n"
21
20
22#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
23msgid "Skip intro"
22msgid "Skip intro"
24−msgstr ""
23+msgstr "Пропусни интрото"
25
24
26#: Components/EdgeDemo.qml:112
25#: Components/EdgeDemo.qml:112
27msgid "Right edge"
26msgid "Right edge"
28−msgstr ""
27+msgstr "Десен край"
29
28
30#: Components/EdgeDemo.qml:113
29#: Components/EdgeDemo.qml:113
31msgid "Try swiping from the right edge to unlock the phone"
30msgid "Try swiping from the right edge to unlock the phone"
32msgstr ""
31msgstr ""
32+"Опитайте се да приплъзнете пръста си от десния край към левия, за да "
33+"отключите телефона"
33
34
34#: Components/EdgeDemo.qml:144
35#: Components/EdgeDemo.qml:144
35msgid "Top edge"
36msgid "Top edge"
36−msgstr ""
37+msgstr "Горен край"
37
38
38#: Components/EdgeDemo.qml:145
39#: Components/EdgeDemo.qml:145
39msgid "Try swiping from the top edge to access the indicators"
40msgid "Try swiping from the top edge to access the indicators"
40msgstr ""
41msgstr ""
42+"Опитайте се да приплъзнете пръста си от горния край към долния, за да "
43+"получите достъп до индикаторите"
41
44
42#: Components/EdgeDemo.qml:170
45#: Components/EdgeDemo.qml:170
43msgid "Close"
46msgid "Close"
44−msgstr ""
47+msgstr "Затвори"
45
48
46#: Components/EdgeDemo.qml:171
49#: Components/EdgeDemo.qml:171
47msgid "Swipe up again to close the settings screen"
50msgid "Swipe up again to close the settings screen"
48msgstr ""
51msgstr ""
52+"Отново приплъзнете пръста си нагоре за да затворите екрана с настройките"
49
53
50#: Components/EdgeDemo.qml:198
54#: Components/EdgeDemo.qml:198
51msgid "Left edge"
55msgid "Left edge"
52−msgstr ""
56+msgstr "Ляв край"
53
57
54#: Components/EdgeDemo.qml:199
58#: Components/EdgeDemo.qml:199
55msgid "Swipe from the left to reveal the launcher for quick access to apps"
59msgid "Swipe from the left to reveal the launcher for quick access to apps"
56msgstr ""
60msgstr ""
61+"Приплъзнете пръста си от левия край към десния, за да отворите стартера за "
62+"бърз достъп до приложенията"
57
63
58#: Components/EdgeDemo.qml:226
64#: Components/EdgeDemo.qml:226
59msgid "Well done"
65msgid "Well done"
60−msgstr ""
66+msgstr "Великолепно"
61
67
62#: Components/EdgeDemo.qml:227
68#: Components/EdgeDemo.qml:227
63msgid ""
69msgid ""
64"You have now mastered the edge gestures and can start using the "
70"You have now mastered the edge gestures and can start using the "
65"phone<br><br>Tap anywhere to start"
71"phone<br><br>Tap anywhere to start"
66msgstr ""
72msgstr ""
73+"Сега, когато сте научили основните движения, можете да започнете да "
74+"използвате телефона си.<br><br>Натиснете някъде за да започнете"
67
75
68#: Components/PageHeader.qml:364
76#: Components/PageHeader.qml:364
69msgid "Recent searches"
77msgid "Recent searches"
70−msgstr "Скорошни търсения"
78+msgstr "Последни търсения"
71
79
72#: Dash/Apps/AppPreview.qml:135
80#: Dash/Apps/AppPreview.qml:135
73msgid "Rate this"
81msgid "Rate this"
74−msgstr ""
82+msgstr "Оценете това"
75
83
76#. TRANSLATORS: Number of persons who rated this app/video/whatever
84#. TRANSLATORS: Number of persons who rated this app/video/whatever
77#: Dash/Previews/Header.qml:93
85#: Dash/Previews/Header.qml:93
78#, qt-format
86#, qt-format
79msgid "(%1)"
87msgid "(%1)"
80−msgstr ""
88+msgstr "(%1)"
81
89
82#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
90#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
83#: Dash/Previews/Header.qml:105
91#: Dash/Previews/Header.qml:105
84#, qt-format
92#, qt-format
85msgid "%1 review"
93msgid "%1 review"
86msgid_plural "%1 reviews"
94msgid_plural "%1 reviews"
87−msgstr[0] ""
95+msgstr[0] "%1 отзив"
88−msgstr[1] ""
96+msgstr[1] "%1 отзива"
89
97
90#: Dash/Previews/Reviews.qml:74
98#: Dash/Previews/Reviews.qml:74
91msgid "Add a review"
99msgid "Add a review"
92−msgstr ""
100+msgstr "Добави отзив"
93
101
94#: Dash/Previews/Reviews.qml:86
102#: Dash/Previews/Reviews.qml:86
95msgid "Review"
103msgid "Review"
96−msgstr ""
104+msgstr "Отзив"
97
105
98#: Dash/Previews/Reviews.qml:121
106#: Dash/Previews/Reviews.qml:121
99msgid "Send"
107msgid "Send"
100−msgstr ""
108+msgstr "Изпрати"
101
109
102#: Dash/Previews/Reviews.qml:139
110#: Dash/Previews/Reviews.qml:139
103msgid "Comments:"
111msgid "Comments:"
104−msgstr ""
112+msgstr "Коментари:"
105
113
106#: Greeter/Lockscreen.qml:149
114#: Greeter/Lockscreen.qml:149
107msgid "Emergency Call"
115msgid "Emergency Call"
108−msgstr ""
116+msgstr "Спешно повикване"
109
117
110#: Greeter/PassphraseLockscreen.qml:59
118#: Greeter/PassphraseLockscreen.qml:59
111#, qt-format
119#, qt-format
112msgid "Hello %1"
120msgid "Hello %1"
113−msgstr ""
121+msgstr "Здравей, %1"
114
122
115#: Greeter/PassphraseLockscreen.qml:59
123#: Greeter/PassphraseLockscreen.qml:59
116msgid "Hello"
124msgid "Hello"
117−msgstr ""
125+msgstr "Здравей"
118
126
119#: Hud/HudParametrizedActionsPage.qml:132
127#: Hud/HudParametrizedActionsPage.qml:132
120msgid "Confirm"
128msgid "Confirm"
@@ -122,23 +130,23 @@ msgstr "Потвърди"
122
130
123#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
131#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
124msgid "Type or say a command"
132msgid "Type or say a command"
125−msgstr ""
133+msgstr "Въведете или кажете команда"
126
134
127#: Hud/Hud.qml:84
135#: Hud/Hud.qml:84
128msgid "Loading. Please Wait..."
136msgid "Loading. Please Wait..."
129−msgstr ""
137+msgstr "Зарежда се. Моля, почакайте..."
130
138
131#: Hud/Hud.qml:89
139#: Hud/Hud.qml:89
132msgid "Speak Now..."
140msgid "Speak Now..."
133−msgstr ""
141+msgstr "Говорете сега..."
134
142
135#: Hud/Hud.qml:94
143#: Hud/Hud.qml:94
136msgid "Speaking..."
144msgid "Speaking..."
137−msgstr ""
145+msgstr "Говорете..."
138
146
139#: Notifications/NotificationMenuItemFactory.qml:89
147#: Notifications/NotificationMenuItemFactory.qml:89
140msgid "Show password"
148msgid "Show password"
141−msgstr ""
149+msgstr "Покажи паролата"
142
150
143#: Panel/SearchIndicator.qml:27
151#: Panel/SearchIndicator.qml:27
144msgid "Search"
152msgid "Search"
@@ -147,13 +155,13 @@ msgstr "Търсене"
147#: plugins/Unity/Launcher/launcheritem.cpp:43
155#: plugins/Unity/Launcher/launcheritem.cpp:43
148#: plugins/Unity/Launcher/launcheritem.cpp:73
156#: plugins/Unity/Launcher/launcheritem.cpp:73
149msgid "Lock to Launcher"
157msgid "Lock to Launcher"
150−msgstr ""
158+msgstr "Заключване към панела"
151
159
152#: plugins/Unity/Launcher/launcheritem.cpp:73
160#: plugins/Unity/Launcher/launcheritem.cpp:73
153msgid "Unlock from Launcher"
161msgid "Unlock from Launcher"
154−msgstr ""
162+msgstr "Отключи от панела за стартиране"
155
163
156#: Shell.qml:439
164#: Shell.qml:439
157#, qt-format
165#, qt-format
158msgid "Please enter %1"
166msgid "Please enter %1"
159−msgstr ""
167+msgstr "Моля, въведете %1"
qml/Components/DragHandle.qml+7−7
@@ -97,7 +97,7 @@ EdgeDragArea {
97 // Private stuff
97 // Private stuff
98 QtObject {
98 QtObject {
99 id: d
99 id: d
100− property var previousStatus: undefined
100+ property var previousStatus: DirectionalDragArea.WaitingForTouch
101 property real startValue
101 property real startValue
102 property real minValue: Direction.isPositive(direction) ? startValue
102 property real minValue: Direction.isPositive(direction) ? startValue
103 : startValue - maxTotalDragDistance
103 : startValue - maxTotalDragDistance
@@ -193,14 +193,14 @@ EdgeDragArea {
193 d.rollbackDrag();
193 d.rollbackDrag();
194 }
194 }
195 } else /* Undecided || Recognized */ {
195 } else /* Undecided || Recognized */ {
196− if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
196+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch) {
197− d.previousStatus === undefined) {
198 dragEvaluator.reset();
197 dragEvaluator.reset();
199 d.startValue = parent[d.targetProp];
198 d.startValue = parent[d.targetProp];
200− }
199+
201− if (hintDisplacement > 0) {
200+ if (hintDisplacement > 0) {
202− hintingAnimation.targetValue = d.startValue;
201+ hintingAnimation.targetValue = d.startValue;
203− hintingAnimation.start();
202+ hintingAnimation.start();
203+ }
204 }
204 }
205 }
205 }
206
206
qml/Components/FilterGrid.qml+6−8
@@ -35,19 +35,17 @@ 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− readonly property bool expandable: model.count > collapsedRowCount * iconTileGrid.columns
38+ readonly property bool expandable: model.count > rowsWhenCollapsed * 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 property int uncollapsedRowCount: Math.ceil(model.count / columns)
44 property int uncollapsedRowCount: Math.ceil(model.count / columns)
45− readonly property int collapsedHeight: {
45+ /* Never show more rows than model would fill up. */
46− return iconTileGrid.contentHeightForRows(Math.min(collapsedRowCount, Math.ceil(model.count / columns)))
46+ readonly property int rowsWhenCollapsed: Math.min(collapsedRowCount, uncollapsedRowCount)
47− }
47+ readonly property int collapsedHeight: iconTileGrid.contentHeightForRows(rowsWhenCollapsed)
48− readonly property int uncollapsedHeight: {
49− return iconTileGrid.contentHeightForRows(uncollapsedRowCount)
48+ readonly property int uncollapsedHeight: iconTileGrid.contentHeightForRows(uncollapsedRowCount)
50− }
51
49
52 property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
50 property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
53 property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
51 property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
@@ -106,7 +104,7 @@ Item {
106
104
107 model: LimitProxyModel {
105 model: LimitProxyModel {
108 model: root.model
106 model: root.model
109− limit: (filter && !filterAnimation.running) ? collapsedRowCount * iconTileGrid.columns : -1
107+ limit: (filter && !filterAnimation.running) ? rowsWhenCollapsed * iconTileGrid.columns : -1
110 }
108 }
111 }
109 }
112}
110}
qml/Components/PageHeader.qml+1
@@ -145,6 +145,7 @@ Item {
145 anchors.fill: parent
145 anchors.fill: parent
146 anchors.margins: units.gu(1)
146 anchors.margins: units.gu(1)
147
147
148+ inputMethodHints: Qt.ImhNoPredictiveText
148 hasClearButton: false
149 hasClearButton: false
149
150
150 primaryItem: AbstractButton {
151 primaryItem: AbstractButton {
qml/Components/ResponsiveGridView.qml+1−1
@@ -72,7 +72,7 @@ Item {
72
72
73 function columnsForSpacing(spacing) {
73 function columnsForSpacing(spacing) {
74 // minimum margin is half of the spacing
74 // minimum margin is half of the spacing
75− return Math.max(1, Math.floor((parent.width - spacing/2) / (delegateWidth + spacing)));
75+ return Math.max(1, Math.floor(parent.width / (delegateWidth + spacing)));
76 }
76 }
77
77
78 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
78 property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
qml/Dash/Card.qml+11−2
@@ -38,9 +38,17 @@ Item {
38 UbuntuShape {
38 UbuntuShape {
39 id: artShape
39 id: artShape
40 objectName: "artShape"
40 objectName: "artShape"
41+ width: {
42+ if (!visible) return 0
41− width: image.fillMode === Image.PreserveAspectCrop || aspect < image.aspect ? image.width : height * image.aspect
43+ return image.fillMode === Image.PreserveAspectCrop || aspect < image.aspect ? image.width : height * image.aspect
44+ }
45+ height: {
46+ if (!visible) return 0
42− height: image.fillMode === Image.PreserveAspectCrop || aspect > image.aspect ? image.height : width / image.aspect
47+ return image.fillMode === Image.PreserveAspectCrop || aspect > image.aspect ? image.height : width / image.aspect
48+ }
43 anchors.horizontalCenter: template && template["card-layout"] === "horizontal" ? undefined : parent.horizontalCenter
49 anchors.horizontalCenter: template && template["card-layout"] === "horizontal" ? undefined : parent.horizontalCenter
50+ anchors.left: template && template["card-layout"] === "horizontal" ? parent.left : undefined
51+ visible: cardData && cardData["art"] || false
44
52
45 property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1
53 property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1
46
54
@@ -79,5 +87,6 @@ Item {
79 maximumLineCount: 5
87 maximumLineCount: 5
80 elide: Text.ElideRight
88 elide: Text.ElideRight
81 text: cardData && cardData["summary"] || ""
89 text: cardData && cardData["summary"] || ""
90+ height: text ? implicitHeight : 0
82 }
91 }
83}
92}
qml/Dash/CardHeader.qml+5−1
@@ -56,9 +56,9 @@ Item {
56
56
57 Label {
57 Label {
58 id: titleLabel
58 id: titleLabel
59+ objectName: "titleLabel"
59 anchors { left: parent.left; right: parent.right }
60 anchors { left: parent.left; right: parent.right }
60 elide: Text.ElideRight
61 elide: Text.ElideRight
61− objectName: "titleLabel"
62 font.weight: Font.DemiBold
62 font.weight: Font.DemiBold
63 wrapMode: Text.Wrap
63 wrapMode: Text.Wrap
64 maximumLineCount: 2
64 maximumLineCount: 2
@@ -66,6 +66,7 @@ Item {
66
66
67 Label {
67 Label {
68 id: subtitleLabel
68 id: subtitleLabel
69+ objectName: "subtitleLabel"
69 anchors { left: parent.left; right: parent.right }
70 anchors { left: parent.left; right: parent.right }
70 elide: Text.ElideRight
71 elide: Text.ElideRight
71 visible: titleLabel.text && text
72 visible: titleLabel.text && text
@@ -90,6 +91,7 @@ Item {
90 elide: Text.ElideRight
91 elide: Text.ElideRight
91 font.weight: Font.DemiBold
92 font.weight: Font.DemiBold
92 color: Theme.palette.selected.foreground
93 color: Theme.palette.selected.foreground
94+ visible: text
93 }
95 }
94
96
95 Label {
97 Label {
@@ -98,6 +100,7 @@ Item {
98 width: parent.labelWidth
100 width: parent.labelWidth
99 elide: Text.ElideRight
101 elide: Text.ElideRight
100 horizontalAlignment: parent.labels === 3 ? Text.AlignHCenter : Text.AlignRight
102 horizontalAlignment: parent.labels === 3 ? Text.AlignHCenter : Text.AlignRight
103+ visible: text
101 }
104 }
102
105
103 Label {
106 Label {
@@ -105,6 +108,7 @@ Item {
105 width: parent.labelWidth
108 width: parent.labelWidth
106 elide: Text.ElideRight
109 elide: Text.ElideRight
107 horizontalAlignment: Text.AlignRight
110 horizontalAlignment: Text.AlignRight
111+ visible: text
108 }
112 }
109 }
113 }
110 }
114 }
qml/Dash/GenericScopeView.qml+7−1
@@ -141,6 +141,7 @@ FocusScope {
141 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
141 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
142 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
142 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
143 readonly property string category: categoryId
143 readonly property string category: categoryId
144+ readonly property var item: rendererLoader.item
144
145
145 Loader {
146 Loader {
146 id: rendererLoader
147 id: rendererLoader
@@ -248,8 +249,10 @@ FocusScope {
248 }
249 }
249 }
250 }
250 }
251 }
252+ onOriginYChanged: rendererLoader.updateDelegateCreationRange();
251 onContentYChanged: rendererLoader.updateDelegateCreationRange();
253 onContentYChanged: rendererLoader.updateDelegateCreationRange();
252 onHeightChanged: rendererLoader.updateDelegateCreationRange();
254 onHeightChanged: rendererLoader.updateDelegateCreationRange();
255+ onContentHeightChanged: rendererLoader.updateDelegateCreationRange();
253 }
256 }
254
257
255 function updateDelegateCreationRange() {
258 function updateDelegateCreationRange() {
@@ -261,7 +264,7 @@ FocusScope {
261 return;
264 return;
262 }
265 }
263
266
264− if (item.hasOwnProperty("delegateCreationBegin")) {
267+ if (item && item.hasOwnProperty("delegateCreationBegin")) {
265 if (baseItem.y + baseItem.height <= 0) {
268 if (baseItem.y + baseItem.height <= 0) {
266 // Not visible (item at top of the list)
269 // Not visible (item at top of the list)
267 item.delegateCreationBegin = baseItem.height
270 item.delegateCreationBegin = baseItem.height
@@ -277,6 +280,9 @@ FocusScope {
277 }
280 }
278 }
281 }
279 }
282 }
283+
284+ onHeightChanged: rendererLoader.updateDelegateCreationRange();
285+ onYChanged: rendererLoader.updateDelegateCreationRange();
280 }
286 }
281
287
282 sectionProperty: "name"
288 sectionProperty: "name"
qml/Panel/IndicatorItem.qml+1−1
@@ -29,7 +29,7 @@ Item {
29 property string identifier
29 property string identifier
30
30
31 opacity: dimmed ? 0.4 : 1
31 opacity: dimmed ? 0.4 : 1
32− Behavior on opacity { StandardAnimation {} }
32+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } }
33
33
34 width: loader.item ? loader.item.width : 0
34 width: loader.item ? loader.item.width : 0
35
35
qml/Panel/IndicatorRow.qml+73−113
@@ -22,11 +22,10 @@ import "../Components"
22Item {
22Item {
23 id: indicatorRow
23 id: indicatorRow
24
24
25− property QtObject currentItem : null
25+ readonly property alias currentItem : itemView.currentItem
26− readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
26+ readonly property alias currentItemIndex: itemView.currentIndex
27− property alias row: row
27+ readonly property alias row: itemView
28 property QtObject indicatorsModel: null
28 property QtObject indicatorsModel: null
29− property var visibleIndicators: undefined
30 property int overFlowWidth: width
29 property int overFlowWidth: width
31 property bool showAll: false
30 property bool showAll: false
32 property real currentItemOffset: 0.0
31 property real currentItemOffset: 0.0
@@ -40,9 +39,15 @@ Item {
40 setCurrentItem(0);
39 setCurrentItem(0);
41 }
40 }
42
41
42+ function setCurrentItemIndex(index) {
43+ itemView.currentIndex = index;
44+ }
45+
43− function setCurrentItem(index) {
46+ function setCurrentItem(item) {
44− if (currentItemIndex !== index) {
47+ if (item && item.hasOwnProperty("ownIndex")) {
45− currentItem = rowRepeater.itemAt(index);
48+ itemView.currentIndex = item.ownIndex;
49+ } else {
50+ itemView.currentIndex = -1;
46 }
51 }
47 }
52 }
48
53
@@ -55,122 +60,75 @@ Item {
55 }
60 }
56 }
61 }
57
62
58− Row {
63+ ListView {
59− id: row
64+ id: itemView
65+ objectName: "indicatorRowItems"
66+ interactive: false
67+ model: indicatorsModel ? indicatorsModel : null
60
68
61− width: children.width
69+ width: childrenRect.width
62− height: parent.height
70+ height: indicatorRow.height
63 anchors.right: parent.right
71 anchors.right: parent.right
72+ orientation: ListView.Horizontal
64
73
65− Repeater {
74+ property int lastCount: 0
66− id: rowRepeater
75+ onCountChanged: {
67− objectName: "rowRepeater"
76+ if (lastCount < count) {
68− model: indicatorsModel ? indicatorsModel : undefined
77+ showAll = true;
78+ allVisible.start();
79+ }
80+ lastCount = count;
81+ }
69
82
83+ delegate: Item {
84+ id: itemWrapper
85+ objectName: "item" + index
86+ height: indicatorRow.height
87+ width: indicatorItem.width
88+ opacity: 1 - indicatorRow.unitProgress
89+ y: 0
90+ state: "standard"
91+
70− property int lastCount: 0
92+ property int ownIndex: index
71− onCountChanged: {
93+ property bool highlighted: indicatorRow.unitProgress > 0 ? ListView.isCurrentItem : false
72− if (lastCount < count) {
94+ property bool dimmed: indicatorRow.unitProgress > 0 ? !ListView.isCurrentItem : false
73− showAll = true;
95+
74− allVisible.start();
96+ property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
75− }
97+ property bool overflow: row.width - itemWrapper.x > overFlowWidth
76− lastCount = count;
98+
99+ IndicatorItem {
100+ id: indicatorItem
101+ identifier: model.identifier
102+ height: parent.height
103+
104+ dimmed: itemWrapper.dimmed
105+
106+ widgetSource: model.widgetSource
107+ indicatorProperties : model.indicatorProperties
77 }
108 }
78
109
79− Item {
110+ states: [
80− id: itemWrapper
111+ State {
81− height: indicatorRow.height
82− width: indicatorItem.width
83− visible: indicatorItem.indicatorVisible
84− opacity: 1.0 * opacityMultiplier
85− y: 0
86− state: "standard"
112+ name: "standard"
87−
113+ when: !hidden && !overflow && !highlighted
88− property int ownIndex: index
114+ },
89− property bool highlighted: indicatorRow.state != "initial" ? ownIndex == indicatorRow.currentItemIndex : false
115+ State {
90− property bool dimmed: indicatorRow.state != "initial" ? ownIndex != indicatorRow.currentItemIndex : false
116+ name: "highlighted"
91−
117+ when: highlighted
92− property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
118+ PropertyChanges { target: itemWrapper; opacity: 1.0 }
93− property bool overflow: row.width - itemWrapper.x > overFlowWidth
119+ },
94− property real opacityMultiplier: highlighted ? 1 : (1 - indicatorRow.unitProgress)
120+ State {
95−
121+ name: "hidden"
96− IndicatorItem {
122+ when: hidden || overflow
97− id: indicatorItem
123+ PropertyChanges { target: itemWrapper; opacity: 0.0 }
98− identifier: model.identifier
99− height: parent.height
100−
101− dimmed: itemWrapper.dimmed
102−
103− widgetSource: model.widgetSource
104− indicatorProperties : model.indicatorProperties
105−
106− Component.onCompleted: {
107− updateVisiblility();
108− }
109− onIndicatorVisibleChanged: {
110− updateVisiblility();
111−
112− if (indicatorVisible) {
113− showAll = true;
114− allVisible.start();
115− }
116− }
117−
118− function updateVisiblility() {
119− if (visibleIndicators == undefined) {
120− visibleIndicators = {}
121− }
122− indicatorRow.visibleIndicators[model.identifier] = indicatorVisible;
123−
124− // removed current index?
125− if (indicatorRow.currentItemIndex === index && !indicatorVisible) {
126− // find the next closest visible indicator (after current, else before)
127− var newIndex = -1;
128− for (var i = index+1; i < rowRepeater.count; i++) {
129− if (indicatorRow.visibleIndicators[i] === undefined || indicatorRow.visibleIndicators[model.identifier]) {
130− newIndex = i;
131− break;
132− }
133− }
134− if (newIndex === -1) {
135− for (i = index - 1; i >= 0; i--) {
136− if (indicatorRow.visibleIndicators[i] === undefined || indicatorRow.visibleIndicators[model.identifier]) {
137− newIndex = i;
138− break;
139− }
140− }
141− }
142− indicatorRow.setCurrentItem(newIndex);
143− }
144−
145− indicatorRow.visibleIndicatorsChanged();
146− }
147 }
124 }
125+ ]
148
126
149− states: [
150− State {
151− name: "standard"
152− when: !hidden && !overflow
153− },
154− State {
155− name: "overflow"
156− when: hidden || overflow
157− PropertyChanges { target: itemWrapper; opacity: 0.0 }
158− }
159− ]
160−
161− transitions: [
162− Transition {
163− UbuntuNumberAnimation {
164− target: itemWrapper
165− property: "opacity"
166− duration: UbuntuAnimation.BriskDuration
127+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } }
167− }
168− }
169− ]
170− }
171 }
128 }
172 }
129 }
173
130
131+
174 Rectangle {
132 Rectangle {
175 id: highlight
133 id: highlight
176 color: Theme.palette.selected.foreground
134 color: Theme.palette.selected.foreground
@@ -178,7 +136,9 @@ Item {
178 height: units.dp(2)
136 height: units.dp(2)
179 anchors.top: row.bottom
137 anchors.top: row.bottom
180 visible: indicatorRow.currentItem != null
138 visible: indicatorRow.currentItem != null
139+
181− x: row.x + (indicatorRow.currentItem != null ? indicatorRow.currentItem.x + centerOffset : 0)
140+ property real intendedX: row.x + (indicatorRow.currentItem != null ? indicatorRow.currentItem.x + centerOffset : 0)
141+ x: intendedX >= row.x ? (intendedX + width <= row.x + row.width ? intendedX : row.x + row.width - width) : row.x // listview boundaries
182 width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0
142 width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0
183
143
184 property real centerOffset: {
144 property real centerOffset: {
qml/Panel/Indicators.qml+18−28
@@ -21,6 +21,7 @@ import Unity.Indicators 0.1 as Indicators
21
21
22import "../Components"
22import "../Components"
23import "../Components/ListItems"
23import "../Components/ListItems"
24+import "Indicators"
24
25
25Showable {
26Showable {
26 id: indicators
27 id: indicators
@@ -31,7 +32,7 @@ Showable {
31 property alias overFlowWidth: indicatorRow.overFlowWidth
32 property alias overFlowWidth: indicatorRow.overFlowWidth
32 property alias showAll: indicatorRow.showAll
33 property alias showAll: indicatorRow.showAll
33
34
34− property int hintValue
35+ readonly property real hintValue: panelHeight + menuContent.headerHeight
35 readonly property int lockThreshold: openedHeight / 2
36 readonly property int lockThreshold: openedHeight / 2
36 property bool fullyOpened: height == openedHeight
37 property bool fullyOpened: height == openedHeight
37 property bool partiallyOpened: height > panelHeight && !fullyOpened
38 property bool partiallyOpened: height > panelHeight && !fullyOpened
@@ -39,7 +40,7 @@ Showable {
39 property bool contentEnabled: true
40 property bool contentEnabled: true
40 property bool initalizeItem: true
41 property bool initalizeItem: true
41 readonly property alias content: menuContent
42 readonly property alias content: menuContent
42− property real unitProgress: 0.0
43+ property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
43
44
44 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
45 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
45 // use its own values. Need to ask design about this.
46 // use its own values. Need to ask design about this.
@@ -128,7 +129,7 @@ Showable {
128
129
129 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
130 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
130 // get the current delegate
131 // get the current delegate
131− currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
132+ currentItem = indicatorRow.row.itemAt(rowCoordinates.x, 0);
132 if (currentItem) {
133 if (currentItem) {
133 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
134 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
134 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
135 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
@@ -143,7 +144,7 @@ Showable {
143 }
144 }
144 }
145 }
145 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) {
146 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) {
146− indicatorRow.currentItem = currentItem;
147+ indicatorRow.setCurrentItem(currentItem);
147 }
148 }
148
149
149 // need to re-init the distanceFromRightEdge for offset calculation
150 // need to re-init the distanceFromRightEdge for offset calculation
@@ -151,7 +152,7 @@ Showable {
151 distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width);
152 distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width);
152 }
153 }
153 indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2);
154 indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2);
154− } else {
155+ } else if (initalizeItem) {
155 indicatorRow.setDefaultItem();
156 indicatorRow.setDefaultItem();
156 indicatorRow.currentItemOffset = 0;
157 indicatorRow.currentItemOffset = 0;
157 }
158 }
@@ -179,6 +180,10 @@ Showable {
179 source: "graphics/VerticalDivider.png"
180 source: "graphics/VerticalDivider.png"
180 }
181 }
181
182
183+ VisibleIndicators {
184+ id: visibleIndicators
185+ }
186+
182 MenuContent {
187 MenuContent {
183 id: menuContent
188 id: menuContent
184 objectName: "menuContent"
189 objectName: "menuContent"
@@ -189,7 +194,7 @@ Showable {
189 top: indicatorRow.bottom
194 top: indicatorRow.bottom
190 bottom: handle.top
195 bottom: handle.top
191 }
196 }
192− indicatorsModel: indicatorsModel
197+ indicatorsModel: visibleIndicators.model
193 clip: !indicators.fullyOpened
198 clip: !indicators.fullyOpened
194 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
199 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
195 enabled: contentEnabled
200 enabled: contentEnabled
@@ -220,13 +225,9 @@ Showable {
220 right: parent.right
225 right: parent.right
221 bottom: parent.bottom
226 bottom: parent.bottom
222 }
227 }
223− height: get_height()
228+ height: Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0)
224 clip: height < handleImage.height
229 clip: height < handleImage.height
225
230
226− function get_height() {
227− return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0);
228− }
229−
230 BorderImage {
231 BorderImage {
231 id: handleImage
232 id: handleImage
232 source: "graphics/handle.sci"
233 source: "graphics/handle.sci"
@@ -246,10 +247,6 @@ Showable {
246 anchors.fill: indicatorRow
247 anchors.fill: indicatorRow
247 }
248 }
248
249
249− Indicators.IndicatorsModel {
250− id: indicatorsModel
251− }
252−
253 IndicatorRow {
250 IndicatorRow {
254 id: indicatorRow
251 id: indicatorRow
255 objectName: "indicatorRow"
252 objectName: "indicatorRow"
@@ -258,18 +255,10 @@ Showable {
258 right: parent.right
255 right: parent.right
259 }
256 }
260 height: indicators.panelHeight
257 height: indicators.panelHeight
261− indicatorsModel: indicatorsModel
258+ indicatorsModel: visibleIndicators.model
262 state: indicators.state
259 state: indicators.state
263 unitProgress: indicators.unitProgress
260 unitProgress: indicators.unitProgress
264
261
265− onVisibleIndicatorsChanged: {
266− // need to do it here so we can control sequence
267− if (visibleIndicators !== undefined) {
268− menuContent.visibleIndicators = visibleIndicators;
269− menuContent.setCurrentMenuIndex(currentItemIndex);
270− }
271− }
272−
273 EdgeDragArea {
262 EdgeDragArea {
274 id: rowDragArea
263 id: rowDragArea
275 anchors.fill: indicatorRow
264 anchors.fill: indicatorRow
@@ -303,6 +292,7 @@ Showable {
303 onRunningChanged: {
292 onRunningChanged: {
304 if (showAnimation.running) {
293 if (showAnimation.running) {
305 indicators.state = "commit";
294 indicators.state = "commit";
295+ indicatorRow.currentItemOffset = 0;
306 }
296 }
307 }
297 }
308 }
298 }
@@ -313,7 +303,7 @@ Showable {
313 if (hideAnimation.running) {
303 if (hideAnimation.running) {
314 indicators.state = "initial";
304 indicators.state = "initial";
315 initalizeItem = true;
305 initalizeItem = true;
316− menuContent.animateNextMenuChange = false;
306+ indicatorRow.currentItemOffset = 0;
317 }
307 }
318 }
308 }
319 }
309 }
@@ -331,7 +321,7 @@ Showable {
331 if (!oldActive) return;
321 if (!oldActive) return;
332 d.enableIndexChangeSignal = false;
322 d.enableIndexChangeSignal = false;
333
323
334− indicatorRow.setCurrentItem(menuContent.currentMenuIndex);
324+ indicatorRow.setCurrentItemIndex(menuContent.currentMenuIndex);
335
325
336 d.enableIndexChangeSignal = oldActive;
326 d.enableIndexChangeSignal = oldActive;
337 }
327 }
@@ -344,7 +334,7 @@ Showable {
344 if (!oldActive) return;
334 if (!oldActive) return;
345 d.enableIndexChangeSignal = false;
335 d.enableIndexChangeSignal = false;
346
336
347− menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex);
337+ menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex, fullyOpened || partiallyOpened);
348
338
349 d.enableIndexChangeSignal = oldActive;
339 d.enableIndexChangeSignal = oldActive;
350 }
340 }
@@ -439,6 +429,6 @@ Showable {
439
429
440 Component.onCompleted: initialise();
430 Component.onCompleted: initialise();
441 function initialise() {
431 function initialise() {
442− indicatorsModel.load();
432+ visibleIndicators.load();
443 }
433 }
444}
434}
qml/Panel/Indicators/DefaultIndicatorPage.qml+9−5
@@ -138,10 +138,14 @@ Indicators.IndicatorBase {
138 sourceComponent: factory.load(model)
138 sourceComponent: factory.load(model)
139
139
140 onLoaded: {
140 onLoaded: {
141+ if (item.hasOwnProperty("selected")) {
142+ item.selected = mainMenu.selectedIndex == index;
143+ }
141 if (item.hasOwnProperty("menuSelected")) {
144 if (item.hasOwnProperty("menuSelected")) {
142− item.menuSelected = mainMenu.selectedIndex == index;
143− item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
145+ item.menuSelected.connect(function() { mainMenu.selectedIndex = index; });
146+ }
147+ if (item.hasOwnProperty("menuDeselected")) {
144− item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
148+ item.menuDeselected.connect(function() { mainMenu.selectedIndex = -1; });
145 }
149 }
146 if (item.hasOwnProperty("menuData")) {
150 if (item.hasOwnProperty("menuData")) {
147 item.menuData = Qt.binding(function() { return model; });
151 item.menuData = Qt.binding(function() { return model; });
@@ -162,8 +166,8 @@ Indicators.IndicatorBase {
162 Connections {
166 Connections {
163 target: mainMenu
167 target: mainMenu
164 onSelectedIndexChanged: {
168 onSelectedIndexChanged: {
165− if (loader.item && loader.item.hasOwnProperty("menuSelected")) {
169+ if (loader.item && loader.item.hasOwnProperty("selected")) {
166− loader.item.menuSelected = mainMenu.selectedIndex == index;
170+ loader.item.selected = mainMenu.selectedIndex == index;
167 }
171 }
168 }
172 }
169 }
173 }
plugins/Unity/Indicators/qml/HLine.qml → qml/Panel/Indicators/IndicatorDelegate.qmlrenamed+12−7
@@ -14,16 +14,21 @@
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>
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import Ubuntu.Components 0.1
21+import Unity.Indicators 0.1 as Indicators
22
22
23−Rectangle {
23+Indicators.IndicatorBase {
24− height: units.dp(1)
24+ enabled: false
25− anchors {
25+
26− left: parent.left
26+ onRootActionStateChanged: {
27− right: parent.right
27+ if (rootActionState == undefined) {
28+ enabled = false;
29+ return;
30+ }
31+
32+ enabled = rootActionState.visible;
28 }
33 }
29}
34}
qml/Panel/Indicators/VisibleIndicators.qmlnew file+84
@@ -0,0 +1,84 @@
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+import Utils 0.1
23+
24+Item {
25+ property SortFilterProxyModel model: filterModel
26+
27+ SortFilterProxyModel {
28+ id: filterModel
29+ filterRole: Indicators.IndicatorsModelRole.IsVisible
30+ filterRegExp: RegExp("^true$")
31+ dynamicSortFilter: true
32+
33+ model: Indicators.VisibleIndicatorsModel {
34+ id: visibleIndicatorsModel
35+ model: indicatorsModel
36+ }
37+ }
38+
39+
40+ Indicators.IndicatorsModel {
41+ id: indicatorsModel
42+ }
43+
44+ Repeater {
45+ id: repeater
46+ model: indicatorsModel
47+
48+ property var visibleIndicators: undefined
49+ onVisibleIndicatorsChanged: {
50+ if (visibleIndicators !== undefined) {
51+ visibleIndicatorsModel.visible = visibleIndicators;
52+ }
53+ }
54+
55+ delegate: IndicatorDelegate {
56+ id: item
57+ objectName: model.identifier + "-delegate"
58+ Component.onCompleted: {
59+ for(var pName in indicatorProperties) {
60+ if (item.hasOwnProperty(pName)) {
61+ item[pName] = indicatorProperties[pName];
62+ }
63+ }
64+ updateVisibility();
65+ }
66+
67+ onEnabledChanged: {
68+ updateVisibility()
69+ }
70+
71+ function updateVisibility() {
72+ if (repeater.visibleIndicators === undefined) {
73+ repeater.visibleIndicators = {}
74+ }
75+ repeater.visibleIndicators[model.identifier] = enabled;
76+ repeater.visibleIndicatorsChanged();
77+ }
78+ }
79+ }
80+
81+ function load() {
82+ indicatorsModel.load();
83+ }
84+}
qml/Panel/Indicators/client/IndicatorsList.qml+14−13
@@ -40,24 +40,25 @@ Page {
40 anchors.fill: parent
40 anchors.fill: parent
41 model: indicatorsModel
41 model: indicatorsModel
42
42
43− delegate: Indicators.FramedMenuItem {
43+ delegate: Rectangle {
44+ color: "#221e1c"
45+
44 anchors.left: parent.left
46 anchors.left: parent.left
45 anchors.right: parent.right
47 anchors.right: parent.right
46− objectName: identifier
48+ height: menuItem.height
47−
48− text: identifier
49
49
50− onClicked: {
50+ ListItem.Standard {
51− var new_page = Qt.createComponent("IndicatorsPage.qml");
51+ id: menuItem
52− page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
52+ anchors.left: parent.left
53− }
53+ anchors.right: parent.right
54+ objectName: identifier
54
55
55− Rectangle {
56+ text: identifier
56− id: background
57
57
58− anchors.fill: parent
58+ onClicked: {
59− color: "#221e1c"
59+ var new_page = Qt.createComponent("IndicatorsPage.qml");
60− z: -1
60+ page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
61+ }
61 }
62 }
62 }
63 }
63 }
64 }
qml/Panel/MenuContent.qml+13−26
@@ -28,26 +28,22 @@ MainView {
28
28
29 property QtObject indicatorsModel: null
29 property QtObject indicatorsModel: null
30 property bool __contentActive: false
30 property bool __contentActive: false
31− readonly property int currentMenuIndex : filteredIndicators.mapToSource(tabs.selectedTabIndex)
31+ readonly property int currentMenuIndex: tabs.selectedTabIndex
32 backgroundColor: "#221e1c" // FIXME not in palette yet
32 backgroundColor: "#221e1c" // FIXME not in palette yet
33 property int contentReleaseInterval: 20000
33 property int contentReleaseInterval: 20000
34 property bool activeHeader: false
34 property bool activeHeader: false
35− property alias visibleIndicators: visibleIndicatorsModel.visible
35+ property real headerHeight: tabs.tabBar.height
36− property bool animateNextMenuChange: false
37
36
38 width: units.gu(40)
37 width: units.gu(40)
39 height: units.gu(42)
38 height: units.gu(42)
40
39
41− function setCurrentMenuIndex(index) {
40+ function setCurrentMenuIndex(index, animate) {
42− var filteredIndex = filteredIndicators.mapFromSource(index);
43−
44− if (tabs.selectedTabIndex !== filteredIndex) {
41+ if (tabs.selectedTabIndex !== index) {
45− if (tabs.selectedTabIndex === -1 || !animateNextMenuChange) {
42+ if (tabs.selectedTabIndex === -1 || !animate) {
46 tabs.tabBar.animate = false;
43 tabs.tabBar.animate = false;
47 }
44 }
48− tabs.selectedTabIndex = filteredIndex;
45+ tabs.selectedTabIndex = index;
49 tabs.tabBar.animate = true;
46 tabs.tabBar.animate = true;
50− animateNextMenuChange = true;
51 }
47 }
52 }
48 }
53
49
@@ -67,29 +63,14 @@ MainView {
67 tabs.tabBar.alwaysSelectionMode = activeHeader;
63 tabs.tabBar.alwaysSelectionMode = activeHeader;
68 }
64 }
69
65
70− SortFilterProxyModel {
71− id: filteredIndicators
72− model: visibleIndicatorsModel
73− dynamicSortFilter: true
74−
75− filterRole: Indicators.IndicatorsModelRole.IsVisible
76− filterRegExp: RegExp("^true$")
77− }
78−
79− Indicators.VisibleIndicatorsModel {
80− id: visibleIndicatorsModel
81− model: indicatorsModel
82− }
83−
84 Tabs {
66 Tabs {
85 id: tabs
67 id: tabs
86 objectName: "tabs"
68 objectName: "tabs"
87 anchors.fill: parent
69 anchors.fill: parent
88− selectedTabIndex: -1
89
70
90 Repeater {
71 Repeater {
91 id: repeater
72 id: repeater
92− model: filteredIndicators
73+ model: content.indicatorsModel ? content.indicatorsModel : null
93 objectName: "tabsRepeater"
74 objectName: "tabsRepeater"
94
75
95 // FIXME: This is needed because tabs dont handle repeaters well.
76 // FIXME: This is needed because tabs dont handle repeaters well.
@@ -145,6 +126,12 @@ MainView {
145 property: "title"
126 property: "title"
146 value: loader.item && loader.item.hasOwnProperty("title") && loader.item.title !== "" ? loader.item.title : model.identifier
127 value: loader.item && loader.item.hasOwnProperty("title") && loader.item.title !== "" ? loader.item.title : model.identifier
147 }
128 }
129+
130+ Binding {
131+ target: loader.item
132+ property: "objectName"
133+ value: identifier + "-page"
134+ }
148 }
135 }
149 }
136 }
150 }
137 }
qml/Panel/Panel.qml+1−4
@@ -50,7 +50,7 @@ Item {
50
50
51 Connections {
51 Connections {
52 target: indicatorsMenu
52 target: indicatorsMenu
53− onShown: hideTimer.stop()
53+ onShownChanged: hideTimer.stop()
54 }
54 }
55
55
56 PanelBackground {
56 PanelBackground {
@@ -101,13 +101,10 @@ Item {
101 y: panelBackground.y
101 y: panelBackground.y
102 width: root.indicatorsMenuWidth
102 width: root.indicatorsMenuWidth
103 shown: false
103 shown: false
104− hintValue: __panelMinusSeparatorLineHeight * 3
105 panelHeight: __panelMinusSeparatorLineHeight
104 panelHeight: __panelMinusSeparatorLineHeight
106 openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
105 openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
107 pinnedMode: !fullscreenMode
106 pinnedMode: !fullscreenMode
108 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
107 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
109−
110− unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
111 }
108 }
112
109
113 PanelSeparatorLine {
110 PanelSeparatorLine {
tests/autopilot/unity8/process_helpers.py+3−3
@@ -110,7 +110,7 @@ def restart_unity(*args):
110 status = _get_unity_status()
110 status = _get_unity_status()
111 if "start/" in status:
111 if "start/" in status:
112 try:
112 try:
113− output = subprocess.check_output(['initctl', 'stop', 'unity8'])
113+ output = subprocess.check_output(['/sbin/initctl', 'stop', 'unity8'])
114 logger.info(output)
114 logger.info(output)
115 except subprocess.CalledProcessError as e:
115 except subprocess.CalledProcessError as e:
116 e.args += (
116 e.args += (
@@ -119,7 +119,7 @@ def restart_unity(*args):
119 raise
119 raise
120
120
121 try:
121 try:
122− command = ['initctl', 'start', 'unity8'] + list(args)
122+ command = ['/sbin/initctl', 'start', 'unity8'] + list(args)
123 output = subprocess.check_output(
123 output = subprocess.check_output(
124 command,
124 command,
125 stderr=subprocess.STDOUT,
125 stderr=subprocess.STDOUT,
@@ -137,7 +137,7 @@ def restart_unity(*args):
137def _get_unity_status():
137def _get_unity_status():
138 try:
138 try:
139 return subprocess.check_output([
139 return subprocess.check_output([
140− 'initctl',
140+ '/sbin/initctl',
141 'status',
141 'status',
142 'unity8'
142 'unity8'
143 ])
143 ])
tests/autopilot/unity8/shell/emulators/dash.py+1−1
@@ -158,7 +158,7 @@ class DashApps(emulators.UnityEmulatorBase):
158
158
159 def _get_category_element(self, category):
159 def _get_category_element(self, category):
160 try:
160 try:
161− return self.select_single(
161+ return self.wait_select_single(
162 'Base', objectName='dashCategory{}'.format(category))
162 'Base', objectName='dashCategory{}'.format(category))
163 except dbus.StateNotFoundError:
163 except dbus.StateNotFoundError:
164 raise emulators.UnityEmulatorException(
164 raise emulators.UnityEmulatorException(
tests/autopilot/unity8/shell/tests/test_notifications.py+3−6
@@ -58,9 +58,7 @@ class NotificationsBase(UnityTestCase):
58 if os.path.abspath(__file__).startswith('/usr/'):
58 if os.path.abspath(__file__).startswith('/usr/'):
59 return '/usr/share/unity8/graphics/' + icon_name
59 return '/usr/share/unity8/graphics/' + icon_name
60 else:
60 else:
61− return os.path.abspath(
62− os.getcwd() + "/../../graphics/" + icon_name
61+ return os.path.dirname(__file__) + "/../../../../../qml/graphics/" + icon_name
63− )
64
62
65 def _get_notifications_list(self):
63 def _get_notifications_list(self):
66 main_view = self.main_window.get_qml_view()
64 main_view = self.main_window.get_qml_view()
@@ -161,8 +159,6 @@ class InteractiveNotificationBase(NotificationsBase):
161 unity_proxy = self.launch_unity()
159 unity_proxy = self.launch_unity()
162 unlock_unity(unity_proxy)
160 unlock_unity(unity_proxy)
163
161
164− notify_list = self._get_notifications_list()
165−
166 summary = "Incoming call"
162 summary = "Incoming call"
167 body = "Frank Zappa\n+44 (0)7736 027340"
163 body = "Frank Zappa\n+44 (0)7736 027340"
168 icon_path = self._get_icon_path('avatars/anna_olsson.png')
164 icon_path = self._get_icon_path('avatars/anna_olsson.png')
@@ -191,8 +187,9 @@ class InteractiveNotificationBase(NotificationsBase):
191 hints
187 hints
192 )
188 )
193
189
190+ notify_list = self._get_notifications_list()
194 get_notification = lambda: notify_list.wait_select_single(
191 get_notification = lambda: notify_list.wait_select_single(
195− 'Notification', objectName='notification1')
192+ 'Notification', objectName='notification0')
196 notification = get_notification()
193 notification = get_notification()
197 self._assert_notification(notification, None, None, True, True, 1.0)
194 self._assert_notification(notification, None, None, True, True, 1.0)
198 initial_height = notification.height
195 initial_height = notification.height
tests/autopilot/unity8/shell/tests/test_system_integration.pynew file+38
@@ -0,0 +1,38 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2014 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
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+"""Tests for system integration."""
21+
22+import subprocess
23+
24+from unity8.shell.emulators import UnityEmulatorBase
25+from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26+
27+from testtools.matchers._basic import Equals
28+
29+class SystemIntegrationTests(UnityTestCase):
30+
31+ scenarios = _get_device_emulation_scenarios()
32+
33+ def test_networkmanager_integration(self):
34+ self.launch_unity()
35+
36+ # invoke policykit to check permissions
37+ pid = subprocess.check_output("pidof -s unity8", shell=True)
38+ retvalue = subprocess.check_call("pkcheck --action-id org.freedesktop.NetworkManager.enable-disable-network --process " + pid, shell=True)
tests/mocks/Unity/Indicators/IndicatorsModel.qml+5−5
@@ -28,35 +28,35 @@ ListModel {
28 "position": 0,
28 "position": 0,
29 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget1.qml",
29 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget1.qml",
30 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page1.qml",
30 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page1.qml",
31− "indicatorProperties": ""
31+ "indicatorProperties": { enabled: true }
32 });
32 });
33
33
34 append({ "identifier": "indicator-fake2",
34 append({ "identifier": "indicator-fake2",
35 "position": 1,
35 "position": 1,
36 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget2.qml",
36 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget2.qml",
37 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page2.qml",
37 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page2.qml",
38− "indicatorProperties": ""
38+ "indicatorProperties": { enabled: true }
39 });
39 });
40
40
41 append({ "identifier": "indicator-fake3",
41 append({ "identifier": "indicator-fake3",
42 "position": 2,
42 "position": 2,
43 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget3.qml",
43 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget3.qml",
44 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page3.qml",
44 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page3.qml",
45− "indicatorProperties": ""
45+ "indicatorProperties": { enabled: true }
46 });
46 });
47
47
48 append({ "identifier": "indicator-fake4",
48 append({ "identifier": "indicator-fake4",
49 "position": 3,
49 "position": 3,
50 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget4.qml",
50 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget4.qml",
51 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page4.qml",
51 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page4.qml",
52− "indicatorProperties": ""
52+ "indicatorProperties": { enabled: true }
53 });
53 });
54
54
55 append({ "identifier": "indicator-fake5",
55 append({ "identifier": "indicator-fake5",
56 "position": 4,
56 "position": 4,
57 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget5.qml",
57 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget5.qml",
58 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page5.qml",
58 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page5.qml",
59− "indicatorProperties": ""
59+ "indicatorProperties": { enabled: true }
60 });
60 });
61 }
61 }
62}
62}
tests/mocks/Unity/Indicators/qml/fake_menu_page1.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin1
21 id: menu_plugin1
22− objectName: "menu_page1"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page2.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin2
21 id: menu_plugin2
22− objectName: "menu_page2"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page3.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin3
21 id: menu_plugin3
22− objectName: "menu_page3"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page4.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin4
21 id: menu_plugin4
22− objectName: "menu_page4"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page5.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin5
21 id: menu_plugin5
22− objectName: "menu_page5"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/qmltests/Components/tst_DragHandle.cpp+65−10
@@ -62,9 +62,13 @@ private Q_SLOTS:
62 void stretch_horizontal();
62 void stretch_horizontal();
63 void stretch_vertical();
63 void stretch_vertical();
64 void hintingAnimation();
64 void hintingAnimation();
65+ void hintingAnimation_dontRestartAfterFinishedAndStillPressed();
66+
65
67
66private:
68private:
67 void flickAndHold(DirectionalDragArea *dragHandle, qreal distance);
69 void flickAndHold(DirectionalDragArea *dragHandle, qreal distance);
70+ void drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
71+ int numSteps, qint64 timeMs = 500);
68 DirectionalDragArea *fetchAndSetupDragHandle(const char *objectName);
72 DirectionalDragArea *fetchAndSetupDragHandle(const char *objectName);
69 qreal fetchDragThreshold(DirectionalDragArea *dragHandle);
73 qreal fetchDragThreshold(DirectionalDragArea *dragHandle);
70 void tryCompare(std::function<qreal ()> actualFunc, qreal expectedValue);
74 void tryCompare(std::function<qreal ()> actualFunc, qreal expectedValue);
@@ -161,25 +165,29 @@ void tst_DragHandle::flickAndHold(DirectionalDragArea *dragHandle,
161 QPointF initialTouchPos = dragHandle->mapToScene(
165 QPointF initialTouchPos = dragHandle->mapToScene(
162 QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
166 QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
163 QPointF touchPoint = initialTouchPos;
167 QPointF touchPoint = initialTouchPos;
164− int numSteps = 10;
165− qint64 flickTimeMs = 500;
166− qint64 timeStep = flickTimeMs / numSteps;
167
168
169+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
170+
171+ int numSteps = 10;
168 QPointF dragDirectionVector = calculateDirectionVector(dragHandle);
172 QPointF dragDirectionVector = calculateDirectionVector(dragHandle);
169− QPointF touchMovement = dragDirectionVector * (distance / (qreal)numSteps);
173+ drag(touchPoint, dragDirectionVector, distance, numSteps);
170
174
175+ // Wait for quite a bit before finally releasing to make a very low flick/release
176+ // speed.
177+ m_fakeTimeSource->m_msecsSinceReference += 5000;
171− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
178+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
179+}
172
180
181+void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
182+ int numSteps, qint64 timeMs)
183+{
184+ qint64 timeStep = timeMs / numSteps;
185+ QPointF touchMovement = direction * (distance / (qreal)numSteps);
173 for (int i = 0; i < numSteps; ++i) {
186 for (int i = 0; i < numSteps; ++i) {
174 touchPoint += touchMovement;
187 touchPoint += touchMovement;
175 m_fakeTimeSource->m_msecsSinceReference += timeStep;
188 m_fakeTimeSource->m_msecsSinceReference += timeStep;
176 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
189 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
177 }
190 }
178−
179− // Wait for quite a bit before finally releasing to make a very low flick/release
180− // speed.
181− m_fakeTimeSource->m_msecsSinceReference += 5000;
182− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
183}
191}
184
192
185DirectionalDragArea *tst_DragHandle::fetchAndSetupDragHandle(const char *objectName)
193DirectionalDragArea *tst_DragHandle::fetchAndSetupDragHandle(const char *objectName)
@@ -389,6 +397,53 @@ void tst_DragHandle::hintingAnimation()
389 QCOMPARE(parentItem->property("shown").toBool(), false);
397 QCOMPARE(parentItem->property("shown").toBool(), false);
390}
398}
391
399
400+/*
401+ Regression test for LP#1269022: https://bugs.launchpad.net/unity8/+bug/1269022
402+
403+ 1) Click on handle.
404+ 2) wait for hint portion to appear
405+ 3) slowly drag handle, only a few pixels
406+
407+ Expected outcome:
408+ Nothing happens
409+
410+ Actual outcome:
411+ Handle will momentarily move back to zero position, then back down to the
412+ hint displacement location.
413+ */
414+void tst_DragHandle::hintingAnimation_dontRestartAfterFinishedAndStillPressed()
415+{
416+ DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
417+ QQuickItem *parentItem = dragHandle->parentItem();
418+ qreal hintDisplacement = 100.0;
419+
420+ // enable hinting animations
421+ m_view->rootObject()->setProperty("hintDisplacement", QVariant(hintDisplacement));
422+ m_view->rootObject()->setProperty("stretch", QVariant(true));
423+
424+ QCOMPARE(parentItem->height(), 0.0);
425+
426+ QPointF initialTouchPos = dragHandle->mapToScene(
427+ QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
428+ QPointF touchPoint = initialTouchPos;
429+
430+ // Pressing causes the Showable to be stretched by hintDisplacement pixels
431+ const int touchId = 0;
432+ QTest::touchEvent(m_view, m_device).press(touchId, touchPoint.toPoint());
433+ tryCompare([&](){ return parentItem->height(); }, hintDisplacement);
434+
435+
436+ QSignalSpy parentHeightChangedSpy(parentItem, SIGNAL(heightChanged()));
437+
438+ drag(touchPoint, QPointF(0.0, -1.0) /*dragDirectionVector*/, 15 /*distance*/, 3 /*numSteps*/);
439+
440+ // Give some time for animations to run, if any
441+ QTest::qWait(300);
442+
443+ // parentItem height shouldn't have changed at all
444+ QVERIFY(parentHeightChangedSpy.isEmpty());
445+}
446+
392QTEST_MAIN(tst_DragHandle)
447QTEST_MAIN(tst_DragHandle)
393
448
394#include "tst_DragHandle.moc"
449#include "tst_DragHandle.moc"
tests/qmltests/Components/tst_FilterGrid.qml+44−5
@@ -20,6 +20,7 @@ import "../../../qml/Components"
20import Ubuntu.Components.ListItems 0.1 as ListItem
20import Ubuntu.Components.ListItems 0.1 as ListItem
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Unity.Test 0.1 as UT
22import Unity.Test 0.1 as UT
23+import Utils 0.1
23
24
24/*
25/*
25 You should see 6 green squares (from "A" to "F") and a button "View all (12)".
26 You should see 6 green squares (from "A" to "F") and a button "View all (12)".
@@ -69,6 +70,20 @@ Rectangle {
69 ListElement { name: "L" }
70 ListElement { name: "L" }
70 }
71 }
71
72
73+ ListModel {
74+ id: fakeModelTwoItems
75+ ListElement { name: "A" }
76+ ListElement { name: "B" }
77+ }
78+
79+ ListModel {
80+ id: fakeModelFourItems
81+ ListElement { name: "A" }
82+ ListElement { name: "B" }
83+ ListElement { name: "C" }
84+ ListElement { name: "D" }
85+ }
86+
72 Rectangle {
87 Rectangle {
73 id: gridRect
88 id: gridRect
74 width: units.gu(30)
89 width: units.gu(30)
@@ -109,15 +124,21 @@ Rectangle {
109 name: "FilterGrid"
124 name: "FilterGrid"
110 when: windowShown
125 when: windowShown
111
126
127+ function init() {
128+ filterGrid.model = fakeModel
129+ }
130+
131+ function cleanup() {
132+ filterCheckBox.checked = true
133+ collapsedRowCountSelector.selectedIndex = 1
134+ }
135+
112 function test_turningFilterOffShowsAllElements() {
136 function test_turningFilterOffShowsAllElements() {
113 tryCompareFunction(countVisibleDelegates, 6)
137 tryCompareFunction(countVisibleDelegates, 6)
114
138
115 filterCheckBox.checked = false
139 filterCheckBox.checked = false
116
140
117 tryCompareFunction(countVisibleDelegates, 12)
141 tryCompareFunction(countVisibleDelegates, 12)
118−
119− // back to initial state
120− filterCheckBox.checked = true
121 }
142 }
122
143
123 function test_collapsedRowCount() {
144 function test_collapsedRowCount() {
@@ -127,9 +148,27 @@ Rectangle {
127 // row count == index + 1
148 // row count == index + 1
128 tryCompareFunction(countVisibleDelegates, 3*(i+1))
149 tryCompareFunction(countVisibleDelegates, 3*(i+1))
129 }
150 }
151+ }
130
152
131− // back to initial state
153+ function test_modelSizeAffectsCollapsedRowCount_data() {
154+ return [
155+ { tag: "2 items, collapsedRows 1", model: fakeModelTwoItems, collapsedRowCountIndex: 0,
156+ rowsWhenCollapsed: 1, visibleDelegates: 2 },
157+ { tag: "2 items, collapsedRows 2", model: fakeModelTwoItems, collapsedRowCountIndex: 1,
158+ rowsWhenCollapsed: 1, visibleDelegates: 2 },
159+ { tag: "4 items, collapsedRows 1", model: fakeModelFourItems, collapsedRowCountIndex: 0,
160+ rowsWhenCollapsed: 1, visibleDelegates: 3 },
161+ { tag: "4 items, collapsedRows 2", model: fakeModelFourItems, collapsedRowCountIndex: 1,
162+ rowsWhenCollapsed: 2, visibleDelegates: 4 },
163+ ]
164+ }
165+
166+ function test_modelSizeAffectsCollapsedRowCount(data) {
167+ filterGrid.model = data.model
132− collapsedRowCountSelector.selectedIndex = 1
168+ collapsedRowCountSelector.selectedIndex = data.collapsedRowCountIndex
169+
170+ tryCompare(filterGrid, "rowsWhenCollapsed", data.rowsWhenCollapsed)
171+ tryCompareFunction(countVisibleDelegates, data.visibleDelegates)
133 }
172 }
134
173
135 function countVisibleDelegates() {
174 function countVisibleDelegates() {
tests/qmltests/Components/tst_ResponsiveGridView.qml+1−1
@@ -152,7 +152,7 @@ Item {
152 var data = new Array()
152 var data = new Array()
153
153
154 data.push({selectedIndex: 0, minHSpacing:0, columnCount: 13})
154 data.push({selectedIndex: 0, minHSpacing:0, columnCount: 13})
155− data.push({selectedIndex: 1, minHSpacing:units.gu(2), columnCount: 9})
155+ data.push({selectedIndex: 1, minHSpacing:units.gu(2), columnCount: 10})
156 data.push({selectedIndex: 2, minHSpacing:units.gu(8), columnCount: 5})
156 data.push({selectedIndex: 2, minHSpacing:units.gu(8), columnCount: 5})
157 data.push({selectedIndex: 3, minHSpacing:units.gu(25), columnCount: 2})
157 data.push({selectedIndex: 3, minHSpacing:units.gu(25), columnCount: 2})
158
158
tests/qmltests/Dash/tst_Card.qml+35−4
@@ -106,6 +106,15 @@ Rectangle {
106 "layout": { "template": { "card-layout": "horizontal" },
106 "layout": { "template": { "card-layout": "horizontal" },
107 "components": JSON.parse(fullMapping) }
107 "components": JSON.parse(fullMapping) }
108 },
108 },
109+ {
110+ "name": "Art, header - vertical",
111+ "layout": { "components": Helpers.update(JSON.parse(root.fullMapping), { "summary": undefined }) }
112+ },
113+ {
114+ "name": "Header title only - horizontal",
115+ "layout": { "template": { "card-layout": "horizontal" },
116+ "components": { "title": "title" } }
117+ },
109 ]
118 ]
110
119
111 Card {
120 Card {
@@ -189,7 +198,10 @@ Rectangle {
189 property Item summary: findChild(card, "summaryLabel")
198 property Item summary: findChild(card, "summaryLabel")
190
199
191 function initTestCase() {
200 function initTestCase() {
192− verify(testCase.header !== undefined, "Couldn't find header object.");
201+ verify(typeof testCase.header === "object", "Couldn't find header object.");
202+ verify(typeof testCase.art === "object", "Couldn't find art object.");
203+ verify(typeof testCase.artImage === "object", "Couldn't find artImage object.");
204+ verify(typeof testCase.summary === "object", "Couldn't find summary object.");
193 }
205 }
194
206
195 function cleanup() {
207 function cleanup() {
@@ -237,6 +249,9 @@ Rectangle {
237 { tag: "Large", width: units.gu(38), size: "large", index: 0 },
249 { tag: "Large", width: units.gu(38), size: "large", index: 0 },
238 { tag: "Wide", width: units.gu(18.5), aspect: 0.5, index: 0 },
250 { tag: "Wide", width: units.gu(18.5), aspect: 0.5, index: 0 },
239 { tag: "Horizontal", width: units.gu(38), index: 5 },
251 { tag: "Horizontal", width: units.gu(38), index: 5 },
252+ // Make sure card ends with header when there's no summary
253+ { tag: "NoSummary", height: function() { return header.y + header.height }, index: 6 },
254+ { tag: "HorizontalNoSummary", height: function() { return header.height }, card_layout: "horizontal", index: 6 },
240 ]
255 ]
241 }
256 }
242
257
@@ -248,6 +263,11 @@ Rectangle {
248 card.templateChanged();
263 card.templateChanged();
249 }
264 }
250
265
266+ if (data.hasOwnProperty("card_layout")) {
267+ card.template['card-layout'] = data.card_layout;
268+ card.templateChanged();
269+ }
270+
251 if (data.hasOwnProperty("aspect")) {
271 if (data.hasOwnProperty("aspect")) {
252 card.components['art']['aspect-ratio'] = data.aspect;
272 card.components['art']['aspect-ratio'] = data.aspect;
253 card.componentsChanged();
273 card.componentsChanged();
@@ -257,7 +277,9 @@ Rectangle {
257 tryCompare(card, "width", data.width);
277 tryCompare(card, "width", data.width);
258 }
278 }
259
279
280+ if (typeof data.height === "function") {
281+ tryCompareFunction(function() { return card.height === data.height() }, true);
260− if (data.hasOwnProperty("height")) {
282+ } else if (data.hasOwnProperty("height")) {
261 tryCompare(card, "height", data.height);
283 tryCompare(card, "height", data.height);
262 }
284 }
263 }
285 }
@@ -308,7 +330,7 @@ Rectangle {
308 function test_art_layout_data() {
330 function test_art_layout_data() {
309 return [
331 return [
310 { tag: "Vertical", left: function() { return 0 }, index: 0},
332 { tag: "Vertical", left: function() { return 0 }, index: 0},
311− { tag: "Horizontal", left: function() { return art.width }, index: 5 }
333+ { tag: "Horizontal", left: function() { return art.width }, index: 5 },
312 ];
334 ];
313 }
335 }
314
336
@@ -323,7 +345,7 @@ Rectangle {
323 { tag: "Vertical", top: function() { return art.y + art.height },
345 { tag: "Vertical", top: function() { return art.y + art.height },
324 left: function() { return art.x }, index: 0 },
346 left: function() { return art.x }, index: 0 },
325 { tag: "Horizontal", top: function() { return art.y },
347 { tag: "Horizontal", top: function() { return art.y },
326− left: function() { return art.x + art.width }, index: 5 }
348+ left: function() { return art.x + art.width }, index: 5 },
327 ]
349 ]
328 }
350 }
329
351
@@ -333,5 +355,14 @@ Rectangle {
333 tryCompareFunction(function() { return testCase.header.y === data.top() }, true);
355 tryCompareFunction(function() { return testCase.header.y === data.top() }, true);
334 tryCompareFunction(function() { return testCase.header.x === data.left() }, true);
356 tryCompareFunction(function() { return testCase.header.x === data.left() }, true);
335 }
357 }
358+
359+ function test_art_visibility() {
360+ selector.selectedIndex = 7
361+
362+ tryCompare(testCase.artImage, "source", "")
363+ compare(testCase.art.visible, false)
364+ compare(testCase.art.height, 0)
365+ compare(testCase.art.width, 0)
366+ }
336 }
367 }
337}
368}
tests/qmltests/Dash/tst_CardHeader.qml+13−8
@@ -52,11 +52,11 @@ Rectangle {
52 property Item column: findChild(cardHeader, "column")
52 property Item column: findChild(cardHeader, "column")
53
53
54 function initTestCase() {
54 function initTestCase() {
55− verify(testCase.mascot !== undefined, "Couldn't find mascot object.");
55+ verify(typeof testCase.mascot === "object", "Couldn't find mascot object.");
56− verify(testCase.titleLabel !== undefined, "Couldn't find titleLabel object.");
56+ verify(typeof testCase.titleLabel === "object", "Couldn't find titleLabel object.");
57− verify(testCase.subtitleLabel !== undefined, "Couldn't find subtitleLabel object.");
57+ verify(typeof testCase.subtitleLabel === "object", "Couldn't find subtitleLabel object.");
58− verify(testCase.prices !== undefined, "Couldn't find prices object.");
58+ verify(typeof testCase.prices === "object", "Couldn't find prices object.");
59− verify(testCase.oldPriceLabel !== undefined, "Couldn't find oldPriceLabel object.");
59+ verify(typeof testCase.oldPriceLabel === "object", "Couldn't find oldPriceLabel object.");
60 }
60 }
61
61
62 function cleanup() {
62 function cleanup() {
@@ -86,7 +86,7 @@ Rectangle {
86 { tag: "Empty", visible: false },
86 { tag: "Empty", visible: false },
87 { tag: "Title only", title: "Foo", visible: true },
87 { tag: "Title only", title: "Foo", visible: true },
88 { tag: "Subtitle only", subtitle: "Bar", visible: false },
88 { tag: "Subtitle only", subtitle: "Bar", visible: false },
89− { tag: "Both", title: "Foo", subtitle: "Bar", visible: true }
89+ { tag: "Both", title: "Foo", subtitle: "Bar", visible: true },
90 ]
90 ]
91 }
91 }
92
92
@@ -104,7 +104,7 @@ Rectangle {
104 { tag: "Main and Alt", main: "$1.25", alt: "€1.00", visible: true },
104 { tag: "Main and Alt", main: "$1.25", alt: "€1.00", visible: true },
105 { tag: "Main and Old", main: "$1.25", old: "$2.00", visible: true, oldAlign: Text.AlignRight },
105 { tag: "Main and Old", main: "$1.25", old: "$2.00", visible: true, oldAlign: Text.AlignRight },
106 { tag: "Alt and Old", alt: "€1.00", old: "$2.00", visible: false },
106 { tag: "Alt and Old", alt: "€1.00", old: "$2.00", visible: false },
107− { tag: "All", main: "$1.25", alt: "€1.00", old: "$2.00", visible: true, oldAlign: Text.AlignHCenter }
107+ { tag: "All", main: "$1.25", alt: "€1.00", old: "$2.00", visible: true, oldAlign: Text.AlignHCenter },
108 ]
108 ]
109 }
109 }
110
110
@@ -121,7 +121,8 @@ Rectangle {
121 function test_dimensions_data() {
121 function test_dimensions_data() {
122 return [
122 return [
123 { tag: "Column width", object: column, width: cardHeader.width - testCase.outerRow.spacing * 2 },
123 { tag: "Column width", object: column, width: cardHeader.width - testCase.outerRow.spacing * 2 },
124− { tag: "Column width", object: column, width: cardHeader.width - mascot.width - testCase.outerRow.spacing * 3, mascot: "artwork/avatar.png" }
124+ { tag: "Column width", object: column, width: cardHeader.width - mascot.width - testCase.outerRow.spacing * 3, mascot: "artwork/avatar.png" },
125+ { tag: "Header height", object: cardHeader, height: function() { return subtitleLabel.y + subtitleLabel.height + outerRow.spacing * 2 } },
125 ]
126 ]
126 }
127 }
127
128
@@ -133,6 +134,10 @@ Rectangle {
133 if (data.hasOwnProperty("width")) {
134 if (data.hasOwnProperty("width")) {
134 tryCompare(data.object, "width", data.width);
135 tryCompare(data.object, "width", data.width);
135 }
136 }
137+
138+ if (data.hasOwnProperty("height")) {
139+ tryCompareFunction(function() { return data.object.height === data.height() }, true);
140+ }
136 }
141 }
137 }
142 }
138}
143}
tests/qmltests/Dash/tst_GenericScopeView.qml+37−1
@@ -71,7 +71,13 @@ Item {
71 name: "GenericScopeView"
71 name: "GenericScopeView"
72 when: scopes.loaded
72 when: scopes.loaded
73
73
74+ function init() {
75+ shell.width = units.gu(120)
76+ genericScopeView.categoryView.positionAtBeginning();
77+ tryCompare(genericScopeView.categoryView.contentY, 0)
78+ }
79+
74− function test_isCurrent() {
80+ function test_isCurrent() {
75 genericScopeView.isCurrent = true
81 genericScopeView.isCurrent = true
76 pageHeader.searchQuery = "test"
82 pageHeader.searchQuery = "test"
77 previewListView.open = true
83 previewListView.open = true
@@ -272,6 +278,21 @@ Item {
272 tryCompare(category, "filtered", true);
278 tryCompare(category, "filtered", true);
273 }
279 }
274
280
281+ function test_getRendererCarouselGridFallback() {
282+ var rendererId = "carousel"
283+ var contentType = ""
284+ var rendererHint = ""
285+ var results = new Object()
286+
287+ results.count = 7
288+ var renderer = genericScopeView.getRenderer(rendererId, contentType, rendererHint, results)
289+ compare(renderer, "Generic/GenericCarousel.qml")
290+
291+ results.count = 6
292+ renderer = genericScopeView.getRenderer(rendererId, contentType, rendererHint, results)
293+ compare(renderer, "Generic/GenericFilterGrid.qml")
294+ }
295+
275 function test_showPreviewCarousel() {
296 function test_showPreviewCarousel() {
276 tryCompareFunction(function() { return findChild(genericScopeView, "carouselDelegate") != undefined; }, true);
297 tryCompareFunction(function() { return findChild(genericScopeView, "carouselDelegate") != undefined; }, true);
277 var tile = findChild(genericScopeView, "carouselDelegate");
298 var tile = findChild(genericScopeView, "carouselDelegate");
@@ -336,6 +357,21 @@ Item {
336 tryCompare(category2, "filtered", true);
357 tryCompare(category2, "filtered", true);
337 tryCompare(category2FilterGrid, "filter", true);
358 tryCompare(category2FilterGrid, "filter", true);
338 }
359 }
360+
361+ function test_narrow_delegate_ranges_expand() {
362+ tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
363+ var category = findChild(genericScopeView, "dashCategory0")
364+
365+ shell.width = units.gu(20)
366+ var categoryListView = findChild(genericScopeView, "categoryListView");
367+ categoryListView.contentY = units.gu(20);
368+ var header0 = findChild(genericScopeView, "dashSectionHeader0")
369+ mouseClick(header0, header0.width / 2, header0.height / 2);
370+ tryCompare(category, "filtered", false);
371+ tryCompare(category.item, "delegateCreationEnd", category.item.delegateCreationBegin + genericScopeView.height);
372+ mouseClick(header0, header0.width / 2, header0.height / 2);
373+ tryCompare(category, "filtered", true);
374+ }
339 }
375 }
340 }
376 }
341}
377}
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml−4
@@ -129,14 +129,10 @@ Item {
129 function test_reloadData() {
129 function test_reloadData() {
130 var mainMenu = findChild(page, "mainMenu");
130 var mainMenu = findChild(page, "mainMenu");
131
131
132− console.log("setting empty data");
133 page.menuModel.modelData = [];
132 page.menuModel.modelData = [];
134 tryCompare(mainMenu, "count", 0);
133 tryCompare(mainMenu, "count", 0);
135− console.log("set empty data");
136
134
137− console.log("setting full data");
138 page.menuModel.modelData = fullMenuData;
135 page.menuModel.modelData = fullMenuData;
139− console.log("set full data");
140 tryCompare(mainMenu, "count", 3);
136 tryCompare(mainMenu, "count", 3);
141
137
142 page.menuModel.modelData = [];
138 page.menuModel.modelData = [];
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+194−18
@@ -84,11 +84,13 @@ Item {
84 { tag: 'switch1', type: "unity.widgets.systemsettings.tablet.switch", objectName: "switchMenu" },
84 { tag: 'switch1', type: "unity.widgets.systemsettings.tablet.switch", objectName: "switchMenu" },
85
85
86 { tag: 'button', type: "com.canonical.indicator.button", objectName: "buttonMenu" },
86 { tag: 'button', type: "com.canonical.indicator.button", objectName: "buttonMenu" },
87− { tag: 'separator', type: "com.canonical.indicator.div", objectName: "divMenu" },
87+ { tag: 'separator', type: "com.canonical.indicator.div", objectName: "separatorMenu" },
88 { tag: 'section', type: "com.canonical.indicator.section", objectName: "sectionMenu" },
88 { tag: 'section', type: "com.canonical.indicator.section", objectName: "sectionMenu" },
89 { tag: 'progress', type: "com.canonical.indicator.progress", objectName: "progressMenu" },
89 { tag: 'progress', type: "com.canonical.indicator.progress", objectName: "progressMenu" },
90 { tag: 'slider1', type: "com.canonical.indicator.slider", objectName: "sliderMenu" },
90 { tag: 'slider1', type: "com.canonical.indicator.slider", objectName: "sliderMenu" },
91 { tag: 'switch2', type: "com.canonical.indicator.switch", objectName: "switchMenu" },
91 { tag: 'switch2', type: "com.canonical.indicator.switch", objectName: "switchMenu" },
92+ { tag: 'alarm', type: "com.canonical.indicator.alarm", objectName: "alarmMenu" },
93+ { tag: 'appointment', type: "com.canonical.indicator.appointment", objectName: "appointmentMenu" },
92
94
93 { tag: 'messageItem', type: "com.canonical.indicator.messages.messageitem", objectName: "messageItem" },
95 { tag: 'messageItem', type: "com.canonical.indicator.messages.messageitem", objectName: "messageItem" },
94 { tag: 'sourceItem', type: "com.canonical.indicator.messages.sourceitem", objectName: "groupedMessage" },
96 { tag: 'sourceItem', type: "com.canonical.indicator.messages.sourceitem", objectName: "groupedMessage" },
@@ -96,8 +98,8 @@ Item {
96 { tag: 'slider2', type: "com.canonical.unity.slider", objectName: "sliderMenu" },
98 { tag: 'slider2', type: "com.canonical.unity.slider", objectName: "sliderMenu" },
97 { tag: 'switch3', type: "com.canonical.unity.switch", objectName: "switchMenu" },
99 { tag: 'switch3', type: "com.canonical.unity.switch", objectName: "switchMenu" },
98
100
99− { tag: 'mediaplayer', type: "com.canonical.unity.media-player", objectName: "standardMenu" },
101+ { tag: 'mediaplayer', type: "com.canonical.unity.media-player", objectName: "mediaPayerMenu" },
100− { tag: 'playbackitem', type: "com.canonical.unity.playback-item", objectName: "standardMenu" },
102+ { tag: 'playbackitem', type: "com.canonical.unity.playback-item", objectName: "playbackItemMenu" },
101
103
102 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
104 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
103 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
105 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
@@ -115,6 +117,16 @@ Item {
115 compare(loader.item.objectName, data.objectName, "Created object name does not match intended object (" + loader.item.objectName + " != " + data.objectName + ")");
117 compare(loader.item.objectName, data.objectName, "Created object name does not match intended object (" + loader.item.objectName + " != " + data.objectName + ")");
116 }
118 }
117
119
120+ function test_create_checkable() {
121+ var tmpData = menuData;
122+ tmpData.isCheck = true;
123+
124+ loader.data = tmpData;
125+ loader.sourceComponent = factory.load(tmpData);
126+ tryCompareFunction(function() { return loader.item != undefined; }, true);
127+ compare(loader.item.objectName, "checkableMenu", "Should have created a checkable menu");
128+ }
129+
118 function test_create_radio() {
130 function test_create_radio() {
119 skip("No radio component");
131 skip("No radio component");
120 menuData.isRadio = true;
132 menuData.isRadio = true;
@@ -131,7 +143,7 @@ Item {
131 loader.data = menuData;
143 loader.data = menuData;
132 loader.sourceComponent = factory.load(menuData);
144 loader.sourceComponent = factory.load(menuData);
133 tryCompareFunction(function() { return loader.item != undefined; }, true);
145 tryCompareFunction(function() { return loader.item != undefined; }, true);
134− compare(loader.item.objectName, "divMenu", "Should have created a separator menu");
146+ compare(loader.item.objectName, "separatorMenu", "Should have created a separator menu");
135 }
147 }
136
148
137 function test_create_sliderMenu_data() {
149 function test_create_sliderMenu_data() {
@@ -145,13 +157,13 @@ Item {
145 menuData.type = "com.canonical.indicator.slider"
157 menuData.type = "com.canonical.indicator.slider"
146 menuData.label = data.label;
158 menuData.label = data.label;
147 menuData.sensitive = data.enabled;
159 menuData.sensitive = data.enabled;
148− menuData.actionState = data.value;
149 menuData.ext = {
160 menuData.ext = {
150 'minIcon': "file:///testMinIcon",
161 'minIcon': "file:///testMinIcon",
151 'maxIcon': "file:///testMaxIcon",
162 'maxIcon': "file:///testMaxIcon",
152 'minValue': data.minValue,
163 'minValue': data.minValue,
153 'maxValue': data.maxValue
164 'maxValue': data.maxValue
154 };
165 };
166+ menuData.actionState = data.value;
155
167
156 loader.data = menuData;
168 loader.data = menuData;
157 loader.sourceComponent = factory.load(menuData);
169 loader.sourceComponent = factory.load(menuData);
@@ -163,7 +175,7 @@ Item {
163 compare(loader.item.maxIcon, "file:///testMaxIcon", "MaxIcon does not match data");
175 compare(loader.item.maxIcon, "file:///testMaxIcon", "MaxIcon does not match data");
164 compare(loader.item.minimumValue, data.minValue, "MinValue does not match data");
176 compare(loader.item.minimumValue, data.minValue, "MinValue does not match data");
165 compare(loader.item.maximumValue, data.maxValue, "MaxValue does not match data");
177 compare(loader.item.maximumValue, data.maxValue, "MaxValue does not match data");
166− compare(loader.item.value, data.value, "Calue does not match data");
178+ compare(loader.item.value, data.value, "Value does not match data");
167 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
179 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
168 }
180 }
169
181
@@ -232,7 +244,7 @@ Item {
232
244
233 function test_create_standardMenu_data() {
245 function test_create_standardMenu_data() {
234 return [
246 return [
235− {label: "testLabel1", enabled: true, icon: "file:///testIcon" },
247+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
236 {label: "testLabel2", enabled: false, icon: "file:///testIcon2"},
248 {label: "testLabel2", enabled: false, icon: "file:///testIcon2"},
237 ];
249 ];
238 }
250 }
@@ -253,31 +265,101 @@ Item {
253 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
265 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
254 }
266 }
255
267
256− function test_create_switchMenu_data() {
268+ function test_create_checkableMenu_data() {
257 return [
269 return [
258 {label: "testLabel1", enabled: true, checked: false },
270 {label: "testLabel1", enabled: true, checked: false },
259 {label: "testLabel2", enabled: false, checked: true },
271 {label: "testLabel2", enabled: false, checked: true },
260 ];
272 ];
261 }
273 }
262
274
275+ function test_create_checkableMenu(data) {
276+ menuData.type = "";
277+ menuData.label = data.label;
278+ menuData.sensitive = data.enabled;
279+ menuData.isCheck = true;
280+ menuData.isToggled = data.checked;
281+
282+ loader.data = menuData;
283+ loader.sourceComponent = factory.load(menuData);
284+ tryCompareFunction(function() { return loader.item != undefined; }, true);
285+ compare(loader.item.objectName, "checkableMenu", "Should have created a checkable menu");
286+
287+ compare(loader.item.text, data.label, "Label does not match data");
288+ compare(loader.item.checked, data.checked, "Checked does not match data");
289+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
290+ }
291+
292+ function test_create_switchMenu_data() {
293+ return [
294+ {label: "testLabel1", enabled: true, checked: false, icon: "file:///testIcon1" },
295+ {label: "testLabel2", enabled: false, checked: true, icon: "file:///testIcon2" },
296+ ];
297+ }
298+
263 function test_create_switchMenu(data) {
299 function test_create_switchMenu(data) {
264 menuData.type = "com.canonical.indicator.switch";
300 menuData.type = "com.canonical.indicator.switch";
265 menuData.label = data.label;
301 menuData.label = data.label;
266 menuData.sensitive = data.enabled;
302 menuData.sensitive = data.enabled;
267− menuData.icon = "file:///testIcon";
303+ menuData.icon = data.icon;
268 menuData.isToggled = data.checked;
304 menuData.isToggled = data.checked;
269
305
270 loader.data = menuData;
306 loader.data = menuData;
271 loader.sourceComponent = factory.load(menuData);
307 loader.sourceComponent = factory.load(menuData);
272 tryCompareFunction(function() { return loader.item != undefined; }, true);
308 tryCompareFunction(function() { return loader.item != undefined; }, true);
273− compare(loader.item.objectName, "switchMenu", "Should have created a standard menu");
309+ compare(loader.item.objectName, "switchMenu", "Should have created a switch menu");
274
310
275 compare(loader.item.text, data.label, "Label does not match data");
311 compare(loader.item.text, data.label, "Label does not match data");
276− compare(loader.item.icon, "file:///testIcon", "MaxIcon does not match data");
312+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
277 compare(loader.item.checked, data.checked, "Checked does not match data");
313 compare(loader.item.checked, data.checked, "Checked does not match data");
278 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
314 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
279 }
315 }
280
316
317+ function test_create_alarmMenu_data() {
318+ return [
319+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
320+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2" },
321+ ];
322+ }
323+
324+ function test_create_alarmMenu(data) {
325+ menuData.type = "com.canonical.indicator.alarm";
326+ menuData.label = data.label;
327+ menuData.sensitive = data.enabled;
328+ menuData.icon = data.icon;
329+
330+ loader.data = menuData;
331+ loader.sourceComponent = factory.load(menuData);
332+ tryCompareFunction(function() { return loader.item != undefined; }, true);
333+ compare(loader.item.objectName, "alarmMenu", "Should have created a alarm menu");
334+
335+ compare(loader.item.text, data.label, "Label does not match data");
336+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
337+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
338+ }
339+
340+ function test_create_appointmentMenu_data() {
341+ return [
342+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
343+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2" },
344+ ];
345+ }
346+
347+ function test_create_appointmentMenu(data) {
348+ menuData.type = "com.canonical.indicator.appointment";
349+ menuData.label = data.label;
350+ menuData.sensitive = data.enabled;
351+ menuData.icon = data.icon;
352+
353+ loader.data = menuData;
354+ loader.sourceComponent = factory.load(menuData);
355+ tryCompareFunction(function() { return loader.item != undefined; }, true);
356+ compare(loader.item.objectName, "appointmentMenu", "Should have created a appointment menu");
357+
358+ compare(loader.item.text, data.label, "Label does not match data");
359+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
360+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
361+ }
362+
281 function test_create_wifiSection_data() {
363 function test_create_wifiSection_data() {
282 return [
364 return [
283 {label: "testLabel1", busy: false },
365 {label: "testLabel1", busy: false },
@@ -322,7 +404,7 @@ Item {
322 tryCompareFunction(function() { return loader.item != undefined; }, true);
404 tryCompareFunction(function() { return loader.item != undefined; }, true);
323 compare(loader.item.objectName, "accessPoint", "Should have created a access point menu");
405 compare(loader.item.objectName, "accessPoint", "Should have created a access point menu");
324
406
325− compare(loader.item.label, data.label, "Label does not match data");
407+ compare(loader.item.text, data.label, "Label does not match data");
326 compare(loader.item.strengthAction.name, "action::strength", "Strength action incorrect");
408 compare(loader.item.strengthAction.name, "action::strength", "Strength action incorrect");
327 compare(loader.item.secure, data.secure, "Secure does not match data");
409 compare(loader.item.secure, data.secure, "Secure does not match data");
328 compare(loader.item.adHoc, data.adHoc, "AdHoc does not match data");
410 compare(loader.item.adHoc, data.adHoc, "AdHoc does not match data");
@@ -341,8 +423,8 @@ Item {
341
423
342 function test_create_groupedMessage_data() {
424 function test_create_groupedMessage_data() {
343 return [
425 return [
344− {label: "testLabel1", enabled: true, count: "5", appIcon: "file:///testIcon" },
426+ {label: "testLabel1", enabled: true, count: "5", icon: "file:///testIcon" },
345− {label: "testLabel2", enabled: false, count: "10", appIcon: "file:///testIcon2" },
427+ {label: "testLabel2", enabled: false, count: "10", icon: "file:///testIcon2" },
346 ];
428 ];
347 }
429 }
348
430
@@ -350,8 +432,8 @@ Item {
350 menuData.type = "com.canonical.indicator.messages.sourceitem";
432 menuData.type = "com.canonical.indicator.messages.sourceitem";
351 menuData.label = data.label;
433 menuData.label = data.label;
352 menuData.sensitive = data.enabled;
434 menuData.sensitive = data.enabled;
353− menuData.icon = data.appIcon;
435+ menuData.icon = data.icon;
354− menuData.ext = { 'icon': data.appIcon };
436+ menuData.ext = { 'icon': data.icon };
355 menuData.actionState = [data.count];
437 menuData.actionState = [data.count];
356 menuData.isToggled = true;
438 menuData.isToggled = true;
357
439
@@ -360,9 +442,103 @@ Item {
360 tryCompareFunction(function() { return loader.item != undefined; }, true);
442 tryCompareFunction(function() { return loader.item != undefined; }, true);
361 compare(loader.item.objectName, "groupedMessage", "Should have created a group message menu");
443 compare(loader.item.objectName, "groupedMessage", "Should have created a group message menu");
362
444
363− compare(loader.item.title, data.label, "Label does not match data");
445+ compare(loader.item.text, data.label, "Label does not match data");
364 compare(loader.item.count, data.count, "Count does not match data");
446 compare(loader.item.count, data.count, "Count does not match data");
365− compare(loader.item.appIcon, data.appIcon, "App Icon does not match data");
447+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
448+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
449+ }
450+
451+ function test_create_mediaPayerMenu_data() {
452+ return [{
453+ label: "player1",
454+ icon: "file:://icon1",
455+ albumArt: "file:://art1",
456+ song: "song1",
457+ artist: "artist1",
458+ album: "album1",
459+ running: true,
460+ state: "Playing",
461+ enabled: true
462+ },{
463+ label: "player2",
464+ icon: "file:://icon2",
465+ albumArt: "file:://art2",
466+ song: "song2",
467+ artist: "artist2",
468+ album: "album2",
469+ running: false,
470+ state: "Paused",
471+ enabled: false
472+ }
473+ ];
474+ }
475+
476+ function test_create_mediaPayerMenu(data) {
477+ menuData.type = "com.canonical.unity.media-player";
478+ menuData.label = data.label;
479+ menuData.sensitive = data.enabled;
480+ menuData.icon = data.icon;
481+ menuData.actionState = {
482+ 'art-url': data.albumArt,
483+ 'title': data.song,
484+ 'artist': data.artist,
485+ 'album': data.album,
486+ 'running': data.running,
487+ 'state': data.state,
488+ };
489+
490+ loader.data = menuData;
491+ loader.sourceComponent = factory.load(menuData);
492+ tryCompareFunction(function() { return loader.item != undefined; }, true);
493+ compare(loader.item.objectName, "mediaPayerMenu", "Should have created a media player menu");
494+
495+ compare(loader.item.playerIcon, data.icon, "Album art does not match data");
496+ compare(loader.item.playerName, data.label, "Album art does not match data");
497+ compare(loader.item.albumArt, data.albumArt, "Album art does not match data");
498+ compare(loader.item.song, data.song, "Song does not match data");
499+ compare(loader.item.artist, data.artist, "Artist does not match data");
500+ compare(loader.item.album, data.album, "Album does not match data");
501+ compare(loader.item.running, data.running, "Running does not match data");
502+ compare(loader.item.state, data.state, "State does not match data");
503+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
504+ }
505+
506+ function test_create_playbackItemMenu_data() {
507+ return [{
508+ playAction: "action::play",
509+ nextAction: "action::next",
510+ previousAction: "action::previous",
511+ enabled: true
512+ },{
513+ playAction: "action::play2",
514+ nextAction: "action::next2",
515+ previousAction: "action::previous2",
516+ enabled: false
517+ }
518+ ];
519+ }
520+
521+ function test_create_playbackItemMenu(data) {
522+ menuData.type = "com.canonical.unity.playback-item";
523+ menuData.sensitive = data.enabled;
524+ menuData.ext = {
525+ 'xCanonicalPlayAction': data.playAction,
526+ 'xCanonicalNextAction': data.nextAction,
527+ 'xCanonicalPreviousAction': data.previousAction
528+ };
529+
530+ loader.data = menuData;
531+ loader.sourceComponent = factory.load(menuData);
532+ tryCompareFunction(function() { return loader.item != undefined; }, true);
533+ compare(loader.item.objectName, "playbackItemMenu", "Should have created a playback menu");
534+
535+ compare(loader.item.playing, false, "Playing does not match data");
536+ compare(loader.item.playAction.name, data.playAction, "Play action incorrect");
537+ compare(loader.item.nextAction.name, data.nextAction, "Next action incorrect");
538+ compare(loader.item.previousAction.name, data.previousAction, "Previous action incorrect");
539+ compare(loader.item.canPlay, false, "CanPlay should be false");
540+ compare(loader.item.canGoNext, false, "CanGoNext should be false");
541+ compare(loader.item.canGoPrevious, false, "CanGoPrevious should be false");
366 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
542 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
367 }
543 }
368 }
544 }
tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qml+13−4
@@ -18,7 +18,8 @@ import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20import QMenuModel 0.1
20import QMenuModel 0.1
21−import Unity.Indicators.Messaging 0.1 as Indicators
21+import Unity.Indicators 0.1 as Indicators
22+import Utils 0.1 as Utils
22
23
23Item {
24Item {
24 id: testView
25 id: testView
@@ -31,6 +32,11 @@ Item {
31 menuIndex: 0
32 menuIndex: 0
32 }
33 }
33
34
35+ Utils.TimeFormatter {
36+ id: timeFormatter
37+ format: "hh:mm - MMM dd"
38+ }
39+
34 UT.UnityTestCase {
40 UT.UnityTestCase {
35 name: "MessageMenuItemFactory"
41 name: "MessageMenuItemFactory"
36
42
@@ -82,13 +88,14 @@ Item {
82 'xCanonicalAppIcon': data.appIcon,
88 'xCanonicalAppIcon': data.appIcon,
83 };
89 };
84 factory.menuData = menuData;
90 factory.menuData = menuData;
91+ timeFormatter.time = data.time;
85
92
86 var loader = findChild(factory, "loader");
93 var loader = findChild(factory, "loader");
87 verify(loader !== undefined);
94 verify(loader !== undefined);
88
95
89 tryCompare(loader.item, "objectName", "simpleTextMessage");
96 tryCompare(loader.item, "objectName", "simpleTextMessage");
90 compare(loader.item.title, data.title, "Title does not match data");
97 compare(loader.item.title, data.title, "Title does not match data");
91− compare(loader.item.time, data.time, "Time does not match data");
98+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
92 compare(loader.item.message, data.message, "Message does not match data");
99 compare(loader.item.message, data.message, "Message does not match data");
93 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
100 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
94 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
101 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
@@ -119,13 +126,14 @@ Item {
119 ]
126 ]
120 };
127 };
121 factory.menuData = menuData;
128 factory.menuData = menuData;
129+ timeFormatter.time = data.time;
122
130
123 var loader = findChild(factory, "loader");
131 var loader = findChild(factory, "loader");
124 verify(loader !== undefined);
132 verify(loader !== undefined);
125
133
126 tryCompare(loader.item, "objectName", "textMessage");
134 tryCompare(loader.item, "objectName", "textMessage");
127 compare(loader.item.title, data.title, "Title does not match data");
135 compare(loader.item.title, data.title, "Title does not match data");
128− compare(loader.item.time, data.time, "Time does not match data");
136+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
129 compare(loader.item.message, data.message, "Message does not match data");
137 compare(loader.item.message, data.message, "Message does not match data");
130 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
138 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
131 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
139 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
@@ -160,13 +168,14 @@ Item {
160 ]
168 ]
161 };
169 };
162 factory.menuData = menuData;
170 factory.menuData = menuData;
171+ timeFormatter.time = data.time;
163
172
164 var loader = findChild(factory, "loader");
173 var loader = findChild(factory, "loader");
165 verify(loader !== undefined);
174 verify(loader !== undefined);
166
175
167 tryCompare(loader.item, "objectName", "snapDecision");
176 tryCompare(loader.item, "objectName", "snapDecision");
168 compare(loader.item.title, data.title, "Title does not match data");
177 compare(loader.item.title, data.title, "Title does not match data");
169− compare(loader.item.time, data.time, "Time does not match data");
178+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
170 compare(loader.item.message, data.message, "Message does not match data");
179 compare(loader.item.message, data.message, "Message does not match data");
171 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
180 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
172 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
181 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
tests/qmltests/Panel/tst_IndicatorRow.qml+64−163
@@ -35,7 +35,7 @@ Item {
35 indicatorModel.load();
35 indicatorModel.load();
36
36
37 indicatorRow.state = "initial";
37 indicatorRow.state = "initial";
38− indicatorRow.currentItem = null;
38+ indicatorRow.setCurrentItemIndex(-1);
39 indicatorRow.unitProgress = 0.0;
39 indicatorRow.unitProgress = 0.0;
40 }
40 }
41
41
@@ -51,6 +51,8 @@ Item {
51 }
51 }
52
52
53 indicatorsModel: indicatorModel
53 indicatorsModel: indicatorModel
54+
55+ Component.onCompleted: indicatorModel.load()
54 }
56 }
55
57
56 Indicators.IndicatorsModel {
58 Indicators.IndicatorsModel {
@@ -61,199 +63,98 @@ Item {
61 name: "IndicatorRow"
63 name: "IndicatorRow"
62 when: windowShown
64 when: windowShown
63
65
66+ function get_indicator_item(index) {
67+ return findChild(indicatorRow.row, "item" + index);
68+ }
69+
64 function test_set_current_item() {
70 function test_set_current_item() {
65 init_test();
71 init_test();
66− indicatorRow.setCurrentItem(0);
72+ indicatorRow.setCurrentItemIndex(0);
67 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake1", "Incorrect item at position 0");
73 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake1", "Incorrect item at position 0");
68
74
69− indicatorRow.setCurrentItem(1);
75+ indicatorRow.setCurrentItemIndex(1);
70 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake2", "Incorrect item at position 1");
76 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake2", "Incorrect item at position 1");
71
77
72− indicatorRow.setCurrentItem(2);
78+ indicatorRow.setCurrentItemIndex(2);
73 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake3", "Incorrect item at position 2");
79 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake3", "Incorrect item at position 2");
74 }
80 }
75− }
76−
77− UT.UnityTestCase {
78− name: "IndicatorRow_IconPosition"
79− when: windowShown
80−
81− function get_indicator_item_at(index) {
82− return findChild(indicatorRow, "rowRepeater").itemAt(index);
83− }
84−
85− function test_current_item_commit() {
86− init_test();
87−
88− indicatorRow.setCurrentItem(2);
89− indicatorRow.state = "commit";
90− tryCompare(get_indicator_item_at(0), "opacity", 0.0);
91− tryCompare(get_indicator_item_at(1), "opacity", 0.0);
92− tryCompare(get_indicator_item_at(2), "opacity", 1.0);
93− tryCompare(get_indicator_item_at(3), "opacity", 0.0);
94− tryCompare(get_indicator_item_at(4), "opacity", 0.0);
95− }
96− }
97−
98− UT.UnityTestCase {
99− name: "IndicatorRow_Highlight"
100− when: windowShown
101−
102− function get_indicator_item_at(index) {
103− return findChild(indicatorRow, "rowRepeater").itemAt(index);
104− }
105−
106− function test_intial_state() {
107− init_test();
108−
109− indicatorRow.state = "initial";
110− indicatorRow.setCurrentItem(0);
111−
112− compare(indicatorRow.currentItem.highlighted, false, "Indicator should not highlight when in initial state");
113− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in initial state");
114− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in initial state");
115− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in initial state");
116− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in initial state");
117− }
118−
119− function test_hint_state() {
120− init_test();
121−
122− indicatorRow.state = "hint";
123− indicatorRow.setCurrentItem(0);
124−
125− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in hint state");
126− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in hint state");
127− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in hint state");
128− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in hint state");
129− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in hint state");
130− }
131−
132− function test_revealed_state() {
133− init_test();
134−
135− indicatorRow.state = "reveal";
136− indicatorRow.setCurrentItem(0);
137−
138− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in reveal state");
139− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
140− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in commit state");
141− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in commit state");
142− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in commit state");
143− }
144−
145− function test_commit_state() {
146− init_test();
147−
148− indicatorRow.state = "commit";
149− indicatorRow.setCurrentItem(0);
150
81
151− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in commit state");
82+ function test_highlight_data() {
152− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
83+ return [
153− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in commit state");
84+ { index: 0, progress: 0.0, current: false, other: false },
154− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in commit state");
85+ { index: 0, progress: 0.1, current: true, other: false },
155− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in commit state");
86+ { index: 0, progress: 0.5, current: true, other: false },
87+ { index: 0, progress: 1.0, current: true, other: false },
88+ { index: 2, progress: 0.0, current: false, other: false },
89+ { index: 2, progress: 0.1, current: true, other: false },
90+ { index: 2, progress: 0.5, current: true, other: false },
91+ { index: 2, progress: 1.0, current: true, other: false }
92+ ];
156 }
93 }
157
94
158− function test_locked_state() {
95+ function test_highlight(data) {
159 init_test();
96 init_test();
160
97
161− indicatorRow.state = "locked";
98+ indicatorRow.unitProgress = data.progress;
162− indicatorRow.setCurrentItem(0);
99+ indicatorRow.setCurrentItemIndex(data.index);
163
100
164− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in locked state");
101+ compare(indicatorRow.currentItem.highlighted, data.current, "Indicator hightlight did not match for current item");
165− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in locked state");
166− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in locked state");
167− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in locked state");
168− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in locked state");
169− }
170
102
171− function test_opacity() {
103+ for (var i = 0; i < indicatorRow.row.count; i++) {
172− init_test();
104+ compare(get_indicator_item(i).highlighted, i === data.index ? data.current: data.other, "Indicator hightlight did not match for item iter");
173−
105+ }
174− indicatorRow.state = "reveal";
175− indicatorRow.unitProgress = 0.5;
176− indicatorRow.setCurrentItem(2);
177−
178− compare(get_indicator_item_at(0).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
179− compare(get_indicator_item_at(1).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
180− compare(get_indicator_item_at(2).opacity, 1.0, "Current indicator should not change in response to panel progress");
181− compare(get_indicator_item_at(3).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
182− compare(get_indicator_item_at(4).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
183 }
106 }
184− }
185
107
186− UT.UnityTestCase {
108+ function test_opacity_data() {
187− name: "IndicatorRow_Dimmed"
109+ return [
188− when: windowShown
110+ { index: 0, progress: 0.0, current: 1.0, other: 1.0 },
189−
111+ { index: 0, progress: 0.1, current: 1.0, other: 0.9 },
190− function get_indicator_item_at(index) {
112+ { index: 0, progress: 0.5, current: 1.0, other: 0.5 },
191− return findChild(indicatorRow, "rowRepeater").itemAt(index);
113+ { index: 0, progress: 1.0, current: 1.0, other: 0.0 },
114+ { index: 2, progress: 0.0, current: 1.0, other: 1.0 },
115+ { index: 2, progress: 0.1, current: 1.0, other: 0.9 },
116+ { index: 2, progress: 0.5, current: 1.0, other: 0.5 },
117+ { index: 2, progress: 1.0, current: 1.0, other: 0.0 }
118+ ];
192 }
119 }
193
120
194− function test_intial_state() {
121+ function test_opacity(data) {
195 init_test();
122 init_test();
196
123
197− indicatorRow.state = "initial";
124+ indicatorRow.unitProgress = data.progress;
198− indicatorRow.setCurrentItem(0);
125+ indicatorRow.setCurrentItemIndex(data.index);
199−
200− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in intiial state");
201− compare(get_indicator_item_at(1).dimmed, false, "Other indicators should not dim when in initial state");
202− compare(get_indicator_item_at(2).dimmed, false, "Other indicators should not dim when in initial state");
203− compare(get_indicator_item_at(3).dimmed, false, "Other indicators should not dim when in initial state");
204− compare(get_indicator_item_at(4).dimmed, false, "Other indicators should not dim when in initial state");
205− }
206−
207− function test_hint_state() {
208− init_test();
209
126
210− indicatorRow.state = "hint";
127+ tryCompare(indicatorRow.currentItem, "opacity", data.current);
211− indicatorRow.setCurrentItem(0);
212
128
213− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in hint state");
129+ for (var i = 0; i < indicatorRow.row.count; i++) {
214− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in hint state");
130+ tryCompare(get_indicator_item(i), "opacity", i === data.index ? data.current: data.other);
215− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in hint state");
131+ }
216− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in hint state");
217− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in hint state");
218 }
132 }
219
133
220− function test_revealed_state() {
134+ function test_dimmed_data() {
221− init_test();
135+ return [
222−
136+ { index: 0, progress: 0.0, current: false, other: false },
223− indicatorRow.state = "reveal";
137+ { index: 0, progress: 0.1, current: false, other: true },
224− indicatorRow.setCurrentItem(0);
138+ { index: 0, progress: 0.5, current: false, other: true },
225−
139+ { index: 0, progress: 1.0, current: false, other: true },
226− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in reveal state");
140+ { index: 2, progress: 0.0, current: false, other: false },
227− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in reveal state");
141+ { index: 2, progress: 0.1, current: false, other: true },
228− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in reveal state");
142+ { index: 2, progress: 0.5, current: false, other: true },
229− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in reveal state");
143+ { index: 2, progress: 1.0, current: false, other: true }
230− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in reveal state");
144+ ];
231 }
145 }
232
146
233− function test_commit_state() {
147+ function test_dimmed(data) {
234 init_test();
148 init_test();
235
149
236− indicatorRow.state = "commit";
150+ indicatorRow.unitProgress = data.progress;
237− indicatorRow.setCurrentItem(0);
151+ indicatorRow.setCurrentItemIndex(data.index);
238−
239− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in commit state");
240− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in commit state");
241− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in commit state");
242− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in commit state");
243− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in commit state");
244− }
245−
246− function test_locked_state() {
247− init_test();
248
152
249− indicatorRow.state = "locked";
153+ compare(indicatorRow.currentItem.dimmed, data.current, "Indicator dim did not match for current item");
250− indicatorRow.setCurrentItem(0);
251
154
252− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in locked state");
155+ for (var i = 0; i < indicatorRow.row.count; i++) {
253− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in locked state");
156+ compare(get_indicator_item(i).dimmed, i === data.index ? data.current: data.other, "Indicator dim did not match for item iter");
254− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in locked state");
157+ }
255− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
256− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
257 }
158 }
258 }
159 }
259}
160}
tests/qmltests/Panel/tst_Indicators.qml+40−32
@@ -103,21 +103,23 @@ Item {
103 // tests changing the lateral position of the revealer activates the correct indicator items.
103 // tests changing the lateral position of the revealer activates the correct indicator items.
104
104
105 var indicatorRow = findChild(indicators, "indicatorRow")
105 var indicatorRow = findChild(indicators, "indicatorRow")
106− var rowRepeater = findChild(indicators, "rowRepeater")
106+ verify(indicatorRow !== null);
107+ var indicatorRowItems = findChild(indicatorRow, "indicatorRowItems");
108+ verify(indicatorRowItems !== null);
107
109
108− for (var i = 0; i < rowRepeater.count; i++) {
110+ for (var i = 0; i < indicatorRowItems.count; i++) {
109− var indicatorItem = rowRepeater.itemAt(i);
111+ var indicatorItem = findChild(indicatorRowItems, "item" + i);
110
112
111 if (!indicatorItem.visible)
113 if (!indicatorItem.visible)
112 continue;
114 continue;
113
115
114 var indicatorPosition = indicators.mapFromItem(indicatorItem,
116 var indicatorPosition = indicators.mapFromItem(indicatorItem,
115− indicatorItem.width/2, indicatorItem.height/2)
117+ indicatorItem.width/2, indicatorItem.height/2);
116
118
117 touchFlick(indicators,
119 touchFlick(indicators,
118 indicatorPosition.x, indicatorPosition.y,
120 indicatorPosition.x, indicatorPosition.y,
119 indicatorPosition.x, indicators.openedHeight * 0.4,
121 indicatorPosition.x, indicators.openedHeight * 0.4,
120− true /* beginTouch */, false /* endTouch */)
122+ true /* beginTouch */, false /* endTouch */);
121
123
122 compare(indicatorRow.currentItem, indicatorItem,
124 compare(indicatorRow.currentItem, indicatorItem,
123 "Incorrect item activated at position " + i);
125 "Incorrect item activated at position " + i);
@@ -125,10 +127,10 @@ Item {
125 touchFlick(indicators,
127 touchFlick(indicators,
126 indicatorPosition.x, indicators.openedHeight * 0.4,
128 indicatorPosition.x, indicators.openedHeight * 0.4,
127 indicatorPosition.x, indicatorPosition.y,
129 indicatorPosition.x, indicatorPosition.y,
128− false /* beginTouch */, true /* endTouch */)
130+ false /* beginTouch */, true /* endTouch */);
129
131
130 // wait until fully closed
132 // wait until fully closed
131− tryCompare(indicators, "height", indicators.panelHeight)
133+ tryCompare(indicators, "height", indicators.panelHeight);
132 }
134 }
133 }
135 }
134
136
@@ -141,20 +143,20 @@ Item {
141 function test_progress_changes_state_to_not_initial() {
143 function test_progress_changes_state_to_not_initial() {
142 indicators.height = indicators.openedHeight / 2
144 indicators.height = indicators.openedHeight / 2
143 compare(indicators.state!="initial", true,
145 compare(indicators.state!="initial", true,
144− "Indicators should not be in initial state when partially opened.")
146+ "Indicators should not be in initial state when partially opened.");
145 }
147 }
146
148
147 function test_progress_changes_state_to_locked() {
149 function test_progress_changes_state_to_locked() {
148 indicators.height = indicators.openedHeight - indicators.panelHeight
150 indicators.height = indicators.openedHeight - indicators.panelHeight
149− compare(indicators.state, "locked", "Indicators should be locked when fully opened.")
151+ compare(indicators.state, "locked", "Indicators should be locked when fully opened.");
150 }
152 }
151
153
152 function test_partially_open() {
154 function test_partially_open() {
153 indicators.height = indicators.openedHeight / 2
155 indicators.height = indicators.openedHeight / 2
154 compare(indicators.partiallyOpened, true,
156 compare(indicators.partiallyOpened, true,
155− "Indicator should show as partially opened when height is half of openedHeight")
157+ "Indicator should show as partially opened when height is half of openedHeight");
156 compare(indicators.fullyOpened, false,
158 compare(indicators.fullyOpened, false,
157− "Indicator should not show as fully opened when height is half of openedHeight")
159+ "Indicator should not show as fully opened when height is half of openedHeight");
158 }
160 }
159
161
160 function test_fully_open() {
162 function test_fully_open() {
@@ -164,8 +166,8 @@ Item {
164 }
166 }
165
167
166 function init_invisible_indicator(identifier) {
168 function init_invisible_indicator(identifier) {
167− tryCompareFunction(function() { return findChild(indicators, identifier+"-widget") !== null }, true);
169+ tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true);
168− var item = findChild(indicators, identifier+"-widget");
170+ var item = findChild(indicators, identifier+"-delegate");
169
171
170 item.enabled = false;
172 item.enabled = false;
171 }
173 }
@@ -179,54 +181,60 @@ Item {
179 }
181 }
180
182
181 function test_row_visible_menuContent_visible(data) {
183 function test_row_visible_menuContent_visible(data) {
182−
183 indicators.show();
184 indicators.show();
184
185
185 var indicatorTabs = findChild(indicators, "tabs");
186 var indicatorTabs = findChild(indicators, "tabs");
186− var rowRepeater = findChild(indicators, "rowRepeater")
187+ var indicatorRowItems = findChild(indicators, "indicatorRowItems");
187−
188
188
189+ var count = data.visible.length
189 for (var i = 0; i< data.visible.length; i++) {
190 for (var i = 0; i< data.visible.length; i++) {
190− if (data.visible[i] === false)
191+ if (data.visible[i] === false) {
191 init_invisible_indicator("indicator-fake" + (i + 1));
192 init_invisible_indicator("indicator-fake" + (i + 1));
193+ count--;
194+ }
192 }
195 }
193
196
197+ tryCompare(indicatorRowItems, "count", count);
198+
194 for (i = 0; i < data.visible.length; i++) {
199 for (i = 0; i < data.visible.length; i++) {
195− var shouldBeVisible = data.visible[i];
200+ var widgetName = "indicator-fake" + (i + 1 + "-widget");
201+ var pageName = "indicator-fake" + (i + 1 + "-page");
202+
203+ // check for item
204+ tryCompareFunction(function() { return findChild(indicatorRowItems, widgetName) !== null }, data.visible[i]);
196
205
197− // check item visibility
206+ // check for tab
198− var indicatorItem = rowRepeater.itemAt(i);
199− tryCompare(indicatorItem, "visible", shouldBeVisible);
200− // check tab visibility
201− tryCompareFunction(function() { return findChild(indicatorTabs, "indicator-fake" + (i + 1)) !== null }, shouldBeVisible);
207+ tryCompareFunction(function() { return findChild(indicatorTabs, pageName) !== null }, data.visible[i]);
202 }
208 }
203 }
209 }
204
210
205 function test_indicator_visible_correct_tabs_data() { return [
211 function test_indicator_visible_correct_tabs_data() { return [
206− {tag: "current-first", currentIndex: 0, visible: [false, true, true, true, true], expected: 1 },
212+ {tag: "current-first", currentIndex: 0, visible: [false, true, true, true, true], expectedIndex: 0, expectedTab: "indicator-fake2" },
207− {tag: "current-last", currentIndex: 4, visible: [true, true, true, true, false], expected: 3 },
213+ {tag: "current-last", currentIndex: 4, visible: [true, true, true, true, false], expectedIndex: 3, expectedTab: "indicator-fake4" },
208− {tag: "after", currentIndex: 0, visible: [true, false, true, true, true], expected: 0 },
214+ {tag: "after", currentIndex: 0, visible: [true, false, true, true, true], expectedIndex: 0, expectedTab: "indicator-fake1" },
209− {tag: "before", currentIndex: 1, visible: [false, true, true, true, true], expected: 1 }];
215+ {tag: "before", currentIndex: 1, visible: [false, true, true, true, true], expectedIndex: 1, expectedTab: "indicator-fake2" }];
210 }
216 }
211
217
212 function test_indicator_visible_correct_tabs(data) {
218 function test_indicator_visible_correct_tabs(data) {
213−
214 var indicatorTabs = findChild(indicators, "tabs");
219 var indicatorTabs = findChild(indicators, "tabs");
215 var indicatorRow = findChild(indicators, "indicatorRow");
220 var indicatorRow = findChild(indicators, "indicatorRow");
216
221
217 indicators.show();
222 indicators.show();
218− indicatorRow.setCurrentItem(data.currentIndex);
223+ indicatorRow.setCurrentItemIndex(data.currentIndex);
219 tryCompare(indicators, "fullyOpened", true);
224 tryCompare(indicators, "fullyOpened", true);
220
225
221 for (var i = 0; i< data.visible.length; i++) {
226 for (var i = 0; i< data.visible.length; i++) {
222− if (data.visible[i] === false)
227+ if (data.visible[i] === false) {
223 init_invisible_indicator("indicator-fake" + (i + 1));
228 init_invisible_indicator("indicator-fake" + (i + 1));
229+ }
224 }
230 }
225
231
226 // check for current selected item
232 // check for current selected item
227− tryCompare(indicatorRow, "currentItemIndex", data.expected);
233+ tryCompare(indicatorRow, "currentItemIndex", data.expectedIndex);
234+
228 // check for current selected tab
235 // check for current selected tab
229− tryCompareFunction(function() { return findChild(indicatorTabs, "indicator-fake" + (data.expected + 1)) === indicatorTabs.selectedTab }, true);
236+ tryCompareFunction(function() { return findChild(indicatorTabs, data.expectedTab) === indicatorTabs.selectedTab }, true);
237+
230 }
238 }
231 }
239 }
232}
240}
tests/qmltests/Panel/tst_MenuContent.qml+6−14
@@ -27,11 +27,11 @@ Item {
27 height: units.gu(70)
27 height: units.gu(70)
28
28
29 property var indicator_status: {
29 property var indicator_status: {
30− 'menu_page1': { 'started': false, 'reset': 0 },
30+ 'indicator-fake1-page': { 'started': false, 'reset': 0 },
31− 'menu_page2': { 'started': false, 'reset': 0 },
31+ 'indicator-fake2-page': { 'started': false, 'reset': 0 },
32− 'menu_page3': { 'started': false, 'reset': 0 },
32+ 'indicator-fake3-page': { 'started': false, 'reset': 0 },
33− 'menu_page4': { 'started': false, 'reset': 0 },
33+ 'indicator-fake4-page': { 'started': false, 'reset': 0 },
34− 'menu_page5': { 'started': false, 'reset': 0 }
34+ 'indicator-fake5-page': { 'started': false, 'reset': 0 }
35 }
35 }
36
36
37 // Dummy objects
37 // Dummy objects
@@ -49,14 +49,6 @@ Item {
49 indicatorsModel: indicatorsModel
49 indicatorsModel: indicatorsModel
50 contentReleaseInterval: 50
50 contentReleaseInterval: 50
51 height: parent.height - 50
51 height: parent.height - 50
52−
53− visibleIndicators: {
54− 'indicator-fake1': true,
55− 'indicator-fake2': true,
56− 'indicator-fake3': true,
57− 'indicator-fake4': true,
58− 'indicator-fake5': true
59− }
60 }
52 }
61
53
62 Rectangle {
54 Rectangle {
@@ -96,7 +88,7 @@ Item {
96 }
88 }
97
89
98 function get_test_menu_objecName(index) {
90 function get_test_menu_objecName(index) {
99− return "menu_page"+(index+1);
91+ return "indicator-fake" + (index + 1) + "-page";
100 }
92 }
101
93
102 property string testTabObjectName : ""
94 property string testTabObjectName : ""
tests/qmltests/Panel/tst_Panel.qml+10−12
@@ -65,9 +65,10 @@ Item {
65 }
65 }
66
66
67 function get_indicator_item(index) {
67 function get_indicator_item(index) {
68− var rowRepeater = findChild(panel.indicators, "rowRepeater");
68+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
69− verify(rowRepeater !== null);
69+ verify(indicatorRow !== null);
70− return rowRepeater.itemAt(index);
70+
71+ return findChild(indicatorRow.row, "item" + index);
71 }
72 }
72
73
73 function get_indicator_item_position(index) {
74 function get_indicator_item_position(index) {
@@ -144,10 +145,10 @@ Item {
144 tryCompare(panel.indicators, "fullyOpened", true);
145 tryCompare(panel.indicators, "fullyOpened", true);
145 }
146 }
146
147
147− var indicatorRow = findChild(panel.indicators, "indicatorRow");
148+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
148 verify(indicatorRow !== null);
149 verify(indicatorRow !== null);
149
150
150− var rowRepeater = findChild(panel.indicators, "rowRepeater");
151+ var menuContent = findChild(panel.indicators, "menuContent");
151 verify(indicatorRow !== null);
152 verify(indicatorRow !== null);
152
153
153 var menuContent = findChild(panel.indicators, "menuContent");
154 var menuContent = findChild(panel.indicators, "menuContent");
@@ -162,10 +163,10 @@ Item {
162 }
163 }
163
164
164 // do this for each indicator item
165 // do this for each indicator item
165− for (var i = 0; i < rowRepeater.count; i++) {
166+ for (var i = 0; i < indicatorRow.row.count; i++) {
166
167
167 var indicatorItem = get_indicator_item(i);
168 var indicatorItem = get_indicator_item(i);
168− verify(indicatorItem != undefined);
169+ verify(indicatorItem !== null);
169
170
170 if (!indicatorItem.visible)
171 if (!indicatorItem.visible)
171 continue;
172 continue;
@@ -236,15 +237,12 @@ Item {
236 var indicatorRow = findChild(panel.indicators, "indicatorRow");
237 var indicatorRow = findChild(panel.indicators, "indicatorRow");
237 verify(indicatorRow !== null);
238 verify(indicatorRow !== null);
238
239
239− var rowRepeater = findChild(panel.indicators, "rowRepeater");
240− verify(indicatorRow !== null);
241−
242 // Get the first indicator
240 // Get the first indicator
243 var indicatorItemFirst = get_indicator_item(0);
241 var indicatorItemFirst = get_indicator_item(0);
244− verify(indicatorItemFirst !== undefined);
242+ verify(indicatorItemFirst !== null);
245
243
246 var indicatorItemCoordFirst = get_indicator_item_position(0);
244 var indicatorItemCoordFirst = get_indicator_item_position(0);
247− var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.count - 1);
245+ var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.row.count - 1);
248
246
249 touchPress(panel,
247 touchPress(panel,
250 indicatorItemCoordFirst.x, panel.panelHeight / 2);
248 indicatorItemCoordFirst.x, panel.panelHeight / 2);