Merge lp:~zsombi/ubuntu-ui-toolkit/pickerpanel into lp:ubuntu-ui-toolkit

Proposed by Zsombor Egri
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
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.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
902. By Zsombor Egri

trunk merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
903. By Zsombor Egri

trunk merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
904. By Zsombor Egri

trunk merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

Why is there a \qmltype DateTimePanel? Is that different from the PickerPanel?

    \qmltype DateTimePanel
    \inqmlmodule Ubuntu.Components.Pickers 0.1
    \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.

review: Needs Information
Revision history for this message
Tim Peeters (tpeeters) wrote :

20 + * Copyright 2013 Canonical Ltd.

you are sooo behind ;)

Revision history for this message
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?

Revision history for this message
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.openDatePicker(dateButton, "date", "Years|Months")

Revision history for this message
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.

Revision history for this message
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?

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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

Revision history for this message
Zsombor Egri (zsombi) wrote :

> Why is there a \qmltype DateTimePanel? Is that different from the PickerPanel?
>
>
> \qmltype DateTimePanel
> \inqmlmodule Ubuntu.Components.Pickers 0.1
> \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.

Revision history for this message
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)?

Revision history for this message
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?

Revision history for this message
Tim Peeters (tpeeters) wrote :

155 + function openPopover(caller, params) {
156 + var panel = PopupUtils.open(datePickerPopover, caller, params);
157 + panel.parent = QuickUtils.rootItem(null);
158 + return panel;
159 + }

the name of the variable is a bit misleading here

Revision history for this message
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?

review: Needs Information
Revision history for this message
Tim Peeters (tpeeters) wrote :

The pointer for the panelTest popover is positioned wrong: http://ubuntuone.com/32S6rK0ZvL35SR6aCK76Lj

review: Needs Fixing
Revision history for this message
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.openDatePicker(defaultAPI, "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.openDatePicker(modeSet, "buttonDate", mode)
445 + }

Revision history for this message
Tim Peeters (tpeeters) wrote :

 function test_0_clickOnDefaultAPI()

Instead of this function name, and id: defaultAPI, I think it is more clear if instead of defaultAPI you would say defaultMode everywhere.

Revision history for this message
Tim Peeters (tpeeters) wrote :

478 + function test_1_modeSet_YM() {
495 + function test_1_modeSet_YD() {
513 + function test_1_modeSet_HMS() {
530 + function test_1_modeSet_HS() {

You can combine these in one function with mode, pickerChildrenLength, modeIsValid parameters.

571 + function test_3_modeSet_YM() {
588 + function test_3_modeSet_YD() {
606 + function test_3_modeSet_HMS() {
623 + function test_3_modeSet_HS() {

same here

review: Needs Fixing
Revision history for this message
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

Revision history for this message
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 :)

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 155 + function openPopover(caller, params) {
> 156 + var panel = PopupUtils.open(datePickerPopover, caller, params);
> 157 + panel.parent = QuickUtils.rootItem(null);
> 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 :)

Revision history for this message
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...

Revision history for this message
Zsombor Egri (zsombi) wrote :

> The pointer for the panelTest popover is positioned wrong:
> http://ubuntuone.com/32S6rK0ZvL35SR6aCK76Lj

That seems to be a PopoverBug, right?

Revision history for this message
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.openDatePicker(defaultAPI,
> "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.openDatePicker(modeSet, "buttonDate",
> mode)
> 445 + }

Revision history for this message
Zsombor Egri (zsombi) wrote :

> function test_0_clickOnDefaultAPI()
>
>
> Instead of this function name, and id: defaultAPI, I think it is more clear if
> instead of defaultAPI you would say defaultMode everywhere.

Done

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 478 + function test_1_modeSet_YM() {
> 495 + function test_1_modeSet_YD() {
> 513 + function test_1_modeSet_HMS() {
> 530 + function test_1_modeSet_HS() {
>
> You can combine these in one function with mode, pickerChildrenLength,
> modeIsValid parameters.
>
> 571 + function test_3_modeSet_YM() {
> 588 + function test_3_modeSet_YD() {
> 606 + function test_3_modeSet_HMS() {
> 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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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 :)

Revision history for this message
Tim Peeters (tpeeters) wrote :

> > The pointer for the panelTest popover is positioned wrong:
> > http://ubuntuone.com/32S6rK0ZvL35SR6aCK76Lj
>
> That seems to be a PopoverBug, right?

yes

Revision history for this message
Tim Peeters (tpeeters) wrote :

looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+}

Subscribers

People subscribed via source and target branches

to status/vote changes: