components for android added
[mardrone] / mardrone / imports / com / nokia / extras / NetPromoterScore.qml
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt Components project.
8 **
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
11 **
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
14 ** met:
15 **   * Redistributions of source code must retain the above copyright
16 **     notice, this list of conditions and the following disclaimer.
17 **   * Redistributions in binary form must reproduce the above copyright
18 **     notice, this list of conditions and the following disclaimer in
19 **     the documentation and/or other materials provided with the
20 **     distribution.
21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 **     the names of its contributors may be used to endorse or promote
23 **     products derived from this software without specific prior written
24 **     permission.
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 import QtQuick 1.1
42 import com.nokia.meego 1.0
43
44 Rectangle {
45     id: root
46
47     // Common public API
48
49     // Input. Set to true if user is signed in to Nokia account.
50     // Account email using agreement is shown if user is signed in.
51     // Otherwise email input box is shown instead.
52     property bool isSignedIn: false
53
54     // Input. Array of localised UI strings:
55     //    header - 'Tell us what you think'
56     //    question - 'How likely ... ?'
57     //    notLikely - 'Not at all\nlikely'
58     //    extremelyLikely - 'Extremely\nlikely'
59     //    selectScore - 'You must select ...'
60     //    commentsInputLabel - 'Please tell us why ...'
61     //    contactAgreement - 'You can contact me using ...'
62     //    emailInputLabel - 'You can contact me for details...'
63     //    emailPlaceholderText - 'Your email address'
64     //    emailSipActionKeyLabel - 'Done'
65     //    invalidEmail - 'Invalid email address'
66     //    legalText - 'Your information will be ...'
67     //    submit - 'Submit'
68
69     property variant uiString: QtObject {}
70
71     // Input. Array of horizontal alignments for strings. Accept same
72     // values as Text { horizontalAlignment: ... } e.g. Text.AlignLeft, Text.AlignRight and so on.
73     // By default all text strings aligned to the left.
74     //    header
75     //    question
76     //    selectScore
77     //    commentsInputLabel
78     //    contactAgreement
79     //    emailInputLabel
80     //    invalidEmail
81     //    legalText
82
83     property variant uiHorizontalAlignment: QtObject {}
84
85     // Promoter score, between 0 ~ 10
86     property alias score: scoreSlider.value
87
88     // True if user touched score slider
89     property alias scoreTouched: scoreSlider.touched
90
91     // Optional comments text
92     property alias comments: commentsText.text
93
94     // Optional email address
95     // emailAddress shall be ignored if isSignedIn is true.
96     property alias emailAddress: emailAddressField.text
97
98     // True if user agrees to be contacted using Nokia Account email address.
99     // useEmail shall be ignored if isSignedIn is false.
100     property alias useEmail: useEmailCheckBox.checked
101
102     // Signal emitted when 'Submit' button is clicked and form passes validation.
103     signal submit()
104
105     height: childrenRect.height
106     color: "#E0E1E2"
107
108     QtObject {
109         id: internal
110
111         property variant defaultValidator:  RegExpValidator{regExp: /.*/}
112         property variant emailValidator: RegExpValidator{regExp: /^\w([a-zA-Z0-9._-]+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/}
113
114         function validateForm() {
115
116             var isValid = true;
117
118             if (!scoreSlider.touched) {
119                 sliderErrorLabel.visible = true;
120                 isValid = false;
121             }
122
123             if (emailAddress && emailAddress.length > 0) {
124                 var validator =  internal.emailValidator
125                 emailAddressField.validator = validator;
126                 var result = emailAddressField.acceptableInput;
127                 if (result)emailAddressField.validator = internal.defaultValidator;
128                 mouseArea.enabled = !result;
129                 invalidEmailLabel.visible = !result;
130                 if (!result)isValid = false;
131             }
132
133             return isValid;
134         }
135     }
136
137     Column {
138         id: formContent
139
140         anchors {
141             left: parent.left
142             leftMargin: 16
143             right: parent.right
144             rightMargin: 16
145         }
146         height: childrenRect.height
147
148         Item {
149             width: parent.width
150             height: 16
151         }
152
153         Label {
154             id: header
155
156             anchors {
157                 left: parent.left
158                 leftMargin: 18 - parent.anchors.leftMargin
159                 right: parent.right
160             }
161
162             wrapMode: Text.Wrap
163             font.pixelSize: 40
164             color: "#282828"
165             horizontalAlignment: uiHorizontalAlignment.header || Text.AlignLeft
166             text: uiString.header ||
167                   "!!Tell us what you think"
168         }
169
170         Item {
171             width: parent.width
172             height: 12
173         }
174
175         // Question
176         Label {
177             width: parent.width
178             wrapMode: Text.Wrap
179             font.pixelSize: 24
180             color: "#282828"
181             horizontalAlignment: uiHorizontalAlignment.question || Text.AlignLeft
182             text: uiString.question ||
183                   "!!How likely are you to recommend this app to a friend or a colleague?"
184         }
185
186         Item {
187             width: parent.width
188             height: 22
189         }
190
191         // Numbers
192         Row {
193             width: parent.width
194             height: childrenRect.height
195
196             Label {
197                 width: parent.width/2
198                 font.pixelSize: 24
199                 color: "#282828"
200                 horizontalAlignment: Text.AlignLeft
201                 text: "0"
202             }
203             Label {
204                 width: parent.width/2
205                 font.pixelSize: 24
206                 color: "#282828"
207                 horizontalAlignment: Text.AlignRight
208                 text: "10"
209             }
210         }
211
212         Slider {
213             id: scoreSlider
214             objectName: "slider_nps_score"
215
216             property bool touched: false
217             width: parent.width
218             height: 64
219             maximumValue: 10
220             stepSize: 1
221             value: 5
222             valueIndicatorVisible: true
223
224             onPressedChanged:  {
225                 if (pressed) {
226                     sliderErrorLabel.visible = false;
227                     touched = true;
228                 }
229             }
230         }
231
232         // Slider text
233         Row {
234             width: parent.width
235             height: childrenRect.height
236
237             Label {
238                 width: parent.width/3
239                 font.pixelSize: 18
240                 color: "#282828"
241                 horizontalAlignment: Text.AlignLeft
242                 text: uiString.notLikely || "!!Not at all \nlikely"
243             }
244
245             Item {
246                 width: parent.width/3
247                 height: 1
248             }
249
250             Label {
251                 width: parent.width/3
252                 font.pixelSize: 18
253                 color: "#282828"
254                 horizontalAlignment: Text.AlignRight
255                 text: uiString.extremelyLikely || "!!Extremely \nlikely"
256             }
257         }
258
259         Item {
260             width: parent.width
261             height: 8
262             visible: sliderErrorLabel.visible
263         }
264
265         // Slider error text
266         Label {
267             id: sliderErrorLabel
268             visible: false
269             width: parent.width
270             font.pixelSize: 18
271             color: "#FF3200"
272             horizontalAlignment: uiHorizontalAlignment.selectScore || Text.AlignLeft
273             text:  uiString.selectScore ||
274                    "!!You must select a rating"
275         }
276
277         Item {
278             width: parent.width
279             height: 18
280         }
281
282         Image {
283             width: parent.width + 16
284             x: 8 - parent.anchors.leftMargin
285             source: "image://theme/meegotouch-separator-background-horizontal"
286             fillMode: Image.TileHorizontally
287         }
288
289         Item {
290             width: parent.width
291             height: 7
292         }
293
294         Label {
295             width: parent.width
296             font.pixelSize: 22
297             color: "#505050"
298             horizontalAlignment: uiHorizontalAlignment.commentsInputLabel || Text.AlignLeft
299             text:  uiString.commentsInputLabel ||
300                    "!!Please tell us why you gave this score (optional)"
301         }
302
303         SipAttributes {
304             id: sipAttributesDefault
305         }
306
307         // Comments
308         TextArea {
309             id: commentsText
310             width: parent.width
311             height: Math.max(118, implicitHeight)
312             platformSipAttributes: sipAttributesDefault
313         }
314
315         Item {
316             width: parent.width
317             height: 16
318         }
319
320         Row {
321             visible: isSignedIn
322             width: parent.width
323
324             spacing: 16
325
326             CheckBox {
327                 id: useEmailCheckBox
328                 objectName: "check_nps_email"
329                 anchors {
330                     verticalCenter: parent.verticalCenter
331                 }
332             }
333
334             Label {
335                 id: description
336                 anchors {
337                     verticalCenter: parent.verticalCenter
338                 }
339
340                 width: parent.width - useEmailCheckBox.width - parent.spacing
341                 font.pixelSize: 22
342                 wrapMode: Text.Wrap
343                 color: "#505050"
344                 horizontalAlignment: uiHorizontalAlignment.contactAgreement || Text.AlignLeft
345                 text: uiString.contactAgreement ||
346                       "!!You can contact me for details using my Nokia Account e-mail."
347             }
348
349         }
350
351         Image {
352             width: parent.width + 16
353             x: 8 - parent.anchors.leftMargin
354             source: "image://theme/meegotouch-separator-background-horizontal"
355             fillMode: Image.TileHorizontally
356             visible: !isSignedIn
357         }
358
359         // Email address
360         Column {
361             id: emailAddressPane
362             width: parent.width
363             visible: !isSignedIn
364
365             Item {
366                 width: parent.width
367                 height: 7
368             }
369
370             Label {
371                 width: parent.width
372                 font.pixelSize: 22
373                 color: "#505050"
374                 horizontalAlignment: uiHorizontalAlignment.emailInputLabel || Text.AlignLeft
375                 text: uiString.emailInputLabel ||
376                       "!!You can contact me for details (Optional)"
377             }
378
379             TextField {
380                 id: emailAddressField
381                 objectName: "input_nps_email"
382                 width: parent.width
383                 inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhEmailCharactersOnly | Qt.ImhNoAutoUppercase
384                 placeholderText: uiString.emailPlaceholderText ||
385                                  "!!Your email address"
386                 platformSipAttributes: SipAttributes {
387                     actionKeyLabel: uiString.emailSipActionKeyLabel || ""
388                     actionKeyHighlighted: !!uiString.emailSipActionKeyLabel
389                 }
390
391                 Keys.onReturnPressed: {
392                     if (internal.validateForm()) {
393                         platformCloseSoftwareInputPanel();
394                     }
395                 }
396
397                 MouseArea {
398                     id: mouseArea
399                     anchors.fill: parent
400                     enabled: false
401                     z: 10
402                     onClicked: {
403                         enabled = false;
404                         invalidEmailLabel.visible = false;
405                         emailAddressField.forceActiveFocus();
406                         emailAddressField.validator = internal.defaultValidator;
407                     }
408                 }
409
410                 onTextChanged: {
411                     if (invalidEmailLabel.visible) {
412                         invalidEmailLabel.visible = false;
413                         emailAddressField.validator = internal.defaultValidator;
414                     }
415                 }
416             }
417
418             Label {
419                 id: invalidEmailLabel
420                 visible: false
421                 width: parent.width
422                 font.pixelSize: 18
423                 color: "#FF3200"
424                 horizontalAlignment: uiHorizontalAlignment.invalidEmail || Text.AlignLeft
425                 text: uiString.invalidEmail ||
426                       "!!Invalid email address"
427             }
428         }
429
430         Item {
431             width: parent.width
432             height: 16
433         }
434
435         Label {
436             width: parent.width
437             font.pixelSize: 22
438             color: "#505050"
439             wrapMode: Text.Wrap
440             horizontalAlignment: uiHorizontalAlignment.legalText || Text.AlignLeft
441             text: uiString.legalText ||
442                       "!!Your information will be treated according to Nokia privacy policy."
443         }
444
445         Item {
446             width: parent.width
447             height: 16
448         }
449
450         Button {
451             objectName: "btn_nps_submit"
452             width: 322
453
454             anchors {
455                 horizontalCenter: parent.horizontalCenter
456             }
457
458             text: uiString.submit || "!!Submit"
459
460             onClicked: {
461                 if (internal.validateForm()) {
462                     submit()
463                 }
464             }
465         }
466
467         Item {
468             width: parent.width
469             height: 16
470         }
471     }
472 }