Merge lp:~renatofilho/ubuntu-calendar-app/majster-new-event-page into lp:ubuntu-calendar-app
- majster-new-event-page
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~renatofilho/ubuntu-calendar-app/majster-new-event-page |
Merge into: | lp:ubuntu-calendar-app |
Diff against target: |
1246 lines (+615/-452) 5 files modified
ContactChoicePopup.qml (+227/-107) KeyboardRectangle.qml (+1/-10) NewEvent.qml (+294/-273) NewEventTimePicker.qml (+90/-59) po/com.ubuntu.calendar.pot (+3/-3) |
To merge this branch: | bzr merge lp:~renatofilho/ubuntu-calendar-app/majster-new-event-page |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
system-apps-ci-bot | continuous-integration | Needs Fixing | |
Jenkins Bot | continuous-integration | Approve | |
Renato Araujo Oliveira Filho | Pending | ||
Review via email: mp+294499@code.launchpad.net |
This proposal supersedes a proposal from 2016-04-11.
Commit message
this is very first proposal for new Event Page, adding new guest is currently to be work on... but first implementation is done.
Description of the change
this is very first proposal for new Event Page, adding new guest is currently to be work on... but first implementation is done.
Renato Araujo Oliveira Filho (renatofilho) wrote : Posted in a previous version of this proposal | # |
Renato Araujo Oliveira Filho (renatofilho) wrote : Posted in a previous version of this proposal | # |
Thanks for the work. I will create a new branch based on this one to fix some small problems.
- 823. By Renato Araujo Oliveira Filho
-
Trunk merged.
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:823
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 824. By Renato Araujo Oliveira Filho
-
Fixed header license format.
- 825. By Renato Araujo Oliveira Filho
-
Remove empty lines.
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:825
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 826. By Renato Araujo Oliveira Filho
-
Update new event header and margins.
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:826
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:826
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 826. By Renato Araujo Oliveira Filho
-
Update new event header and margins.
- 825. By Renato Araujo Oliveira Filho
-
Remove empty lines.
- 824. By Renato Araujo Oliveira Filho
-
Fixed header license format.
- 823. By Renato Araujo Oliveira Filho
-
Trunk merged.
- 822. By Renato Araujo Oliveira Filho
-
Removed commented code.
Fixed code style. - 821. By Szymon Waliczek
-
First implementation of new designs for New Event page.
Preview Diff
1 | === modified file 'ContactChoicePopup.qml' | |||
2 | --- ContactChoicePopup.qml 2016-02-04 13:37:00 +0000 | |||
3 | +++ ContactChoicePopup.qml 2016-05-12 13:36:24 +0000 | |||
4 | @@ -17,138 +17,258 @@ | |||
5 | 17 | */ | 17 | */ |
6 | 18 | import QtQuick 2.4 | 18 | import QtQuick 2.4 |
7 | 19 | import Ubuntu.Components 1.3 | 19 | import Ubuntu.Components 1.3 |
8 | 20 | import Ubuntu.Components.Popups 1.3 | ||
9 | 21 | import Ubuntu.Components.ListItems 1.0 | ||
10 | 22 | import Ubuntu.Components.Themes.Ambiance 1.0 | ||
11 | 23 | import QtOrganizer 5.0 | ||
12 | 24 | import QtContacts 5.0 | 20 | import QtContacts 5.0 |
13 | 25 | 21 | ||
17 | 26 | import "Defines.js" as Defines | 22 | Item { |
15 | 27 | |||
16 | 28 | Popover { | ||
18 | 29 | id: root | 23 | id: root |
20 | 30 | objectName: "contactPopover" | 24 | |
21 | 25 | width: parent.width | ||
22 | 26 | height: mainColumn.height | ||
23 | 27 | |||
24 | 28 | property bool contactOpen: false | ||
25 | 29 | property var openContanctObject | ||
26 | 31 | 30 | ||
27 | 32 | signal contactSelected(var contact, string emailAddress); | 31 | signal contactSelected(var contact, string emailAddress); |
28 | 33 | 32 | ||
62 | 34 | Label { | 33 | onContactOpenChanged: { |
63 | 35 | id: noContact | 34 | positionDelay.start() |
64 | 36 | anchors.centerIn: parent | 35 | } |
65 | 37 | text: i18n.tr("No contact") | 36 | |
66 | 38 | visible: contactModel.contacts.length === 0 | 37 | Timer { |
67 | 39 | } | 38 | id: positionDelay |
68 | 40 | 39 | interval: 300 | |
69 | 41 | UnionFilter { | 40 | onTriggered: suggestionsFlickable.contentY = openContanctObject.y |
70 | 42 | id: filter | 41 | } |
71 | 43 | 42 | ||
72 | 44 | property string searchString: "" | 43 | states: [ |
73 | 45 | 44 | State { | |
74 | 46 | filters: [ | 45 | name: "open" |
75 | 47 | DetailFilter{ | 46 | PropertyChanges { target: contactsSuggestionItem; height: units.gu(10)} |
76 | 48 | detail: ContactDetail.Name | 47 | }, |
77 | 49 | field: Name.FirstName | 48 | State { |
78 | 50 | matchFlags: Filter.MatchContains | 49 | name: "close" |
79 | 51 | value: filter.searchString | 50 | PropertyChanges { target: contactsSuggestionItem; height: 0} |
80 | 52 | }, | 51 | } |
81 | 53 | DetailFilter{ | 52 | |
82 | 54 | detail: ContactDetail.Name | 53 | ] |
83 | 55 | field: Name.LastName | 54 | |
84 | 56 | matchFlags: Filter.MatchContains | 55 | Behavior on height { |
85 | 57 | value: filter.searchString | 56 | UbuntuNumberAnimation {} |
86 | 58 | }, | 57 | } |
87 | 59 | DetailFilter{ | 58 | |
55 | 60 | detail: ContactDetail.DisplayLabel | ||
56 | 61 | field: DisplayLabel.Label | ||
57 | 62 | matchFlags: Filter.MatchContains | ||
58 | 63 | value: filter.searchString | ||
59 | 64 | } | ||
60 | 65 | ] | ||
61 | 66 | } | ||
88 | 67 | 59 | ||
89 | 68 | ContactModel { | 60 | ContactModel { |
90 | 69 | id: contactModel | 61 | id: contactModel |
91 | 70 | manager: "galera" | 62 | manager: "galera" |
92 | 71 | filter: filter | ||
93 | 72 | autoUpdate: true | 63 | autoUpdate: true |
94 | 73 | } | 64 | } |
95 | 74 | 65 | ||
96 | 75 | Timer { | ||
97 | 76 | id: idleSearch | ||
98 | 77 | 66 | ||
99 | 78 | interval: 500 | ||
100 | 79 | repeat: false | ||
101 | 80 | onTriggered: { | ||
102 | 81 | filter.searchString = searchBox.text | ||
103 | 82 | } | ||
104 | 83 | } | ||
105 | 84 | 67 | ||
106 | 85 | Column { | 68 | Column { |
111 | 86 | anchors.top: parent.top | 69 | id: mainColumn |
112 | 87 | anchors.left: parent.left | 70 | width: parent.width |
113 | 88 | anchors.right: parent.right | 71 | spacing: units.gu(1) |
114 | 89 | anchors.margins: units.gu(1) | 72 | |
115 | 73 | Item { | ||
116 | 74 | id: guestsAdded | ||
117 | 75 | width: parent.width | ||
118 | 76 | |||
119 | 77 | } | ||
120 | 90 | 78 | ||
121 | 91 | TextField { | 79 | TextField { |
125 | 92 | id: searchBox | 80 | id: addGuestTestField |
126 | 93 | objectName: "contactPopoverInput" | 81 | objectName: "addGuestTestField" |
127 | 94 | focus: true | 82 | |
128 | 95 | width: parent.width | 83 | width: parent.width |
129 | 96 | placeholderText: i18n.tr("Search contact") | ||
130 | 97 | inputMethodHints: Qt.ImhNoPredictiveText | 84 | inputMethodHints: Qt.ImhNoPredictiveText |
140 | 98 | primaryItem: Icon { | 85 | placeholderText: i18n.tr("Guests") |
141 | 99 | height: parent.height*0.5 | 86 | |
142 | 100 | width: parent.height*0.5 | 87 | onActiveFocusChanged: { |
143 | 101 | anchors.verticalCenter: parent.verticalCenter | 88 | if(addGuestTestField.activeFocus) { |
144 | 102 | name:"find" | 89 | lol2.state = "open" |
145 | 103 | } | 90 | flickable.makeMeVisible(addGuestListItem); |
146 | 104 | onTextChanged: { | 91 | } else { |
147 | 105 | idleSearch.restart() | 92 | lol2.state = "close" |
148 | 106 | } | 93 | } |
149 | 94 | } | ||
150 | 95 | |||
151 | 107 | } | 96 | } |
152 | 108 | 97 | ||
174 | 109 | ListView { | 98 | Component { |
175 | 110 | id: contactList | 99 | id: suggestionsDelegate |
176 | 111 | objectName: "contactPopoverList" | 100 | Item { |
177 | 112 | width: parent.width | 101 | id: rootSug |
178 | 113 | model: contactModel | 102 | |
179 | 114 | height: units.gu(15) | 103 | clip: true |
180 | 115 | clip: true | 104 | width: String(contact.displayLabel.label).toLowerCase().search(addGuestTestField.text.toLowerCase()) == - 1 ? 0 : mainGrid.width |
181 | 116 | focus: false | 105 | height: mainGrid.height |
182 | 117 | delegate: Column { | 106 | |
183 | 118 | width: contactList.width | 107 | ListModel { |
184 | 119 | Repeater { | 108 | id: addressesModel |
185 | 120 | anchors { | 109 | } |
186 | 121 | left: parent.left | 110 | |
187 | 122 | right: parent.right | 111 | function getEmails() { |
188 | 123 | } | 112 | for(var i=0; contact.emails.length > i; i++) { |
189 | 124 | height: childrenRect.height | 113 | addressesModel.append({"email": contact.emails[i].emailAddress}) |
190 | 125 | 114 | } | |
191 | 126 | model: Math.max(1, contact.emails.length) | 115 | } |
192 | 127 | delegate: ListItem { | 116 | |
193 | 128 | property string emailAddress: contact.emails.length > index ? contact.emails[index].emailAddress : "" | 117 | Behavior on width { |
194 | 129 | 118 | UbuntuNumberAnimation {} | |
195 | 119 | } | ||
196 | 120 | |||
197 | 121 | Connections { | ||
198 | 122 | target: root | ||
199 | 123 | onContactOpenChanged: { | ||
200 | 124 | if(!contactOpen) { | ||
201 | 125 | emailAddressesColumn.state = "default" | ||
202 | 126 | } | ||
203 | 127 | } | ||
204 | 128 | } | ||
205 | 129 | |||
206 | 130 | Row { | ||
207 | 131 | id: mainGrid | ||
208 | 132 | |||
209 | 133 | AbstractButton { | ||
210 | 134 | id: contactNameAbstractButton | ||
211 | 135 | |||
212 | 136 | width: contactNameLabel.width + units.gu(1) | ||
213 | 137 | height: contactNameLabel.height + units.gu(1) | ||
214 | 130 | activeFocusOnPress: false | 138 | activeFocusOnPress: false |
223 | 131 | opacity: emailAddress.length > 0 ? 1.0 : 0.3 | 139 | enabled: contact.emails.length > 0 |
224 | 132 | width: contactList.width | 140 | |
225 | 133 | objectName: "contactPopoverList%1".arg(index) | 141 | Rectangle { |
218 | 134 | ListItemLayout { | ||
219 | 135 | title.text: contact.displayLabel.label | ||
220 | 136 | subtitle.text: emailAddress | ||
221 | 137 | } | ||
222 | 138 | MouseArea { | ||
226 | 139 | anchors.fill: parent | 142 | anchors.fill: parent |
236 | 140 | onClicked: { | 143 | color: (parent.pressed || (emailAddressesColumn.state === "open")) ? UbuntuColors.lightGrey : "transparent" |
237 | 141 | if (emailAddress.length > 0) { | 144 | } |
238 | 142 | root.contactSelected(contact, emailAddress); | 145 | |
239 | 143 | PopupUtils.close(root) | 146 | Label { |
240 | 144 | } | 147 | id: contactNameLabel |
241 | 145 | } | 148 | text: emailAddressesColumn.state === "open" ? contact.displayLabel.label+":" : contact.displayLabel.label |
242 | 146 | } | 149 | anchors.centerIn: parent |
243 | 147 | } | 150 | color: contact.emails.length > 0 ? "black" : UbuntuColors.lightGrey |
244 | 148 | } | 151 | font.italic: contact.emails.length > 0 ? false : true |
245 | 152 | fontSize: "medium" | ||
246 | 153 | } | ||
247 | 154 | onClicked: { | ||
248 | 155 | if(contact.emails.length > 1) { | ||
249 | 156 | if(contactOpen) { | ||
250 | 157 | contactOpen = false | ||
251 | 158 | } else { | ||
252 | 159 | emailAddressesColumn.openClose() | ||
253 | 160 | openContanctObject = rootSug | ||
254 | 161 | } | ||
255 | 162 | |||
256 | 163 | } else { | ||
257 | 164 | root.contactSelected(contact, contact.email.emailAddress); | ||
258 | 165 | } | ||
259 | 166 | } | ||
260 | 167 | } | ||
261 | 168 | Column { | ||
262 | 169 | id: emailAddressesColumn | ||
263 | 170 | |||
264 | 171 | clip: true | ||
265 | 172 | state: "default" | ||
266 | 173 | |||
267 | 174 | function openClose() { | ||
268 | 175 | if(emailAddressesColumn.state === "open") { | ||
269 | 176 | emailAddressesColumn.state = "default" | ||
270 | 177 | } else { | ||
271 | 178 | emailAddressesColumn.state = "open" | ||
272 | 179 | } | ||
273 | 180 | } | ||
274 | 181 | |||
275 | 182 | states: [ | ||
276 | 183 | State { | ||
277 | 184 | name: "default" | ||
278 | 185 | PropertyChanges { target: emailAddressesColumn; width: 0 } | ||
279 | 186 | }, | ||
280 | 187 | State { | ||
281 | 188 | name: "open" | ||
282 | 189 | PropertyChanges { target: emailAddressesColumn; width: mainColumn.width - contactNameAbstractButton.width } | ||
283 | 190 | } | ||
284 | 191 | ] | ||
285 | 192 | |||
286 | 193 | onStateChanged: { | ||
287 | 194 | if(state === "open") { | ||
288 | 195 | rootSug.getEmails() | ||
289 | 196 | contactOpen = true | ||
290 | 197 | } else { | ||
291 | 198 | addressesModel.clear() | ||
292 | 199 | } | ||
293 | 200 | } | ||
294 | 201 | |||
295 | 202 | Repeater { | ||
296 | 203 | model: addressesModel | ||
297 | 204 | delegate: AbstractButton { | ||
298 | 205 | width: contactEmailLabel.width + units.gu(2) | ||
299 | 206 | height: contactEmailLabel.height + units.gu(1) | ||
300 | 207 | activeFocusOnPress: false | ||
301 | 208 | |||
302 | 209 | Rectangle { | ||
303 | 210 | anchors.fill: parent | ||
304 | 211 | color: parent.pressed ? UbuntuColors.lightGrey : "transparent" | ||
305 | 212 | } | ||
306 | 213 | |||
307 | 214 | Label { | ||
308 | 215 | id: contactEmailLabel | ||
309 | 216 | anchors.verticalCenter: parent.verticalCenter | ||
310 | 217 | anchors.left: parent.left | ||
311 | 218 | anchors.leftMargin: units.gu(1) | ||
312 | 219 | text: email | ||
313 | 220 | color: contact.emails.length > 0 ? "black" : UbuntuColors.lightGrey | ||
314 | 221 | font.italic: contact.emails.length > 0 ? false : true | ||
315 | 222 | fontSize: "medium" | ||
316 | 223 | elide: Text.ElideRight | ||
317 | 224 | } | ||
318 | 225 | |||
319 | 226 | onClicked: { | ||
320 | 227 | root.contactSelected(contact, email); | ||
321 | 228 | emailAddressesColumn.state = "default" | ||
322 | 229 | } | ||
323 | 230 | } | ||
324 | 231 | } | ||
325 | 232 | } | ||
326 | 233 | } | ||
327 | 234 | } | ||
328 | 235 | } | ||
329 | 236 | |||
330 | 237 | Item { | ||
331 | 238 | id: contactsSuggestionItem | ||
332 | 239 | width: parent.width | ||
333 | 240 | clip: true | ||
334 | 241 | |||
335 | 242 | Flickable { | ||
336 | 243 | id: suggestionsFlickable | ||
337 | 244 | width: parent.width - units.gu(0) | ||
338 | 245 | height: parent.height - units.gu(1) | ||
339 | 246 | anchors.top: parent.top | ||
340 | 247 | anchors.topMargin: units.gu(1) | ||
341 | 248 | contentHeight: suggestionsListView.height + units.gu(1) | ||
342 | 249 | |||
343 | 250 | // animation on flickable contentY change | ||
344 | 251 | Behavior on contentY { | ||
345 | 252 | UbuntuNumberAnimation {} | ||
346 | 253 | } | ||
347 | 254 | |||
348 | 255 | onFlickStarted: contactOpen = false | ||
349 | 256 | Flow { | ||
350 | 257 | id: suggestionsListView | ||
351 | 258 | width: parent.width | ||
352 | 259 | spacing: units.gu(1.5) | ||
353 | 260 | |||
354 | 261 | Repeater { | ||
355 | 262 | model: contactModel | ||
356 | 263 | delegate: suggestionsDelegate | ||
357 | 264 | } | ||
358 | 265 | } | ||
359 | 266 | } | ||
360 | 267 | |||
361 | 268 | Scrollbar { | ||
362 | 269 | flickableItem: suggestionsFlickable | ||
363 | 270 | align: Qt.AlignTrailing | ||
364 | 149 | } | 271 | } |
365 | 150 | } | 272 | } |
366 | 151 | } | 273 | } |
367 | 152 | |||
368 | 153 | Component.onCompleted: searchBox.forceActiveFocus() | ||
369 | 154 | } | 274 | } |
370 | 155 | 275 | ||
371 | === modified file 'KeyboardRectangle.qml' | |||
372 | --- KeyboardRectangle.qml 2016-02-03 19:53:46 +0000 | |||
373 | +++ KeyboardRectangle.qml 2016-05-12 13:36:24 +0000 | |||
374 | @@ -26,16 +26,7 @@ | |||
375 | 26 | anchors.bottom: parent.bottom | 26 | anchors.bottom: parent.bottom |
376 | 27 | height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0 | 27 | height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0 |
377 | 28 | 28 | ||
388 | 29 | states: [ | 29 | property bool isVisible: Qt.inputMethod.visible |
379 | 30 | State { | ||
380 | 31 | name: "hidden" | ||
381 | 32 | when: keyboardRect.height == 0 | ||
382 | 33 | }, | ||
383 | 34 | State { | ||
384 | 35 | name: "shown" | ||
385 | 36 | when: keyboardRect.height == Qt.inputMethod.keyboardRectangle.height | ||
386 | 37 | } | ||
387 | 38 | ] | ||
389 | 39 | 30 | ||
390 | 40 | function recursiveFindFocusedItem(parent) { | 31 | function recursiveFindFocusedItem(parent) { |
391 | 41 | if (parent.activeFocus) { | 32 | if (parent.activeFocus) { |
392 | 42 | 33 | ||
393 | === modified file 'NewEvent.qml' | |||
394 | --- NewEvent.qml 2016-04-06 18:46:29 +0000 | |||
395 | +++ NewEvent.qml 2016-05-12 13:36:24 +0000 | |||
396 | @@ -319,6 +319,7 @@ | |||
397 | 319 | } | 319 | } |
398 | 320 | 320 | ||
399 | 321 | Keys.onEscapePressed: root.cancel() | 321 | Keys.onEscapePressed: root.cancel() |
400 | 322 | |||
401 | 322 | header: PageHeader { | 323 | header: PageHeader { |
402 | 323 | id: pageHeader | 324 | id: pageHeader |
403 | 324 | 325 | ||
404 | @@ -326,37 +327,35 @@ | |||
405 | 326 | title: isEdit ? i18n.tr("Edit Event"):i18n.tr("New Event") | 327 | title: isEdit ? i18n.tr("Edit Event"):i18n.tr("New Event") |
406 | 327 | leadingActionBar.actions: Action { | 328 | leadingActionBar.actions: Action { |
407 | 328 | id: backAction | 329 | id: backAction |
408 | 329 | |||
409 | 330 | name: "cancel" | 330 | name: "cancel" |
410 | 331 | text: i18n.tr("Cancel") | 331 | text: i18n.tr("Cancel") |
411 | 332 | iconName: isEdit ? "back" : "down" | 332 | iconName: isEdit ? "back" : "down" |
412 | 333 | onTriggered: root.cancel() | 333 | onTriggered: root.cancel() |
413 | 334 | } | 334 | } |
414 | 335 | 335 | ||
429 | 336 | trailingActionBar.actions: [ | 336 | trailingActionBar { |
430 | 337 | Action { | 337 | actions: [ |
431 | 338 | text: i18n.tr("Delete"); | 338 | Action { |
432 | 339 | objectName: "delete" | 339 | text: i18n.tr("Save") |
433 | 340 | iconName: "delete" | 340 | iconName: "tick" |
434 | 341 | visible : isEdit | 341 | onTriggered: saveToQtPim(); |
435 | 342 | onTriggered: { | 342 | }, |
436 | 343 | var dialog = PopupUtils.open(Qt.resolvedUrl("DeleteConfirmationDialog.qml"),root,{"event": event}); | 343 | Action { |
437 | 344 | dialog.deleteEvent.connect( function(eventId){ | 344 | text: i18n.tr("Delete") |
438 | 345 | model.removeItem(eventId); | 345 | iconName: "delete" |
439 | 346 | if (pageStack) | 346 | visible : isEdit |
440 | 347 | pageStack.pop(); | 347 | onTriggered: { |
441 | 348 | root.eventDeleted(eventId); | 348 | var dialog = PopupUtils.open(Qt.resolvedUrl("DeleteConfirmationDialog.qml"),root,{"event": event}); |
442 | 349 | }); | 349 | dialog.deleteEvent.connect( function(eventId){ |
443 | 350 | model.removeItem(eventId); | ||
444 | 351 | if (pageStack) | ||
445 | 352 | pageStack.pop(); | ||
446 | 353 | root.eventDeleted(eventId); | ||
447 | 354 | }); | ||
448 | 355 | } | ||
449 | 350 | } | 356 | } |
459 | 351 | }, | 357 | ] |
460 | 352 | Action { | 358 | } |
452 | 353 | iconName: "ok" | ||
453 | 354 | objectName: "save" | ||
454 | 355 | text: i18n.tr("Save") | ||
455 | 356 | enabled: !!titleEdit.text.trim() | ||
456 | 357 | onTriggered: saveToQtPim(); | ||
457 | 358 | } | ||
458 | 359 | ] | ||
461 | 360 | } | 359 | } |
462 | 361 | 360 | ||
463 | 362 | Component{ | 361 | Component{ |
464 | @@ -399,7 +398,7 @@ | |||
465 | 399 | // if it is not, try to scroll and make it visible | 398 | // if it is not, try to scroll and make it visible |
466 | 400 | var targetY = position.y + item.height - flickable.height | 399 | var targetY = position.y + item.height - flickable.height |
467 | 401 | if (targetY >= 0 && position.y) { | 400 | if (targetY >= 0 && position.y) { |
469 | 402 | flickable.contentY = targetY; | 401 | flickable.contentY = targetY + units.gu(1); |
470 | 403 | } else if (position.y < flickable.contentY) { | 402 | } else if (position.y < flickable.contentY) { |
471 | 404 | // if it is hidden at the top, also show it | 403 | // if it is hidden at the top, also show it |
472 | 405 | flickable.contentY = position.y; | 404 | flickable.contentY = position.y; |
473 | @@ -407,6 +406,11 @@ | |||
474 | 407 | flickable.returnToBounds() | 406 | flickable.returnToBounds() |
475 | 408 | } | 407 | } |
476 | 409 | 408 | ||
477 | 409 | // animation on flickable contentY change | ||
478 | 410 | Behavior on contentY { | ||
479 | 411 | UbuntuNumberAnimation {} | ||
480 | 412 | } | ||
481 | 413 | |||
482 | 410 | flickableDirection: Flickable.VerticalFlick | 414 | flickableDirection: Flickable.VerticalFlick |
483 | 411 | anchors{ | 415 | anchors{ |
484 | 412 | left: parent.left | 416 | left: parent.left |
485 | @@ -425,9 +429,8 @@ | |||
486 | 425 | 429 | ||
487 | 426 | NewEventTimePicker{ | 430 | NewEventTimePicker{ |
488 | 427 | id: startDateTimeInput | 431 | id: startDateTimeInput |
492 | 428 | objectName: "startDateTimeInput" | 432 | //TRANSLATORS: this referes to date. eg: From: Wendsday, 9 March 2016 |
493 | 429 | 433 | headerText: i18n.tr("From") | |
491 | 430 | header: i18n.tr("From") | ||
494 | 431 | showTimePicker: !allDayEventCheckbox.checked | 434 | showTimePicker: !allDayEventCheckbox.checked |
495 | 432 | anchors { | 435 | anchors { |
496 | 433 | left: parent.left | 436 | left: parent.left |
497 | @@ -435,255 +438,275 @@ | |||
498 | 435 | } | 438 | } |
499 | 436 | onDateTimeChanged: { | 439 | onDateTimeChanged: { |
500 | 437 | startDate = dateTime; | 440 | startDate = dateTime; |
501 | 438 | endDateTimeInput.dateTime = new Date(startDate.getTime() + root.eventSize) | ||
502 | 439 | } | 441 | } |
503 | 440 | } | 442 | } |
504 | 441 | 443 | ||
505 | 442 | NewEventTimePicker{ | 444 | NewEventTimePicker{ |
506 | 443 | id: endDateTimeInput | 445 | id: endDateTimeInput |
510 | 444 | objectName: "endDateTimeInput" | 446 | //TRANSLATORS: this referes to date. eg: To: Wendsday, 9 March 2016 |
511 | 445 | 447 | headerText: i18n.tr("To") | |
509 | 446 | header: i18n.tr("To") | ||
512 | 447 | showTimePicker: !allDayEventCheckbox.checked | 448 | showTimePicker: !allDayEventCheckbox.checked |
513 | 448 | anchors { | 449 | anchors { |
514 | 449 | left: parent.left | 450 | left: parent.left |
515 | 450 | right: parent.right | 451 | right: parent.right |
516 | 451 | } | 452 | } |
517 | 452 | onDateTimeChanged: { | 453 | onDateTimeChanged: { |
518 | 453 | if (dateTime.getTime() < startDate.getTime()) { | ||
519 | 454 | root.eventSize = root.allDay ? 0 : root.millisecsInAnHour | ||
520 | 455 | dateTime = new Date(startDate.getTime() + root.eventSize) | ||
521 | 456 | return | ||
522 | 457 | } | ||
523 | 458 | |||
524 | 459 | endDate = dateTime; | 454 | endDate = dateTime; |
741 | 460 | if (allDay) | 455 | } |
742 | 461 | root.eventSize = endDate.midnight().getTime() - startDate.midnight().getTime() | 456 | } |
743 | 462 | else | 457 | |
744 | 463 | root.eventSize = endDate.getTime() - startDate.getTime() | 458 | // All day event ListItem with Switch |
745 | 464 | } | 459 | ListItem { |
746 | 465 | } | 460 | width: parent.width |
747 | 466 | 461 | ||
748 | 467 | ListItems.Standard { | 462 | ListItemLayout { |
749 | 468 | anchors { | 463 | title.text: i18n.tr("All day event") |
750 | 469 | left: parent.left | 464 | Switch { |
751 | 470 | right: parent.right | 465 | id: allDayEventCheckbox |
752 | 471 | } | 466 | checked: false |
753 | 472 | 467 | SlotsLayout.position: SlotsLayout.Trailing; | |
754 | 473 | text: i18n.tr("All day event") | 468 | } |
755 | 474 | __foregroundColor: Theme.palette.normal.baseText | 469 | } |
756 | 475 | showDivider: false | 470 | onClicked: { |
757 | 476 | control: CheckBox { | 471 | allDayEventCheckbox.checked = !allDayEventCheckbox.checked |
758 | 477 | objectName: "allDayEventCheckbox" | 472 | } |
759 | 478 | id: allDayEventCheckbox | 473 | |
760 | 479 | checked: false | 474 | } |
761 | 480 | onCheckedChanged: { | 475 | |
762 | 481 | if (checked) | 476 | // ListItem which holds "Event details" label + TextField + TextArea + TextField |
763 | 482 | root.eventSize = Math.max(endDate.midnight().getTime() - startDate.midnight().getTime(), 0) | 477 | ListItem { |
764 | 483 | else | 478 | height: eventDetailsColumn.height + eventDetailsColumn.spacing * 2 |
765 | 484 | root.eventSize = Math.max(endDate.getTime() - startDate.getTime(), root.millisecsInAnHour) | 479 | |
766 | 485 | } | 480 | Column { |
767 | 486 | } | 481 | id: eventDetailsColumn |
768 | 487 | } | 482 | spacing: units.gu(2) |
769 | 488 | 483 | anchors { | |
770 | 489 | ListItems.ThinDivider {} | 484 | left: parent.left |
771 | 490 | 485 | right: parent.right | |
772 | 491 | Column { | 486 | top: parent.top |
773 | 492 | width: parent.width | 487 | margins: units.gu(2) |
774 | 493 | spacing: units.gu(1) | 488 | } |
775 | 494 | 489 | ||
776 | 495 | ListItems.Header{ | 490 | Label { |
777 | 496 | text: i18n.tr("Event Details") | 491 | anchors { |
778 | 497 | __foregroundColor: Theme.palette.normal.baseText | 492 | left: parent.left |
779 | 498 | } | 493 | right: parent.right |
780 | 499 | 494 | } | |
781 | 500 | TextField { | 495 | |
782 | 501 | id: titleEdit | 496 | text: i18n.tr("Event details") |
783 | 502 | objectName: "newEventName" | 497 | elide: Text.ElideRight |
784 | 503 | 498 | } | |
785 | 504 | anchors { | 499 | |
786 | 505 | left: parent.left | 500 | TextField { |
787 | 506 | right: parent.right | 501 | id: titleEdit |
788 | 507 | margins: units.gu(2) | 502 | objectName: "newEventName" |
789 | 508 | } | 503 | |
790 | 509 | 504 | anchors { | |
791 | 510 | placeholderText: i18n.tr("Event Name") | 505 | left: parent.left |
792 | 511 | onFocusChanged: { | 506 | right: parent.right |
793 | 512 | if(titleEdit.focus) { | 507 | } |
794 | 513 | flickable.makeMeVisible(titleEdit); | 508 | inputMethodHints: Qt.ImhNoPredictiveText |
795 | 514 | } | 509 | placeholderText: i18n.tr("Event Name") |
796 | 515 | } | 510 | |
797 | 516 | } | 511 | onActiveFocusChanged: { |
798 | 517 | 512 | if(titleEdit.activeFocus) { | |
799 | 518 | TextArea{ | 513 | flickable.makeMeVisible(titleEdit); |
800 | 519 | id: messageEdit | 514 | } |
801 | 520 | objectName: "eventDescriptionInput" | 515 | } |
802 | 521 | 516 | } | |
803 | 522 | anchors { | 517 | |
804 | 523 | left: parent.left | 518 | TextArea{ |
805 | 524 | right: parent.right | 519 | id: messageEdit |
806 | 525 | margins: units.gu(2) | 520 | objectName: "eventDescriptionInput" |
807 | 526 | } | 521 | |
808 | 527 | 522 | anchors { | |
809 | 528 | placeholderText: i18n.tr("Description") | 523 | left: parent.left |
810 | 529 | onFocusChanged: { | 524 | right: parent.right |
811 | 530 | if(messageEdit.focus) { | 525 | } |
812 | 531 | flickable.makeMeVisible(messageEdit); | 526 | placeholderText: i18n.tr("Description") |
813 | 532 | } | 527 | |
814 | 533 | } | 528 | onActiveFocusChanged: { |
815 | 534 | } | 529 | if(messageEdit.activeFocus) { |
816 | 535 | 530 | flickable.makeMeVisible(messageEdit); | |
817 | 536 | TextField { | 531 | } |
818 | 537 | id: locationEdit | 532 | } |
819 | 538 | objectName: "eventLocationInput" | 533 | } |
820 | 539 | 534 | ||
821 | 540 | anchors { | 535 | TextField { |
822 | 541 | left: parent.left | 536 | id: locationEdit |
823 | 542 | right: parent.right | 537 | objectName: "eventLocationInput" |
824 | 543 | margins: units.gu(2) | 538 | |
825 | 544 | } | 539 | anchors { |
826 | 545 | 540 | left: parent.left | |
827 | 546 | inputMethodHints: Qt.ImhNoPredictiveText | 541 | right: parent.right |
828 | 547 | placeholderText: i18n.tr("Location") | 542 | } |
829 | 548 | 543 | inputMethodHints: Qt.ImhNoPredictiveText | |
830 | 549 | onFocusChanged: { | 544 | placeholderText: i18n.tr("Location") |
831 | 550 | if(locationEdit.focus) { | 545 | |
832 | 551 | flickable.makeMeVisible(locationEdit); | 546 | onActiveFocusChanged: { |
833 | 552 | } | 547 | if(locationEdit.activeFocus) { |
834 | 553 | } | 548 | flickable.makeMeVisible(locationEdit); |
835 | 554 | } | 549 | } |
836 | 555 | } | 550 | } |
837 | 556 | 551 | } | |
838 | 557 | Column { | 552 | } |
839 | 558 | width: parent.width | 553 | } |
840 | 559 | spacing: units.gu(1) | 554 | |
841 | 560 | 555 | // ListItem to hold calendars selector | |
842 | 561 | ListItems.Header { | 556 | ListItem { |
843 | 562 | text: i18n.tr("Calendar") | 557 | height: chooseCalendarColumn.height + (eventDetailsColumn.anchors.topMargin*2) |
844 | 563 | __foregroundColor: Theme.palette.normal.baseText | 558 | |
845 | 564 | } | 559 | Column { |
846 | 565 | 560 | id: chooseCalendarColumn | |
847 | 566 | OptionSelector{ | 561 | spacing: units.gu(2) |
848 | 567 | id: calendarsOption | 562 | anchors { |
849 | 568 | objectName: "calendarsOption" | 563 | left: parent.left |
850 | 569 | 564 | right: parent.right | |
851 | 570 | anchors { | 565 | top: parent.top |
852 | 571 | left: parent.left | 566 | margins: units.gu(2) |
853 | 572 | right: parent.right | 567 | } |
854 | 573 | margins: units.gu(2) | 568 | |
855 | 574 | } | 569 | Label { |
856 | 575 | 570 | width: parent.width | |
857 | 576 | containerHeight: itemHeight * 4 | 571 | anchors { |
858 | 577 | model: root.model ? root.model.getWritableAndSelectedCollections() : [] | 572 | left: parent.left |
859 | 578 | 573 | right: parent.right | |
860 | 579 | delegate: OptionSelectorDelegate{ | 574 | } |
861 | 580 | text: modelData.name | 575 | text: i18n.tr("Choose calendar") |
862 | 581 | 576 | elide: Text.ElideRight | |
863 | 582 | UbuntuShape{ | 577 | } |
864 | 583 | id: calColor | 578 | |
865 | 584 | width: height | 579 | ListItems.ItemSelector { |
866 | 585 | height: parent.height - units.gu(2) | 580 | id: calendarsOption |
867 | 586 | color: modelData.color | 581 | model: root.model.getWritableCollections(); |
868 | 587 | anchors { | 582 | delegate: OptionSelectorDelegate { text: modelData.name } |
869 | 588 | right: parent.right | 583 | } |
870 | 589 | rightMargin: units.gu(4) | 584 | |
871 | 590 | verticalCenter: parent.verticalCenter | 585 | } |
872 | 591 | } | 586 | } |
873 | 592 | } | 587 | |
874 | 593 | } | 588 | |
875 | 594 | onExpandedChanged: Qt.inputMethod.hide(); | 589 | // add guest field |
876 | 595 | } | 590 | ListItem { |
877 | 596 | } | 591 | id: addGuestListItem |
878 | 597 | 592 | height: addGusestColumn.height + (addGusestColumn.anchors.margins*2) | |
879 | 598 | Column { | 593 | |
880 | 599 | width: parent.width | 594 | Column { |
881 | 600 | spacing: units.gu(1) | 595 | id: addGusestColumn |
882 | 601 | 596 | anchors { | |
883 | 602 | ListItems.Header { | 597 | left: parent.left |
884 | 603 | text: i18n.tr("Guests") | 598 | right: parent.right |
885 | 604 | __foregroundColor: Theme.palette.normal.baseText | 599 | top: parent.top |
886 | 605 | } | 600 | margins: units.gu(2) |
887 | 606 | 601 | } | |
888 | 607 | Button{ | 602 | |
889 | 608 | id: addGuestButton | 603 | Behavior on height { |
890 | 609 | objectName: "addGuestButton" | 604 | UbuntuNumberAnimation {} |
891 | 610 | 605 | } | |
892 | 611 | property var contactsPopup: null | 606 | |
893 | 612 | 607 | Label { | |
894 | 613 | text: i18n.tr("Add Guest") | 608 | width: parent.width |
895 | 614 | anchors { | 609 | text: i18n.tr("Event details") |
896 | 615 | left: parent.left | 610 | elide: Text.ElideRight |
897 | 616 | right: parent.right | 611 | } |
898 | 617 | margins: units.gu(2) | 612 | |
899 | 618 | } | 613 | Item { |
900 | 619 | 614 | width: parent.width | |
901 | 620 | onClicked: { | 615 | height: units.gu(1) |
902 | 621 | if (contactsPopup) | 616 | } |
903 | 622 | return | 617 | |
904 | 623 | 618 | ListModel{ | |
905 | 624 | flickable.makeMeVisible(addGuestButton) | 619 | id: contactModel |
906 | 625 | contactsPopup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), addGuestButton); | 620 | } |
907 | 626 | contactsPopup.contactSelected.connect( function(contact, emailAddress) { | 621 | |
908 | 627 | if(!internal.isContactAlreadyAdded(contact, emailAddress) ) { | 622 | Component { |
909 | 628 | var t = internal.contactToAttendee(contact, emailAddress); | 623 | id: addedGusestDelegate |
910 | 629 | contactModel.append({"contact": t}); | 624 | Item { |
911 | 630 | } | 625 | width: delegateRow.width + units.gu(1) |
912 | 631 | 626 | height: units.gu(3) | |
913 | 632 | }); | 627 | |
914 | 633 | contactsPopup.Component.onDestruction.connect( function() { | 628 | Rectangle { |
915 | 634 | addGuestButton.contactsPopup = null | 629 | anchors.fill: parent |
916 | 635 | }) | 630 | color: delegateMouseArea.pressed ? UbuntuColors.lightGrey : "transparent" |
917 | 636 | } | 631 | } |
918 | 637 | } | 632 | |
919 | 638 | 633 | Row { | |
920 | 639 | UbuntuShape { | 634 | id: delegateRow |
921 | 640 | anchors { | 635 | height: parent.height |
922 | 641 | left: parent.left | 636 | spacing: units.gu(0.5) |
923 | 642 | right: parent.right | 637 | anchors.horizontalCenter: parent.horizontalCenter |
924 | 643 | margins: units.gu(2) | 638 | |
925 | 644 | } | 639 | UbuntuShape { |
926 | 645 | 640 | id: rec | |
927 | 646 | height: contactList.height | 641 | height: parent.height - units.gu(0.5) |
928 | 647 | 642 | anchors.verticalCenter: parent.verticalCenter | |
929 | 648 | Column{ | 643 | width: height |
930 | 649 | id: contactList | 644 | color: "green" |
931 | 650 | objectName: "guestList" | 645 | Text { |
932 | 651 | 646 | anchors.centerIn: parent | |
933 | 652 | spacing: units.gu(1) | 647 | text: contact.name.charAt(0).toUpperCase() |
934 | 653 | width: parent.width | 648 | font.bold: true |
935 | 654 | clip: true | 649 | color: "white" |
720 | 655 | |||
721 | 656 | ListModel{ | ||
722 | 657 | id: contactModel | ||
723 | 658 | } | ||
724 | 659 | |||
725 | 660 | Repeater{ | ||
726 | 661 | model: contactModel | ||
727 | 662 | delegate: ListItem { | ||
728 | 663 | objectName: "eventGuest%1".arg(index) | ||
729 | 664 | |||
730 | 665 | ListItemLayout { | ||
731 | 666 | title.text: contact.name | ||
732 | 667 | subtitle.text: contact.emailAddress | ||
733 | 668 | } | ||
734 | 669 | |||
735 | 670 | leadingActions: ListItemActions { | ||
736 | 671 | actions: Action { | ||
737 | 672 | iconName: "delete" | ||
738 | 673 | onTriggered: { | ||
739 | 674 | contactModel.remove(index) | ||
740 | 675 | } | ||
936 | 676 | } | 650 | } |
937 | 677 | } | 651 | } |
947 | 678 | } | 652 | Label { |
948 | 679 | } | 653 | id: lab |
949 | 680 | } | 654 | anchors.verticalCenter: parent.verticalCenter |
950 | 681 | } | 655 | text: contact.name |
951 | 682 | 656 | } | |
952 | 683 | ListItems.ThinDivider { | 657 | } |
953 | 684 | visible: (event != undefined) && (event.itemType === Type.Event) | 658 | |
954 | 685 | } | 659 | MouseArea { |
955 | 686 | 660 | id: delegateMouseArea | |
956 | 661 | anchors.fill: parent | ||
957 | 662 | onClicked: contactModel.remove(index) | ||
958 | 663 | |||
959 | 664 | } | ||
960 | 665 | } | ||
961 | 666 | } | ||
962 | 667 | |||
963 | 668 | // Add guest section (this is now in development) | ||
964 | 669 | Item { | ||
965 | 670 | width: parent.width | ||
966 | 671 | height: suggestionsListView.height + units.gu(0.5) | ||
967 | 672 | Behavior on height { | ||
968 | 673 | UbuntuNumberAnimation {} | ||
969 | 674 | } | ||
970 | 675 | |||
971 | 676 | Flow { | ||
972 | 677 | id: suggestionsListView | ||
973 | 678 | width: parent.width | ||
974 | 679 | spacing: units.gu(1.5) | ||
975 | 680 | move: Transition { | ||
976 | 681 | NumberAnimation { | ||
977 | 682 | properties: "x,y" | ||
978 | 683 | } | ||
979 | 684 | } | ||
980 | 685 | add: Transition { | ||
981 | 686 | NumberAnimation { | ||
982 | 687 | properties: "x,y" | ||
983 | 688 | } | ||
984 | 689 | } | ||
985 | 690 | |||
986 | 691 | Repeater { | ||
987 | 692 | model: contactModel | ||
988 | 693 | delegate: addedGusestDelegate | ||
989 | 694 | } | ||
990 | 695 | } | ||
991 | 696 | } | ||
992 | 697 | |||
993 | 698 | ContactChoicePopup { | ||
994 | 699 | id: lol2 | ||
995 | 700 | width: parent.width | ||
996 | 701 | |||
997 | 702 | onContactSelected: { | ||
998 | 703 | if(!internal.isContactAlreadyAdded(contact, emailAddress) ) { | ||
999 | 704 | var t = internal.contactToAttendee(contact, emailAddress); | ||
1000 | 705 | contactModel.append({"contact": t}); | ||
1001 | 706 | } | ||
1002 | 707 | } | ||
1003 | 708 | } | ||
1004 | 709 | } | ||
1005 | 687 | } | 710 | } |
1006 | 688 | 711 | ||
1007 | 689 | ListItem { | 712 | ListItem { |
1008 | @@ -768,6 +791,12 @@ | |||
1009 | 768 | } | 791 | } |
1010 | 769 | } | 792 | } |
1011 | 770 | 793 | ||
1012 | 794 | // Scrollbar | ||
1013 | 795 | Scrollbar{ | ||
1014 | 796 | flickableItem: flickable | ||
1015 | 797 | align: Qt.AlignTrailing | ||
1016 | 798 | } | ||
1017 | 799 | |||
1018 | 771 | // used to keep the field visible when the keyboard appear or dismiss | 800 | // used to keep the field visible when the keyboard appear or dismiss |
1019 | 772 | KeyboardRectangle { | 801 | KeyboardRectangle { |
1020 | 773 | id: keyboardRectangle | 802 | id: keyboardRectangle |
1021 | @@ -783,14 +812,7 @@ | |||
1022 | 783 | PauseAnimation { duration: 200 } | 812 | PauseAnimation { duration: 200 } |
1023 | 784 | ScriptAction { | 813 | ScriptAction { |
1024 | 785 | script: { | 814 | script: { |
1033 | 786 | if (addGuestButton.contactsPopup) { | 815 | flickable.makeMeVisible(flickable.activeItem) |
1026 | 787 | // WORKAROUND: causes the popover to follow the buttom position when keyboard appears | ||
1027 | 788 | flickable.makeMeVisible(addGuestButton) | ||
1028 | 789 | addGuestButton.contactsPopup.caller = null | ||
1029 | 790 | addGuestButton.contactsPopup.caller = addGuestButton | ||
1030 | 791 | } else { | ||
1031 | 792 | flickable.makeMeVisible(flickable.activeItem) | ||
1032 | 793 | } | ||
1034 | 794 | } | 816 | } |
1035 | 795 | } | 817 | } |
1036 | 796 | } | 818 | } |
1037 | @@ -827,8 +849,7 @@ | |||
1038 | 827 | return false; | 849 | return false; |
1039 | 828 | } | 850 | } |
1040 | 829 | 851 | ||
1043 | 830 | function attendeeFromData(id, name, emailAddress) | 852 | function attendeeFromData(id, name, emailAddress) { |
1042 | 831 | { | ||
1044 | 832 | var attendee = Qt.createQmlObject("import QtOrganizer 5.0; EventAttendee{}", internal, "NewEvent.qml"); | 853 | var attendee = Qt.createQmlObject("import QtOrganizer 5.0; EventAttendee{}", internal, "NewEvent.qml"); |
1045 | 833 | attendee.name = name | 854 | attendee.name = name |
1046 | 834 | attendee.emailAddress = emailAddress | 855 | attendee.emailAddress = emailAddress |
1047 | 835 | 856 | ||
1048 | === modified file 'NewEventTimePicker.qml' | |||
1049 | --- NewEventTimePicker.qml 2016-03-22 20:09:08 +0000 | |||
1050 | +++ NewEventTimePicker.qml 2016-05-12 13:36:24 +0000 | |||
1051 | @@ -1,76 +1,107 @@ | |||
1052 | 1 | import QtQuick 2.4 | 1 | import QtQuick 2.4 |
1054 | 2 | import Ubuntu.Components.ListItems 1.0 as ListItem | 2 | import Ubuntu.Components 1.3 |
1055 | 3 | import Ubuntu.Components.Themes.Ambiance 1.0 | 3 | import Ubuntu.Components.Themes.Ambiance 1.0 |
1057 | 4 | import Ubuntu.Components.Pickers 1.0 | 4 | import Ubuntu.Components.Pickers 1.3 |
1058 | 5 | 5 | ||
1060 | 6 | Column { | 6 | ListItem { |
1061 | 7 | id: dateTimeInput | 7 | id: dateTimeInput |
1066 | 8 | property alias header: listHeader.text | 8 | |
1067 | 9 | 9 | property string headerText //header label ("From" or "To") | |
1068 | 10 | property date dateTime; | 10 | property date dateTime //keep date from DatePicker |
1069 | 11 | property bool showTimePicker; | 11 | property bool showTimePicker //if true then user is able to set time on event |
1070 | 12 | |||
1071 | 13 | // when new date set in DatePicker then this will be run. | ||
1072 | 14 | onDateTimeChanged: { | ||
1073 | 15 | layout.summary.text = dateTime.toLocaleDateString() // set date | ||
1074 | 16 | secondLabel.text = Qt.formatTime(dateTime, "hh:mm AP").replace(/\./g, "") // set time | ||
1075 | 17 | } | ||
1076 | 12 | 18 | ||
1077 | 13 | function clearFocus() { | 19 | function clearFocus() { |
1080 | 14 | dateInput.focus = false; | 20 | dateBG.focus = false; |
1081 | 15 | timeInput.focus = false; | 21 | timeBG.focus = false; |
1082 | 16 | } | 22 | } |
1083 | 17 | 23 | ||
1084 | 24 | // function to open date/time picker | ||
1085 | 18 | function openDatePicker (element, caller, callerProperty, mode) { | 25 | function openDatePicker (element, caller, callerProperty, mode) { |
1086 | 19 | element.highlighted = true; | 26 | element.highlighted = true; |
1087 | 20 | var picker = PickerPanel.openDatePicker(caller, callerProperty, mode); | 27 | var picker = PickerPanel.openDatePicker(caller, callerProperty, mode); |
1088 | 21 | if (!picker) return; | 28 | if (!picker) return; |
1134 | 22 | picker.closed.connect(function () { | 29 | picker.closed.connect(function () { element.highlighted = false; }); |
1135 | 23 | element.highlighted = false; | 30 | } |
1136 | 24 | }); | 31 | |
1137 | 25 | } | 32 | height: layout.height + divider.height |
1138 | 26 | 33 | ||
1139 | 27 | onDateTimeChanged: { | 34 | // backgroud color of full date fabel, to be shown when user click on date and DatePicker is visable |
1140 | 28 | dateInput.text = dateTime.toLocaleDateString(); | 35 | Rectangle { |
1141 | 29 | timeInput.text = Qt.formatTime(dateTime); | 36 | id: dateBG |
1142 | 30 | } | 37 | |
1143 | 31 | 38 | property bool highlighted: false | |
1144 | 32 | ListItem.Header { | 39 | |
1145 | 33 | id: listHeader | 40 | height: layout.summary.height + units.gu(3.5) |
1146 | 34 | __foregroundColor: Theme.palette.normal.baseText | 41 | width: showTimePicker ? layout.title.width + units.gu(3) : layout.width |
1147 | 35 | } | 42 | anchors.bottom: parent.bottom |
1148 | 36 | 43 | color: highlighted || abstractButtonDate.pressed ? UbuntuColors.lightGrey : "transparent" | |
1149 | 37 | Item { | 44 | } |
1150 | 38 | anchors { | 45 | |
1151 | 39 | left: parent.left | 46 | // backgroud color of time label, to be shown when user click on date and DatePicker is visable |
1152 | 40 | right: parent.right | 47 | Rectangle { |
1153 | 41 | margins: units.gu(2) | 48 | id: timeBG |
1154 | 42 | } | 49 | |
1155 | 43 | 50 | property bool highlighted: false | |
1156 | 44 | height: dateInput.height | 51 | |
1157 | 45 | 52 | height: dateBG.height | |
1158 | 46 | NewEventEntryField{ | 53 | width: slot.width + units.gu(4) |
1159 | 47 | id: dateInput | 54 | anchors.bottom: parent.bottom |
1160 | 48 | objectName: "dateInput" | 55 | anchors.right: parent.right |
1161 | 49 | 56 | color: (highlighted || abstractButtonTime.pressed) ? UbuntuColors.lightGrey : "transparent" | |
1162 | 50 | text: "" | 57 | } |
1163 | 51 | anchors.left: parent.left | 58 | |
1164 | 52 | width: !showTimePicker ? parent.width : 4 * parent.width / 5 | 59 | // ListItemLayout to keep full date label and time label |
1165 | 53 | 60 | ListItemLayout { | |
1166 | 54 | MouseArea{ | 61 | id: layout |
1167 | 55 | anchors.fill: parent | 62 | |
1168 | 56 | onClicked: openDatePicker(dateInput, dateTimeInput, "dateTime", "Years|Months|Days") | 63 | title.text: headerText |
1169 | 57 | } | 64 | title.color: Theme.palette.selected.overlayText |
1170 | 58 | } | 65 | title.font.pixelSize: FontUtils.sizeToPixels("small") |
1171 | 59 | 66 | subtitle.text: " " | |
1172 | 60 | NewEventEntryField{ | 67 | summary.color: dateBG.highlighted ? "white" : Theme.palette.selected.fieldText |
1173 | 61 | id: timeInput | 68 | summary.font.pixelSize: FontUtils.sizeToPixels("medium") |
1174 | 62 | objectName: "timeInput" | 69 | |
1175 | 63 | 70 | // Item to hold Trailing tile label item | |
1176 | 64 | text: "" | 71 | Item { |
1177 | 65 | anchors.right: parent.right | 72 | id: slot |
1178 | 66 | width: parent.width / 5 | 73 | |
1179 | 74 | width: secondLabel.width | ||
1180 | 75 | height: parent.height | ||
1181 | 67 | visible: showTimePicker | 76 | visible: showTimePicker |
1187 | 68 | horizontalAlignment: Text.AlignRight | 77 | SlotsLayout.overrideVerticalPositioning: true |
1188 | 69 | 78 | ||
1189 | 70 | MouseArea{ | 79 | // label to keep time [ 10:20 AM ] |
1190 | 71 | anchors.fill: parent | 80 | Label { |
1191 | 72 | onClicked: openDatePicker(timeInput, dateTimeInput, "dateTime", "Hours|Minutes") | 81 | id: secondLabel |
1192 | 82 | |||
1193 | 83 | fontSize: "medium" | ||
1194 | 84 | color: timeBG.highlighted ? "white" : Theme.palette.selected.fieldText | ||
1195 | 85 | y: layout.mainSlot.y + layout.summary.y + layout.summary.baselineOffset - baselineOffset | ||
1196 | 73 | } | 86 | } |
1197 | 74 | } | 87 | } |
1198 | 75 | } | 88 | } |
1199 | 89 | |||
1200 | 90 | // AbstractButton to be triggered when user click on full date | ||
1201 | 91 | AbstractButton { | ||
1202 | 92 | id: abstractButtonDate | ||
1203 | 93 | |||
1204 | 94 | anchors.fill: dateBG | ||
1205 | 95 | onClicked: { openDatePicker(dateBG, dateTimeInput, "dateTime", "Years|Months|Days")} | ||
1206 | 96 | } | ||
1207 | 97 | |||
1208 | 98 | // AbstractButton to be triggered when user click on time | ||
1209 | 99 | AbstractButton { | ||
1210 | 100 | id: abstractButtonTime | ||
1211 | 101 | |||
1212 | 102 | anchors.fill: timeBG | ||
1213 | 103 | visible: showTimePicker | ||
1214 | 104 | onClicked: { openDatePicker(timeBG, dateTimeInput, "dateTime", "Hours|Minutes")} | ||
1215 | 105 | } | ||
1216 | 106 | |||
1217 | 76 | } | 107 | } |
1218 | 77 | 108 | ||
1219 | === modified file 'po/com.ubuntu.calendar.pot' | |||
1220 | --- po/com.ubuntu.calendar.pot 2016-04-29 18:22:02 +0000 | |||
1221 | +++ po/com.ubuntu.calendar.pot 2016-05-12 13:36:24 +0000 | |||
1222 | @@ -1,6 +1,6 @@ | |||
1223 | 1 | # SOME DESCRIPTIVE TITLE. | 1 | # SOME DESCRIPTIVE TITLE. |
1224 | 2 | # Copyright (C) YEAR Canonical Ltd. | 2 | # Copyright (C) YEAR Canonical Ltd. |
1226 | 3 | # This file is distributed under the same license as the package. | 3 | # This file is distributed under the same license as the PACKAGE package. |
1227 | 4 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | 4 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. |
1228 | 5 | # | 5 | # |
1229 | 6 | #, fuzzy | 6 | #, fuzzy |
1230 | @@ -8,7 +8,7 @@ | |||
1231 | 8 | msgstr "" | 8 | msgstr "" |
1232 | 9 | "Project-Id-Version: \n" | 9 | "Project-Id-Version: \n" |
1233 | 10 | "Report-Msgid-Bugs-To: \n" | 10 | "Report-Msgid-Bugs-To: \n" |
1235 | 11 | "POT-Creation-Date: 2016-04-29 15:21-0300\n" | 11 | "POT-Creation-Date: 2016-05-03 09:46-0300\n" |
1236 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
1237 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
1238 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
1239 | @@ -123,7 +123,7 @@ | |||
1240 | 123 | #. TRANSLATORS: this is a time formatting string, | 123 | #. TRANSLATORS: this is a time formatting string, |
1241 | 124 | #. see http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions. | 124 | #. see http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions. |
1242 | 125 | #. It's used in the header of the month and week views | 125 | #. It's used in the header of the month and week views |
1244 | 126 | #: ../DayView.qml:122 ../MonthView.qml:76 ../WeekView.qml:154 | 126 | #: ../DayView.qml:122 ../MonthView.qml:76 ../WeekView.qml:150 |
1245 | 127 | msgid "MMMM yyyy" | 127 | msgid "MMMM yyyy" |
1246 | 128 | msgstr "" | 128 | msgstr "" |
1247 | 129 | 129 |
Good work. Some small inline comments.