Merge lp:~renatofilho/ubuntu-calendar-app/majster-new-event-page into lp:ubuntu-calendar-app

Proposed by Renato Araujo Oliveira Filho
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
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.

To post a comment you must log in.
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote : Posted in a previous version of this proposal

Good work. Some small inline comments.

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

Revision history for this message
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://code.launchpad.net/~renatofilho/ubuntu-calendar-app/majster-new-event-page/+merge/294499/+edit-commit-message

https://core-apps-jenkins.ubuntu.com/job/calendar-app-ci/846/
Executed test runs:
    None: https://core-apps-jenkins.ubuntu.com/job/generic-update-mp/893/console

Click here to trigger a rebuild:
https://core-apps-jenkins.ubuntu.com/job/calendar-app-ci/846/rebuild

review: Needs Fixing (continuous-integration)
824. By Renato Araujo Oliveira Filho

Fixed header license format.

825. By Renato Araujo Oliveira Filho

Remove empty lines.

Revision history for this message
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://code.launchpad.net/~renatofilho/ubuntu-calendar-app/majster-new-event-page/+merge/294499/+edit-commit-message

https://core-apps-jenkins.ubuntu.com/job/calendar-app-ci/847/
Executed test runs:
    None: https://core-apps-jenkins.ubuntu.com/job/generic-update-mp/894/console

Click here to trigger a rebuild:
https://core-apps-jenkins.ubuntu.com/job/calendar-app-ci/847/rebuild

review: Needs Fixing (continuous-integration)
826. By Renato Araujo Oliveira Filho

Update new event header and margins.

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :

FAILED: Continuous integration, rev:826
https://jenkins.canonical.com/system-apps/job/lp-ubuntu-calendar-app-ci/3/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/743/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/743
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=vivid+overlay/690
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=xenial+overlay/690
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=yakkety/690
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/682/console
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/682/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-ubuntu-calendar-app-ci/3/rebuild

review: Needs Fixing (continuous-integration)

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

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

Subscribers

People subscribed via source and target branches

to status/vote changes: