Merge lp:~zsombi/ubuntu-ui-toolkit/pickerpanel into lp:ubuntu-ui-toolkit
- pickerpanel
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Tim Peeters |
Approved revision: | 908 |
Merged at revision: | 925 |
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/pickerpanel |
Merge into: | lp:ubuntu-ui-toolkit |
Prerequisite: | lp:~zsombi/ubuntu-ui-toolkit/datepicker |
Diff against target: |
642 lines (+566/-2) 8 files modified
components.api (+3/-0) modules/Ubuntu/Components/Pickers/PickerPanel.qml (+261/-0) modules/Ubuntu/Components/Pickers/PickerRow.qml (+1/-0) modules/Ubuntu/Components/plugin/plugin.cpp (+12/-0) modules/Ubuntu/Components/plugin/plugin.h (+1/-1) tests/resources/pickers/PanelTest.qml (+42/-0) tests/unit/add_qmlmakecheck.pri (+1/-1) tests/unit_x11/tst_components/tst_pickerpanel.qml (+245/-0) |
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/pickerpanel |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Peeters | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+199250@code.launchpad.net |
Commit message
Panel implementation for DatePicker. Presents the DatePicker either in a panel covering the OSK area or in a Popover, depending on the form factor and presence of input method provider.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 902. By Zsombor Egri
-
trunk merge
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:902
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 903. By Zsombor Egri
-
trunk merge
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:903
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 904. By Zsombor Egri
-
trunk merge
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:904
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
Why is there a \qmltype DateTimePanel? Is that different from the PickerPanel?
\qmltype DateTimePanel
\inqmlmodule Ubuntu.
\ingroup ubuntu-pickers
\brief Provides a panel for opening a DatePicker in place of the input panel or
as Popover, depending on the form factor.
PickerPanel is a singleton component designed to open a DatePicker in input panel
area or in a Popover, depending on the form factor, following the design guides
on date pickers.
Tim Peeters (tpeeters) wrote : | # |
20 + * Copyright 2013 Canonical Ltd.
you are sooo behind ;)
Tim Peeters (tpeeters) wrote : | # |
78 + The function opens a date picker panel. The date picker is opened in input
79 + panel area if there is on-screen input panel available and the form factor
80 + describes a phone. The picked date will be read from and reported into the
the sentence doesn't read very fluent..
and what is "form factor describes a phone"? Can you be more specific what you mean?
Tim Peeters (tpeeters) wrote : | # |
80 + describes a phone. The picked date will be read from and reported into the
81 + \a property of the \a caller as date type. This implies that the caller
82 + must have defined a property with date type.
seems a bit vague, and you don't pass this property in the example code:
65 + onClicked: PickerPanel.
Tim Peeters (tpeeters) wrote : | # |
106 + \li \b pickerMode
107 + \li represents the DatePicker \l mode to be used. This is an optional
108 + parameter and if not defined, the default mode will be used.
How do you not pass this optional parameter while still passing the parameters that follow it in the function specifications?
Also, in the returned object, it is not an optional parameter, the property is always there. Only in the function call it is optional.
Tim Peeters (tpeeters) wrote : | # |
09 + \row
110 + \li \b date
111 + \li represents the date selected
The object is returned when the function is called, but the has not picked a date yet then. Can you make that clear in this description?
Tim Peeters (tpeeters) wrote : | # |
112 + \row
113 + \li \b caller
114 + \li the instance of the component opening the panel
Is this optional? I guess it is used for positioning the popover, but that can be done without a caller (it is then centered in the window), and not needed for the panel.
Tim Peeters (tpeeters) wrote : | # |
116 + \li \b callerProperty
117 + \li the property of the caller holding the date value which will be
118 + updated by the picker.
Ignore my previous comment. The callerProperty makes the caller not optional.
Zsombor Egri (zsombi) wrote : | # |
> 20 + * Copyright 2013 Canonical Ltd.
>
>
> you are sooo behind ;)
Am I? This was ready last year, it's you who review it after one year :D
Zsombor Egri (zsombi) wrote : | # |
> Why is there a \qmltype DateTimePanel? Is that different from the PickerPanel?
>
>
> \qmltype DateTimePanel
> \inqmlmodule Ubuntu.
> \ingroup ubuntu-pickers
> \brief Provides a panel for opening a DatePicker in place of the input
> panel or
> as Popover, depending on the form factor.
>
> PickerPanel is a singleton component designed to open a DatePicker in
> input panel
> area or in a Popover, depending on the form factor, following the design
> guides
> on date pickers.
Ehh, that's wrong there.
Tim Peeters (tpeeters) wrote : | # |
150 + property bool formFactorPhone: Screen.width <= units.gu(40) && Screen.height <= units.gu(71)
Do we always have Screen.height >= Screen.width ? What if width = 80, height = 50?
151 + // present in a property so we can test it in
152 + property bool isPhone: false
Is there a design spec that says it should be done like this?
What about a tiny tablet (like ipod touch)?
Tim Peeters (tpeeters) wrote : | # |
> 150 + property bool formFactorPhone: Screen.width <= units.gu(40) &&
> Screen.height <= units.gu(71)
>
> Do we always have Screen.height >= Screen.width ? What if width = 80, height =
> 50?
sorry, the other way around. What if width = 70, height = 30?
Tim Peeters (tpeeters) wrote : | # |
155 + function openPopover(caller, params) {
156 + var panel = PopupUtils.
157 + panel.parent = QuickUtils.
158 + return panel;
159 + }
the name of the variable is a bit misleading here
Tim Peeters (tpeeters) wrote : | # |
329 - QUrl baseUrl(const QStringList& importPathList, const char* uri);
330 + static QUrl baseUrl(const QStringList& importPathList, const char* uri);
why is this needed?
and shouldn't you add the static in the cpp as well?
Tim Peeters (tpeeters) wrote : | # |
The pointer for the panelTest popover is positioned wrong: http://
Tim Peeters (tpeeters) wrote : | # |
431 + Button {
432 + id: defaultAPI
433 + text: "modeSet"
I would put a different text here.
434 + property date buttonDate: new Date()
435 + property Item panel
436 + onClicked: panel = PickerPanel.
437 + }
438 + Button {
439 + id: modeSet
440 + text: "modeSet"
441 + property string mode
442 + property date buttonDate: new Date()
443 + property Item panel
444 + onClicked: panel = PickerPanel.
445 + }
Tim Peeters (tpeeters) wrote : | # |
function test_0_
Instead of this function name, and id: defaultAPI, I think it is more clear if instead of defaultAPI you would say defaultMode everywhere.
Tim Peeters (tpeeters) wrote : | # |
478 + function test_1_modeSet_YM() {
495 + function test_1_modeSet_YD() {
513 + function test_1_
530 + function test_1_modeSet_HS() {
You can combine these in one function with mode, pickerChildrenL
571 + function test_3_modeSet_YM() {
588 + function test_3_modeSet_YD() {
606 + function test_3_
623 + function test_3_modeSet_HS() {
same here
Zsombor Egri (zsombi) wrote : | # |
> 78 + The function opens a date picker panel. The date picker is opened in
> input
> 79 + panel area if there is on-screen input panel available and the form
> factor
> 80 + describes a phone. The picked date will be read from and reported
> into the
>
> the sentence doesn't read very fluent..
> and what is "form factor describes a phone"? Can you be more specific what you
> mean?
Reformulated the sentence, however the phone detection code is still based on 40/71 GU w/h, till we get a proper agreement on how we detect these form factors.
Revision 905
Zsombor Egri (zsombi) wrote : | # |
> 150 + property bool formFactorPhone: Screen.width <= units.gu(40) &&
> Screen.height <= units.gu(71)
>
> Do we always have Screen.height >= Screen.width ? What if width = 80, height =
> 50?
>
> 151 + // present in a property so we can test it in
> 152 + property bool isPhone: false
>
> Is there a design spec that says it should be done like this?
> What about a tiny tablet (like ipod touch)?
You are right in a sense that we have w/h 40/71 or h/w 40/71, due to landscape. And then we still need to show the picker in OSK area.
We don't have design spec, the wiki was the only thing we followed at some extent. I hate to say, but this whole component was really a mess from UX point of view. So all we have here is based on the UX guys, and they said they will return back once they have time to check it. So we will most probably have some updates later on this, Jouni promised to take a look at some point when the storm goes down. OSK area is a must, that's for sure, the Popover was suggested by me on higher FFs like tablet, desktop, TV, aso. He agreed that it is good to have it in such a way, let's see how we proceed with that.
iPod touch is NOT a tablet, Tim, sorry to disappoint you :)
Zsombor Egri (zsombi) wrote : | # |
> 155 + function openPopover(caller, params) {
> 156 + var panel = PopupUtils.
> 157 + panel.parent = QuickUtils.
> 158 + return panel;
> 159 + }
>
> the name of the variable is a bit misleading here
I don't get it. Why? It can be a popover or an OSK panel... In a sense Popover is also a panel... and panel is also a popover... would you like to see popup there? OK, I'll rename to popover, but just for you :)
Zsombor Egri (zsombi) wrote : | # |
> 329 - QUrl baseUrl(const QStringList& importPathList, const char* uri);
> 330 + static QUrl baseUrl(const QStringList& importPathList, const char*
> uri);
>
>
> why is this needed?
It is needed for us to return the base path to the location of the Ubuntu Components library so we know where to search for the rest of the QML files to be used as sigleton types. This method was there before, all I did is I defined the function to be static, so it can be accessed in other singleton definition functions.
Btw, there's a comment in the body of the function, so we may get rid of this method once we go for Qt5.2, however as far as I see that method does a bit differently... Let's see.
> and shouldn't you add the static in the cpp as well?
Khmm... I pretend I have not seen this question... :) C++ basics...
Zsombor Egri (zsombi) wrote : | # |
> The pointer for the panelTest popover is positioned wrong:
> http://
That seems to be a PopoverBug, right?
Zsombor Egri (zsombi) wrote : | # |
> 431 + Button {
> 432 + id: defaultAPI
> 433 + text: "modeSet"
>
> I would put a different text here.
Done.
>
> 434 + property date buttonDate: new Date()
> 435 + property Item panel
> 436 + onClicked: panel = PickerPanel.
> "buttonDate")
> 437 + }
> 438 + Button {
> 439 + id: modeSet
> 440 + text: "modeSet"
> 441 + property string mode
> 442 + property date buttonDate: new Date()
> 443 + property Item panel
> 444 + onClicked: panel = PickerPanel.
> mode)
> 445 + }
Zsombor Egri (zsombi) wrote : | # |
> function test_0_
>
>
> Instead of this function name, and id: defaultAPI, I think it is more clear if
> instead of defaultAPI you would say defaultMode everywhere.
Done
Zsombor Egri (zsombi) wrote : | # |
> 478 + function test_1_modeSet_YM() {
> 495 + function test_1_modeSet_YD() {
> 513 + function test_1_
> 530 + function test_1_modeSet_HS() {
>
> You can combine these in one function with mode, pickerChildrenL
> modeIsValid parameters.
>
> 571 + function test_3_modeSet_YM() {
> 588 + function test_3_modeSet_YD() {
> 606 + function test_3_
> 623 + function test_3_modeSet_HS() {
>
> same here
Nope. These modes are better to be tested separately, detecting the problem is lot easier in separate tests.
- 905. By Zsombor Egri
-
function documentation reformulated
- 906. By Zsombor Egri
-
variable name fixed
- 907. By Zsombor Egri
-
update test cases
- 908. By Zsombor Egri
-
trunk merge
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:907
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:908
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
> > and shouldn't you add the static in the cpp as well?
> Khmm... I pretend I have not seen this question... :) C++ basics...
uhm, yeah. thank you :)
Tim Peeters (tpeeters) wrote : | # |
> > The pointer for the panelTest popover is positioned wrong:
> > http://
>
> That seems to be a PopoverBug, right?
yes
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2013-12-13 14:10:39 +0000 |
3 | +++ components.api 2014-01-20 07:58:18 +0000 |
4 | @@ -286,6 +286,9 @@ |
5 | modules/Ubuntu/Components/Pickers/PickerDelegate.qml |
6 | AbstractButton |
7 | readonly property Picker picker |
8 | +modules/Ubuntu/Components/Pickers/PickerPanel.qml |
9 | +Object |
10 | + function openDatePicker(caller, property, mode) |
11 | modules/Ubuntu/Components/Popups/ActionSelectionPopover.qml |
12 | Popover |
13 | property Item target |
14 | |
15 | === added file 'modules/Ubuntu/Components/Pickers/PickerPanel.qml' |
16 | --- modules/Ubuntu/Components/Pickers/PickerPanel.qml 1970-01-01 00:00:00 +0000 |
17 | +++ modules/Ubuntu/Components/Pickers/PickerPanel.qml 2014-01-20 07:58:18 +0000 |
18 | @@ -0,0 +1,261 @@ |
19 | +/* |
20 | + * Copyright 2014 Canonical Ltd. |
21 | + * |
22 | + * This program is free software; you can redistribute it and/or modify |
23 | + * it under the terms of the GNU Lesser General Public License as published by |
24 | + * the Free Software Foundation; version 3. |
25 | + * |
26 | + * This program is distributed in the hope that it will be useful, |
27 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 | + * GNU Lesser General Public License for more details. |
30 | + * |
31 | + * You should have received a copy of the GNU Lesser General Public License |
32 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
33 | + */ |
34 | + |
35 | +import QtQuick 2.0 |
36 | +import QtQuick.Window 2.0 |
37 | +import Ubuntu.Components 0.1 |
38 | +import Ubuntu.Components.ListItems 0.1 |
39 | +import Ubuntu.Components.Popups 0.1 |
40 | + |
41 | +/*! |
42 | + \qmltype PickerPanel |
43 | + \inqmlmodule Ubuntu.Components 0.1 |
44 | + \ingroup ubuntu-pickers |
45 | + \brief Provides a panel for opening a DatePicker in place of the input panel or |
46 | + as Popover, depending on the form factor. |
47 | + |
48 | + PickerPanel is a singleton component designed to open a DatePicker in input panel |
49 | + area or in a Popover, depending on the form factor, following the design guides |
50 | + on date pickers. |
51 | + \qml |
52 | + import QtQuick 2.0 |
53 | + import Ubuntu.Components 0.1 |
54 | + |
55 | + MainWindow { |
56 | + width: units.gu(40) |
57 | + height: units.gu(71) |
58 | + |
59 | + Page { |
60 | + title: "PickerPanel" |
61 | + Button { |
62 | + id: dateButton |
63 | + property date date: new Date() |
64 | + text: Qt.formatDateTime(date, "yyyy/MMMM") |
65 | + onClicked: PickerPanel.openDatePicker(dateButton, "date", "Years|Months") |
66 | + } |
67 | + } |
68 | + } |
69 | + \endqml |
70 | + |
71 | + The opened panel is closed automatically when the user taps/presses outside |
72 | + of the panel or Popover area. |
73 | + */ |
74 | + |
75 | +Object { |
76 | + |
77 | + /*! |
78 | + The function opend a DatePicker component in the input method area or in a |
79 | + popover depending on the availability of an input method provider in the |
80 | + system, and whether the size of the main screen width/height defines a phone |
81 | + form factor. The picked date will be read from and reported into the \a property |
82 | + of the \a caller as date type. This implies that the caller must have defined a |
83 | + property with date type. |
84 | + |
85 | + On failure the function returns null. On success the returned object has the |
86 | + following properties: |
87 | + \code |
88 | + Object { |
89 | + property DatePicker picker |
90 | + property string pickerMode |
91 | + property date date |
92 | + property Item caller |
93 | + property string callerProperty |
94 | + |
95 | + signal closed() |
96 | + } |
97 | + \endcode |
98 | + |
99 | + \table |
100 | + \header |
101 | + \li Property |
102 | + \li Description |
103 | + \row |
104 | + \li \b picker |
105 | + \li instance of the DatePicker component shown in the panel/popup |
106 | + \row |
107 | + \li \b pickerMode |
108 | + \li represents the \l DatePicker::mode to be used. This is an optional |
109 | + parameter and if not defined, the default mode will be used. |
110 | + \row |
111 | + \li \b date |
112 | + \li represents the date selected |
113 | + \row |
114 | + \li \b caller |
115 | + \li the instance of the component opening the panel |
116 | + \row |
117 | + \li \b callerProperty |
118 | + \li the property of the caller holding the date value which will be |
119 | + updated by the picker. |
120 | + \header |
121 | + \li Signal |
122 | + \li Description |
123 | + \row |
124 | + \li closed() |
125 | + \li the signal is emitted when the panel or popover gets closed. The |
126 | + signal is handy when actions are performed upon panel close. |
127 | + \endtable |
128 | + */ |
129 | + function openDatePicker(caller, property, mode) { |
130 | + if (mode === undefined) { |
131 | + mode = "Years|Months|Days"; |
132 | + } |
133 | + var params = { |
134 | + "date": caller[property], |
135 | + "pickerMode": mode, |
136 | + "callerProperty": property |
137 | + } |
138 | + |
139 | + if (!internal.isPhone) { |
140 | + // we have no input panel defined, or the therefore we show the picker in a Popover |
141 | + return internal.openPopover(caller, params); |
142 | + } |
143 | + // OSK panel |
144 | + return internal.openPanel(caller, params); |
145 | + } |
146 | + |
147 | + QtObject { |
148 | + id: internal |
149 | + objectName: "PickerPanel_Internals" |
150 | + |
151 | + property bool formFactorPhone: Screen.width <= units.gu(40) && Screen.height <= units.gu(71) |
152 | + // present in a property so we can test it in |
153 | + property bool isPhone: false |
154 | + Component.onCompleted: isPhone = formFactorPhone && (QuickUtils.inputMethodProvider !== "") |
155 | + |
156 | + function openPopover(caller, params) { |
157 | + var popover = PopupUtils.open(datePickerPopover, caller, params); |
158 | + popover.parent = QuickUtils.rootItem(null); |
159 | + return popover; |
160 | + } |
161 | + function openPanel(caller, params) { |
162 | + params["caller"] = caller; |
163 | + var panel = datePickerPanel.createObject(QuickUtils.rootItem(null), params); |
164 | + return panel; |
165 | + } |
166 | + } |
167 | + |
168 | + // popover |
169 | + Component { |
170 | + id: datePickerPopover |
171 | + Popover { |
172 | + property alias picker: picker |
173 | + property alias date: picker.date |
174 | + property alias pickerMode: picker.mode |
175 | + property string callerProperty |
176 | + |
177 | + signal closed() |
178 | + |
179 | + contentWidth: frame.width |
180 | + contentHeight: frame.height |
181 | + |
182 | + Item { |
183 | + id: frame |
184 | + width: picker.width + units.gu(4) |
185 | + height: picker.height + units.gu(4) |
186 | + DatePicker { |
187 | + id: picker |
188 | + anchors.centerIn: parent |
189 | + Binding { |
190 | + target: caller |
191 | + property: callerProperty |
192 | + when: callerProperty != undefined |
193 | + value: picker.date |
194 | + } |
195 | + } |
196 | + } |
197 | + Component.onDestruction: closed() |
198 | + } |
199 | + } |
200 | + |
201 | + // OSK panel |
202 | + Component { |
203 | + id: datePickerPanel |
204 | + Rectangle { |
205 | + property alias picker: picker |
206 | + property alias date: picker.date |
207 | + property alias pickerMode: picker.mode |
208 | + property string callerProperty |
209 | + property Item caller |
210 | + |
211 | + signal closed() |
212 | + |
213 | + id: panel |
214 | + // no additional styling is needed |
215 | + color: Theme.palette.normal.overlay |
216 | + width: parent.width |
217 | + height: Qt.inputMethod.keyboardRectangle.height > 0 ? Qt.inputMethod.keyboardRectangle.height : units.gu(26) |
218 | + y: parent.height |
219 | + |
220 | + ThinDivider { anchors.bottom: parent.top } |
221 | + DatePicker { |
222 | + id: picker |
223 | + anchors { |
224 | + fill: panel |
225 | + margins: units.gu(2) |
226 | + } |
227 | + Binding { |
228 | + target: caller |
229 | + property: callerProperty |
230 | + when: callerProperty != undefined |
231 | + value: picker.date |
232 | + } |
233 | + } |
234 | + |
235 | + InverseMouseArea { |
236 | + anchors.fill: parent |
237 | + onPressed: panel.state = '' |
238 | + } |
239 | + |
240 | + Component.onCompleted: state = 'opened' |
241 | + |
242 | + states: [ |
243 | + State { |
244 | + name: 'opened' |
245 | + PropertyChanges { |
246 | + target: panel |
247 | + y: parent.height - height |
248 | + } |
249 | + } |
250 | + ] |
251 | + transitions: [ |
252 | + Transition { |
253 | + from: '' |
254 | + to: 'opened' |
255 | + UbuntuNumberAnimation { |
256 | + target: panel |
257 | + property: 'y' |
258 | + } |
259 | + }, |
260 | + Transition { |
261 | + from: 'opened' |
262 | + to: '' |
263 | + SequentialAnimation { |
264 | + UbuntuNumberAnimation { |
265 | + target: panel |
266 | + property: 'y' |
267 | + } |
268 | + ScriptAction { |
269 | + script: { |
270 | + closed(); |
271 | + panel.destroy(); |
272 | + } |
273 | + } |
274 | + } |
275 | + } |
276 | + ] |
277 | + } |
278 | + } |
279 | +} |
280 | |
281 | === modified file 'modules/Ubuntu/Components/Pickers/PickerRow.qml' |
282 | --- modules/Ubuntu/Components/Pickers/PickerRow.qml 2013-12-16 14:53:37 +0000 |
283 | +++ modules/Ubuntu/Components/Pickers/PickerRow.qml 2014-01-20 07:58:18 +0000 |
284 | @@ -47,6 +47,7 @@ |
285 | circular: pickerModel.circular |
286 | live: false |
287 | width: pickerModel.pickerWidth |
288 | + height: parent.height |
289 | |
290 | style: Rectangle { |
291 | anchors.fill: parent |
292 | |
293 | === modified file 'modules/Ubuntu/Components/plugin/plugin.cpp' |
294 | --- modules/Ubuntu/Components/plugin/plugin.cpp 2013-11-19 17:26:04 +0000 |
295 | +++ modules/Ubuntu/Components/plugin/plugin.cpp 2014-01-20 07:58:18 +0000 |
296 | @@ -59,6 +59,16 @@ |
297 | * Type registration functions. |
298 | */ |
299 | |
300 | +static QObject *registerPickerPanel(QQmlEngine *engine, QJSEngine *scriptEngine) |
301 | +{ |
302 | + Q_UNUSED(scriptEngine) |
303 | + |
304 | + const char *uri = "Ubuntu.Components"; |
305 | + QString qmlFile("Pickers/PickerPanel.qml"); |
306 | + QUrl url = UbuntuComponentsPlugin::baseUrl(engine->importPathList(), uri).resolved(QUrl::fromLocalFile(qmlFile)); |
307 | + return QuickUtils::instance().createQmlObject(url); |
308 | +} |
309 | + |
310 | static QObject *registerClipboard(QQmlEngine *engine, QJSEngine *scriptEngine) |
311 | { |
312 | Q_UNUSED(engine) |
313 | @@ -164,6 +174,8 @@ |
314 | qmlRegisterSingletonType<UCUriHandler>(uri, 0, 1, "UriHandler", registerUriHandler); |
315 | // Needed for unit tests |
316 | qRegisterMetaType<QList <QQmlError> >(); |
317 | + // register QML singletons |
318 | + qmlRegisterSingletonType<QObject>(uri, 0, 1, "PickerPanel", registerPickerPanel); |
319 | } |
320 | |
321 | void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) |
322 | |
323 | === modified file 'modules/Ubuntu/Components/plugin/plugin.h' |
324 | --- modules/Ubuntu/Components/plugin/plugin.h 2013-10-18 08:56:39 +0000 |
325 | +++ modules/Ubuntu/Components/plugin/plugin.h 2014-01-20 07:58:18 +0000 |
326 | @@ -32,7 +32,7 @@ |
327 | public: |
328 | void registerTypes(const char *uri); |
329 | void initializeEngine(QQmlEngine *engine, const char *uri); |
330 | - QUrl baseUrl(const QStringList& importPathList, const char* uri); |
331 | + static QUrl baseUrl(const QStringList& importPathList, const char* uri); |
332 | void registerQmlSingletonType(QQmlEngine *engine, const char* uri, const char* typeName, const char* qmlFile); |
333 | |
334 | private Q_SLOTS: |
335 | |
336 | === added file 'tests/resources/pickers/PanelTest.qml' |
337 | --- tests/resources/pickers/PanelTest.qml 1970-01-01 00:00:00 +0000 |
338 | +++ tests/resources/pickers/PanelTest.qml 2014-01-20 07:58:18 +0000 |
339 | @@ -0,0 +1,42 @@ |
340 | +/* |
341 | + * Copyright 2012 Canonical Ltd. |
342 | + * |
343 | + * This program is free software; you can redistribute it and/or modify |
344 | + * it under the terms of the GNU Lesser General Public License as published by |
345 | + * the Free Software Foundation; version 3. |
346 | + * |
347 | + * This program is distributed in the hope that it will be useful, |
348 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
349 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
350 | + * GNU Lesser General Public License for more details. |
351 | + * |
352 | + * You should have received a copy of the GNU Lesser General Public License |
353 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
354 | + */ |
355 | + |
356 | +import QtQuick 2.0 |
357 | +import Ubuntu.Components 0.1 |
358 | +import Ubuntu.Components.Pickers 0.1 |
359 | + |
360 | +MainView { |
361 | + width: units.gu(40) |
362 | + height: units.gu(71) |
363 | + |
364 | + Column { |
365 | + Button { |
366 | + id: datePickerButton |
367 | + property date date: new Date() |
368 | + text: "Date picker: " + Qt.formatDate(date, "yyyy/MMMM/dd dddd") |
369 | + onClicked: { |
370 | + var picker = PickerPanel.openDatePicker(datePickerButton, "date", "Years|Months|Days") |
371 | + picker.picker.locale = Qt.locale("hu_HU") |
372 | + } |
373 | + } |
374 | + Button { |
375 | + id: timePickerButton |
376 | + property date date: new Date() |
377 | + text: "Time picker: " + Qt.formatTime(date, "hh:mm:ss") |
378 | + onClicked: PickerPanel.openDatePicker(timePickerButton, "date", "Hours|Minutes|Seconds") |
379 | + } |
380 | + } |
381 | +} |
382 | |
383 | === modified file 'tests/unit/add_qmlmakecheck.pri' |
384 | --- tests/unit/add_qmlmakecheck.pri 2013-12-13 15:50:35 +0000 |
385 | +++ tests/unit/add_qmlmakecheck.pri 2014-01-20 07:58:18 +0000 |
386 | @@ -10,5 +10,5 @@ |
387 | check.commands += cd ../../..; |
388 | check.commands += qmlplugindump Ubuntu.Components 0.1 modules > plugins.qmltypes; |
389 | # Palette gets included in Qt 5.2 qmlplugindump even though it's qml |
390 | -check.commands += BUILTINS=QQuick,QQml,U1db::,Palette python tests/qmlapicheck.py modules/Ubuntu/Components/qmldir modules/Ubuntu/Components/Colors/UbuntuColors.qml modules/Ubuntu/Components/*/qmldir plugins.qmltypes > components.api.new; |
391 | +check.commands += BUILTINS=QQuick,QQml,U1db::,Palette python tests/qmlapicheck.py modules/Ubuntu/Components/qmldir modules/Ubuntu/Components/Colors/UbuntuColors.qml modules/Ubuntu/Components/Pickers/PickerPanel.qml modules/Ubuntu/Components/*/qmldir plugins.qmltypes > components.api.new; |
392 | check.commands += diff -Fqml -u components.api components.api.new || exit 1; cd tests/unit |
393 | |
394 | === added file 'tests/unit_x11/tst_components/tst_pickerpanel.qml' |
395 | --- tests/unit_x11/tst_components/tst_pickerpanel.qml 1970-01-01 00:00:00 +0000 |
396 | +++ tests/unit_x11/tst_components/tst_pickerpanel.qml 2014-01-20 07:58:18 +0000 |
397 | @@ -0,0 +1,245 @@ |
398 | +/* |
399 | + * Copyright 2013 Canonical Ltd. |
400 | + * |
401 | + * This program is free software; you can redistribute it and/or modify |
402 | + * it under the terms of the GNU Lesser General Public License as published by |
403 | + * the Free Software Foundation; version 3. |
404 | + * |
405 | + * This program is distributed in the hope that it will be useful, |
406 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
407 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
408 | + * GNU Lesser General Public License for more details. |
409 | + * |
410 | + * You should have received a copy of the GNU Lesser General Public License |
411 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
412 | + */ |
413 | + |
414 | +import QtQuick 2.0 |
415 | +import QtTest 1.0 |
416 | +import Ubuntu.Test 0.1 |
417 | +import Ubuntu.Components 0.1 |
418 | +import Ubuntu.Components.Pickers 0.1 |
419 | + |
420 | +Item { |
421 | + id: testSuite |
422 | + width: units.gu(40) |
423 | + height: units.gu(71) |
424 | + |
425 | + Flow { |
426 | + anchors { |
427 | + fill: parent |
428 | + // give a margin so we can dismiss panels |
429 | + topMargin: units.gu(4) |
430 | + } |
431 | + |
432 | + Button { |
433 | + id: defaultMode |
434 | + text: "defaultMode" |
435 | + property date buttonDate: new Date() |
436 | + property Item panel |
437 | + onClicked: panel = PickerPanel.openDatePicker(defaultMode, "buttonDate") |
438 | + } |
439 | + Button { |
440 | + id: modeSet |
441 | + text: "modeSet" |
442 | + property string mode |
443 | + property date buttonDate: new Date() |
444 | + property Item panel |
445 | + onClicked: panel = PickerPanel.openDatePicker(modeSet, "buttonDate", mode) |
446 | + } |
447 | + } |
448 | + |
449 | + SignalSpy { |
450 | + id: closeSpy |
451 | + signalName: "closed" |
452 | + } |
453 | + |
454 | + UbuntuTestCase { |
455 | + name: "PickerPanelAPI" |
456 | + when: windowShown |
457 | + |
458 | + function initTestCase() { |
459 | + waitForRendering(testSuite); |
460 | + } |
461 | + |
462 | + function test_0_clickOndefaultMode() { |
463 | + mouseClick(defaultMode, units.gu(1), units.gu(1)); |
464 | + verify(defaultMode.panel !== null, "the picker is not opened"); |
465 | + verify(defaultMode.panel.picker !== null, "the DatePicker is not defined"); |
466 | + compare(defaultMode.panel.pickerMode, "Years|Months|Days", "the mode from the picker is not the default"); |
467 | + compare(defaultMode.panel.date, defaultMode.buttonDate, "the date from the picker differs from the button's"); |
468 | + compare(defaultMode.panel.caller, defaultMode, "wrong caller"); |
469 | + compare(defaultMode.panel.callerProperty, "buttonDate", "wrong callerProperty"); |
470 | + verify(defaultMode.panel.hasOwnProperty("closed"), "the object has no closed signal"); |
471 | + |
472 | + // dismiss |
473 | + closeSpy.clear(); |
474 | + closeSpy.target = defaultMode.panel; |
475 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
476 | + closeSpy.wait(); |
477 | + } |
478 | + |
479 | + function test_1_modeSet_YM() { |
480 | + modeSet.mode = "Years|Months" ; |
481 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
482 | + verify(modeSet.panel !== null, "the picker is opened"); |
483 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
484 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
485 | + // check the number of pickers |
486 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
487 | + compare(picker.children.length, 3, "there is not enough pickers in the panel"); |
488 | + |
489 | + // dismiss |
490 | + closeSpy.clear(); |
491 | + closeSpy.target = modeSet.panel; |
492 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
493 | + closeSpy.wait(); |
494 | + } |
495 | + |
496 | + function test_1_modeSet_YD() { |
497 | + modeSet.mode = "Years|Days" ; |
498 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
499 | + verify(modeSet.panel !== null, "the picker is opened"); |
500 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
501 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
502 | + // check the number of pickers |
503 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
504 | + expectFailContinue("", "this mode is invalid"); |
505 | + compare(picker.children.length, 2, "there is not enough pickers in the panel"); |
506 | + |
507 | + // dismiss |
508 | + closeSpy.clear(); |
509 | + closeSpy.target = modeSet.panel; |
510 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
511 | + closeSpy.wait(); |
512 | + } |
513 | + |
514 | + function test_1_modeSet_HMS() { |
515 | + modeSet.mode = "Hours|Minutes|Seconds" ; |
516 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
517 | + verify(modeSet.panel !== null, "the picker is opened"); |
518 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
519 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
520 | + // check the number of pickers |
521 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
522 | + compare(picker.children.length, 4, "there is not enough pickers in the panel"); |
523 | + |
524 | + // dismiss |
525 | + closeSpy.clear(); |
526 | + closeSpy.target = modeSet.panel; |
527 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
528 | + closeSpy.wait(); |
529 | + } |
530 | + |
531 | + function test_1_modeSet_HS() { |
532 | + modeSet.mode = "Hours|Seconds" ; |
533 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
534 | + verify(modeSet.panel !== null, "the picker is opened"); |
535 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
536 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
537 | + // check the number of pickers |
538 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
539 | + expectFailContinue("", "this mode is invalid"); |
540 | + compare(picker.children.length, 2, "there is not enough pickers in the panel"); |
541 | + |
542 | + // dismiss |
543 | + closeSpy.clear(); |
544 | + closeSpy.target = modeSet.panel; |
545 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
546 | + closeSpy.wait(); |
547 | + } |
548 | + |
549 | + // forced panel tests |
550 | + // these should be executed as last ones |
551 | + function test_2_clickOndefaultMode() { |
552 | + // force panel - this is private specific!!! |
553 | + var privates = findChild(PickerPanel, "PickerPanel_Internals"); |
554 | + privates.isPhone = true; |
555 | + |
556 | + mouseClick(defaultMode, units.gu(1), units.gu(1)); |
557 | + verify(defaultMode.panel !== null, "the picker is not opened"); |
558 | + verify(defaultMode.panel.picker !== null, "the DatePicker is not defined"); |
559 | + compare(defaultMode.panel.pickerMode, "Years|Months|Days", "the mode from the picker is not the default"); |
560 | + compare(defaultMode.panel.date, defaultMode.buttonDate, "the date from the picker differs from the button's"); |
561 | + compare(defaultMode.panel.caller, defaultMode, "wrong caller"); |
562 | + compare(defaultMode.panel.callerProperty, "buttonDate", "wrong callerProperty"); |
563 | + verify(defaultMode.panel.hasOwnProperty("closed"), "the object has no closed signal"); |
564 | + |
565 | + // dismiss |
566 | + closeSpy.clear(); |
567 | + closeSpy.target = defaultMode.panel; |
568 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
569 | + closeSpy.wait(); |
570 | + } |
571 | + |
572 | + function test_3_modeSet_YM() { |
573 | + modeSet.mode = "Years|Months" ; |
574 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
575 | + verify(modeSet.panel !== null, "the picker is opened"); |
576 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
577 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
578 | + // check the number of pickers |
579 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
580 | + compare(picker.children.length, 3, "there is not enough pickers in the panel"); |
581 | + |
582 | + // dismiss |
583 | + closeSpy.clear(); |
584 | + closeSpy.target = modeSet.panel; |
585 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
586 | + closeSpy.wait(); |
587 | + } |
588 | + |
589 | + function test_3_modeSet_YD() { |
590 | + modeSet.mode = "Years|Days" ; |
591 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
592 | + verify(modeSet.panel !== null, "the picker is opened"); |
593 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
594 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
595 | + // check the number of pickers |
596 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
597 | + expectFailContinue("", "this mode is invalid"); |
598 | + compare(picker.children.length, 2, "there is not enough pickers in the panel"); |
599 | + |
600 | + // dismiss |
601 | + closeSpy.clear(); |
602 | + closeSpy.target = modeSet.panel; |
603 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
604 | + closeSpy.wait(); |
605 | + } |
606 | + |
607 | + function test_3_modeSet_HMS() { |
608 | + modeSet.mode = "Hours|Minutes|Seconds" ; |
609 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
610 | + verify(modeSet.panel !== null, "the picker is opened"); |
611 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
612 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
613 | + // check the number of pickers |
614 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
615 | + compare(picker.children.length, 4, "there is not enough pickers in the panel"); |
616 | + |
617 | + // dismiss |
618 | + closeSpy.clear(); |
619 | + closeSpy.target = modeSet.panel; |
620 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
621 | + closeSpy.wait(); |
622 | + } |
623 | + |
624 | + function test_3_modeSet_HS() { |
625 | + modeSet.mode = "Hours|Seconds" ; |
626 | + mouseClick(modeSet, units.gu(1), units.gu(1)); |
627 | + verify(modeSet.panel !== null, "the picker is opened"); |
628 | + compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); |
629 | + compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); |
630 | + // check the number of pickers |
631 | + var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); |
632 | + expectFailContinue("", "this mode is invalid"); |
633 | + compare(picker.children.length, 2, "there is not enough pickers in the panel"); |
634 | + |
635 | + // dismiss |
636 | + closeSpy.clear(); |
637 | + closeSpy.target = modeSet.panel; |
638 | + mouseClick(testSuite, units.gu(1), units.gu(1)); |
639 | + closeSpy.wait(); |
640 | + } |
641 | + } |
642 | +} |
PASSED: Continuous integration, rev:901 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- ci/1468/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 1781 jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/1701 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- amd64-ci/ 416 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 416 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 416/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-trusty/ 1573 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/1781 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/1781/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/1701 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/1701/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- runner- mako/4204 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 2431
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- ui-toolkit- ci/1468/ rebuild
http://