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