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
=== modified file 'ContactChoicePopup.qml'
--- ContactChoicePopup.qml 2016-02-04 13:37:00 +0000
+++ ContactChoicePopup.qml 2016-05-12 13:36:24 +0000
@@ -17,138 +17,258 @@
17 */17 */
18import QtQuick 2.418import QtQuick 2.4
19import Ubuntu.Components 1.319import Ubuntu.Components 1.3
20import Ubuntu.Components.Popups 1.3
21import Ubuntu.Components.ListItems 1.0
22import Ubuntu.Components.Themes.Ambiance 1.0
23import QtOrganizer 5.0
24import QtContacts 5.020import QtContacts 5.0
2521
26import "Defines.js" as Defines22Item {
27
28Popover {
29 id: root23 id: root
30 objectName: "contactPopover"24
25 width: parent.width
26 height: mainColumn.height
27
28 property bool contactOpen: false
29 property var openContanctObject
3130
32 signal contactSelected(var contact, string emailAddress);31 signal contactSelected(var contact, string emailAddress);
3332
34 Label {33 onContactOpenChanged: {
35 id: noContact34 positionDelay.start()
36 anchors.centerIn: parent35 }
37 text: i18n.tr("No contact")36
38 visible: contactModel.contacts.length === 037 Timer {
39 }38 id: positionDelay
4039 interval: 300
41 UnionFilter {40 onTriggered: suggestionsFlickable.contentY = openContanctObject.y
42 id: filter41 }
4342
44 property string searchString: ""43 states: [
4544 State {
46 filters: [45 name: "open"
47 DetailFilter{46 PropertyChanges { target: contactsSuggestionItem; height: units.gu(10)}
48 detail: ContactDetail.Name47 },
49 field: Name.FirstName48 State {
50 matchFlags: Filter.MatchContains49 name: "close"
51 value: filter.searchString50 PropertyChanges { target: contactsSuggestionItem; height: 0}
52 },51 }
53 DetailFilter{52
54 detail: ContactDetail.Name53 ]
55 field: Name.LastName54
56 matchFlags: Filter.MatchContains55 Behavior on height {
57 value: filter.searchString56 UbuntuNumberAnimation {}
58 },57 }
59 DetailFilter{58
60 detail: ContactDetail.DisplayLabel
61 field: DisplayLabel.Label
62 matchFlags: Filter.MatchContains
63 value: filter.searchString
64 }
65 ]
66 }
6759
68 ContactModel {60 ContactModel {
69 id: contactModel61 id: contactModel
70 manager: "galera"62 manager: "galera"
71 filter: filter
72 autoUpdate: true63 autoUpdate: true
73 }64 }
7465
75 Timer {
76 id: idleSearch
7766
78 interval: 500
79 repeat: false
80 onTriggered: {
81 filter.searchString = searchBox.text
82 }
83 }
8467
85 Column {68 Column {
86 anchors.top: parent.top69 id: mainColumn
87 anchors.left: parent.left70 width: parent.width
88 anchors.right: parent.right71 spacing: units.gu(1)
89 anchors.margins: units.gu(1)72
73 Item {
74 id: guestsAdded
75 width: parent.width
76
77 }
9078
91 TextField {79 TextField {
92 id: searchBox80 id: addGuestTestField
93 objectName: "contactPopoverInput"81 objectName: "addGuestTestField"
94 focus: true82
95 width: parent.width83 width: parent.width
96 placeholderText: i18n.tr("Search contact")
97 inputMethodHints: Qt.ImhNoPredictiveText84 inputMethodHints: Qt.ImhNoPredictiveText
98 primaryItem: Icon {85 placeholderText: i18n.tr("Guests")
99 height: parent.height*0.586
100 width: parent.height*0.587 onActiveFocusChanged: {
101 anchors.verticalCenter: parent.verticalCenter88 if(addGuestTestField.activeFocus) {
102 name:"find"89 lol2.state = "open"
103 }90 flickable.makeMeVisible(addGuestListItem);
104 onTextChanged: {91 } else {
105 idleSearch.restart()92 lol2.state = "close"
106 }93 }
94 }
95
107 }96 }
10897
109 ListView {98 Component {
110 id: contactList99 id: suggestionsDelegate
111 objectName: "contactPopoverList"100 Item {
112 width: parent.width101 id: rootSug
113 model: contactModel102
114 height: units.gu(15)103 clip: true
115 clip: true104 width: String(contact.displayLabel.label).toLowerCase().search(addGuestTestField.text.toLowerCase()) == - 1 ? 0 : mainGrid.width
116 focus: false105 height: mainGrid.height
117 delegate: Column {106
118 width: contactList.width107 ListModel {
119 Repeater {108 id: addressesModel
120 anchors {109 }
121 left: parent.left110
122 right: parent.right111 function getEmails() {
123 }112 for(var i=0; contact.emails.length > i; i++) {
124 height: childrenRect.height113 addressesModel.append({"email": contact.emails[i].emailAddress})
125114 }
126 model: Math.max(1, contact.emails.length)115 }
127 delegate: ListItem {116
128 property string emailAddress: contact.emails.length > index ? contact.emails[index].emailAddress : ""117 Behavior on width {
129118 UbuntuNumberAnimation {}
119 }
120
121 Connections {
122 target: root
123 onContactOpenChanged: {
124 if(!contactOpen) {
125 emailAddressesColumn.state = "default"
126 }
127 }
128 }
129
130 Row {
131 id: mainGrid
132
133 AbstractButton {
134 id: contactNameAbstractButton
135
136 width: contactNameLabel.width + units.gu(1)
137 height: contactNameLabel.height + units.gu(1)
130 activeFocusOnPress: false138 activeFocusOnPress: false
131 opacity: emailAddress.length > 0 ? 1.0 : 0.3139 enabled: contact.emails.length > 0
132 width: contactList.width140
133 objectName: "contactPopoverList%1".arg(index)141 Rectangle {
134 ListItemLayout {
135 title.text: contact.displayLabel.label
136 subtitle.text: emailAddress
137 }
138 MouseArea {
139 anchors.fill: parent142 anchors.fill: parent
140 onClicked: {143 color: (parent.pressed || (emailAddressesColumn.state === "open")) ? UbuntuColors.lightGrey : "transparent"
141 if (emailAddress.length > 0) {144 }
142 root.contactSelected(contact, emailAddress);145
143 PopupUtils.close(root)146 Label {
144 }147 id: contactNameLabel
145 }148 text: emailAddressesColumn.state === "open" ? contact.displayLabel.label+":" : contact.displayLabel.label
146 }149 anchors.centerIn: parent
147 }150 color: contact.emails.length > 0 ? "black" : UbuntuColors.lightGrey
148 }151 font.italic: contact.emails.length > 0 ? false : true
152 fontSize: "medium"
153 }
154 onClicked: {
155 if(contact.emails.length > 1) {
156 if(contactOpen) {
157 contactOpen = false
158 } else {
159 emailAddressesColumn.openClose()
160 openContanctObject = rootSug
161 }
162
163 } else {
164 root.contactSelected(contact, contact.email.emailAddress);
165 }
166 }
167 }
168 Column {
169 id: emailAddressesColumn
170
171 clip: true
172 state: "default"
173
174 function openClose() {
175 if(emailAddressesColumn.state === "open") {
176 emailAddressesColumn.state = "default"
177 } else {
178 emailAddressesColumn.state = "open"
179 }
180 }
181
182 states: [
183 State {
184 name: "default"
185 PropertyChanges { target: emailAddressesColumn; width: 0 }
186 },
187 State {
188 name: "open"
189 PropertyChanges { target: emailAddressesColumn; width: mainColumn.width - contactNameAbstractButton.width }
190 }
191 ]
192
193 onStateChanged: {
194 if(state === "open") {
195 rootSug.getEmails()
196 contactOpen = true
197 } else {
198 addressesModel.clear()
199 }
200 }
201
202 Repeater {
203 model: addressesModel
204 delegate: AbstractButton {
205 width: contactEmailLabel.width + units.gu(2)
206 height: contactEmailLabel.height + units.gu(1)
207 activeFocusOnPress: false
208
209 Rectangle {
210 anchors.fill: parent
211 color: parent.pressed ? UbuntuColors.lightGrey : "transparent"
212 }
213
214 Label {
215 id: contactEmailLabel
216 anchors.verticalCenter: parent.verticalCenter
217 anchors.left: parent.left
218 anchors.leftMargin: units.gu(1)
219 text: email
220 color: contact.emails.length > 0 ? "black" : UbuntuColors.lightGrey
221 font.italic: contact.emails.length > 0 ? false : true
222 fontSize: "medium"
223 elide: Text.ElideRight
224 }
225
226 onClicked: {
227 root.contactSelected(contact, email);
228 emailAddressesColumn.state = "default"
229 }
230 }
231 }
232 }
233 }
234 }
235 }
236
237 Item {
238 id: contactsSuggestionItem
239 width: parent.width
240 clip: true
241
242 Flickable {
243 id: suggestionsFlickable
244 width: parent.width - units.gu(0)
245 height: parent.height - units.gu(1)
246 anchors.top: parent.top
247 anchors.topMargin: units.gu(1)
248 contentHeight: suggestionsListView.height + units.gu(1)
249
250 // animation on flickable contentY change
251 Behavior on contentY {
252 UbuntuNumberAnimation {}
253 }
254
255 onFlickStarted: contactOpen = false
256 Flow {
257 id: suggestionsListView
258 width: parent.width
259 spacing: units.gu(1.5)
260
261 Repeater {
262 model: contactModel
263 delegate: suggestionsDelegate
264 }
265 }
266 }
267
268 Scrollbar {
269 flickableItem: suggestionsFlickable
270 align: Qt.AlignTrailing
149 }271 }
150 }272 }
151 }273 }
152
153 Component.onCompleted: searchBox.forceActiveFocus()
154}274}
155275
=== modified file 'KeyboardRectangle.qml'
--- KeyboardRectangle.qml 2016-02-03 19:53:46 +0000
+++ KeyboardRectangle.qml 2016-05-12 13:36:24 +0000
@@ -26,16 +26,7 @@
26 anchors.bottom: parent.bottom26 anchors.bottom: parent.bottom
27 height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 027 height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
2828
29 states: [29 property bool isVisible: Qt.inputMethod.visible
30 State {
31 name: "hidden"
32 when: keyboardRect.height == 0
33 },
34 State {
35 name: "shown"
36 when: keyboardRect.height == Qt.inputMethod.keyboardRectangle.height
37 }
38 ]
3930
40 function recursiveFindFocusedItem(parent) {31 function recursiveFindFocusedItem(parent) {
41 if (parent.activeFocus) {32 if (parent.activeFocus) {
4233
=== modified file 'NewEvent.qml'
--- NewEvent.qml 2016-04-06 18:46:29 +0000
+++ NewEvent.qml 2016-05-12 13:36:24 +0000
@@ -319,6 +319,7 @@
319 }319 }
320320
321 Keys.onEscapePressed: root.cancel()321 Keys.onEscapePressed: root.cancel()
322
322 header: PageHeader {323 header: PageHeader {
323 id: pageHeader324 id: pageHeader
324325
@@ -326,37 +327,35 @@
326 title: isEdit ? i18n.tr("Edit Event"):i18n.tr("New Event")327 title: isEdit ? i18n.tr("Edit Event"):i18n.tr("New Event")
327 leadingActionBar.actions: Action {328 leadingActionBar.actions: Action {
328 id: backAction329 id: backAction
329
330 name: "cancel"330 name: "cancel"
331 text: i18n.tr("Cancel")331 text: i18n.tr("Cancel")
332 iconName: isEdit ? "back" : "down"332 iconName: isEdit ? "back" : "down"
333 onTriggered: root.cancel()333 onTriggered: root.cancel()
334 }334 }
335335
336 trailingActionBar.actions: [336 trailingActionBar {
337 Action {337 actions: [
338 text: i18n.tr("Delete");338 Action {
339 objectName: "delete"339 text: i18n.tr("Save")
340 iconName: "delete"340 iconName: "tick"
341 visible : isEdit341 onTriggered: saveToQtPim();
342 onTriggered: {342 },
343 var dialog = PopupUtils.open(Qt.resolvedUrl("DeleteConfirmationDialog.qml"),root,{"event": event});343 Action {
344 dialog.deleteEvent.connect( function(eventId){344 text: i18n.tr("Delete")
345 model.removeItem(eventId);345 iconName: "delete"
346 if (pageStack)346 visible : isEdit
347 pageStack.pop();347 onTriggered: {
348 root.eventDeleted(eventId);348 var dialog = PopupUtils.open(Qt.resolvedUrl("DeleteConfirmationDialog.qml"),root,{"event": event});
349 });349 dialog.deleteEvent.connect( function(eventId){
350 model.removeItem(eventId);
351 if (pageStack)
352 pageStack.pop();
353 root.eventDeleted(eventId);
354 });
355 }
350 }356 }
351 },357 ]
352 Action {358 }
353 iconName: "ok"
354 objectName: "save"
355 text: i18n.tr("Save")
356 enabled: !!titleEdit.text.trim()
357 onTriggered: saveToQtPim();
358 }
359 ]
360 }359 }
361360
362 Component{361 Component{
@@ -399,7 +398,7 @@
399 // if it is not, try to scroll and make it visible398 // if it is not, try to scroll and make it visible
400 var targetY = position.y + item.height - flickable.height399 var targetY = position.y + item.height - flickable.height
401 if (targetY >= 0 && position.y) {400 if (targetY >= 0 && position.y) {
402 flickable.contentY = targetY;401 flickable.contentY = targetY + units.gu(1);
403 } else if (position.y < flickable.contentY) {402 } else if (position.y < flickable.contentY) {
404 // if it is hidden at the top, also show it403 // if it is hidden at the top, also show it
405 flickable.contentY = position.y;404 flickable.contentY = position.y;
@@ -407,6 +406,11 @@
407 flickable.returnToBounds()406 flickable.returnToBounds()
408 }407 }
409408
409 // animation on flickable contentY change
410 Behavior on contentY {
411 UbuntuNumberAnimation {}
412 }
413
410 flickableDirection: Flickable.VerticalFlick414 flickableDirection: Flickable.VerticalFlick
411 anchors{415 anchors{
412 left: parent.left416 left: parent.left
@@ -425,9 +429,8 @@
425429
426 NewEventTimePicker{430 NewEventTimePicker{
427 id: startDateTimeInput431 id: startDateTimeInput
428 objectName: "startDateTimeInput"432 //TRANSLATORS: this referes to date. eg: From: Wendsday, 9 March 2016
429433 headerText: i18n.tr("From")
430 header: i18n.tr("From")
431 showTimePicker: !allDayEventCheckbox.checked434 showTimePicker: !allDayEventCheckbox.checked
432 anchors {435 anchors {
433 left: parent.left436 left: parent.left
@@ -435,255 +438,275 @@
435 }438 }
436 onDateTimeChanged: {439 onDateTimeChanged: {
437 startDate = dateTime;440 startDate = dateTime;
438 endDateTimeInput.dateTime = new Date(startDate.getTime() + root.eventSize)
439 }441 }
440 }442 }
441443
442 NewEventTimePicker{444 NewEventTimePicker{
443 id: endDateTimeInput445 id: endDateTimeInput
444 objectName: "endDateTimeInput"446 //TRANSLATORS: this referes to date. eg: To: Wendsday, 9 March 2016
445447 headerText: i18n.tr("To")
446 header: i18n.tr("To")
447 showTimePicker: !allDayEventCheckbox.checked448 showTimePicker: !allDayEventCheckbox.checked
448 anchors {449 anchors {
449 left: parent.left450 left: parent.left
450 right: parent.right451 right: parent.right
451 }452 }
452 onDateTimeChanged: {453 onDateTimeChanged: {
453 if (dateTime.getTime() < startDate.getTime()) {
454 root.eventSize = root.allDay ? 0 : root.millisecsInAnHour
455 dateTime = new Date(startDate.getTime() + root.eventSize)
456 return
457 }
458
459 endDate = dateTime;454 endDate = dateTime;
460 if (allDay)455 }
461 root.eventSize = endDate.midnight().getTime() - startDate.midnight().getTime()456 }
462 else457
463 root.eventSize = endDate.getTime() - startDate.getTime()458 // All day event ListItem with Switch
464 }459 ListItem {
465 }460 width: parent.width
466461
467 ListItems.Standard {462 ListItemLayout {
468 anchors {463 title.text: i18n.tr("All day event")
469 left: parent.left464 Switch {
470 right: parent.right465 id: allDayEventCheckbox
471 }466 checked: false
472467 SlotsLayout.position: SlotsLayout.Trailing;
473 text: i18n.tr("All day event")468 }
474 __foregroundColor: Theme.palette.normal.baseText469 }
475 showDivider: false470 onClicked: {
476 control: CheckBox {471 allDayEventCheckbox.checked = !allDayEventCheckbox.checked
477 objectName: "allDayEventCheckbox"472 }
478 id: allDayEventCheckbox473
479 checked: false474 }
480 onCheckedChanged: {475
481 if (checked)476 // ListItem which holds "Event details" label + TextField + TextArea + TextField
482 root.eventSize = Math.max(endDate.midnight().getTime() - startDate.midnight().getTime(), 0)477 ListItem {
483 else478 height: eventDetailsColumn.height + eventDetailsColumn.spacing * 2
484 root.eventSize = Math.max(endDate.getTime() - startDate.getTime(), root.millisecsInAnHour)479
485 }480 Column {
486 }481 id: eventDetailsColumn
487 }482 spacing: units.gu(2)
488483 anchors {
489 ListItems.ThinDivider {}484 left: parent.left
490485 right: parent.right
491 Column {486 top: parent.top
492 width: parent.width487 margins: units.gu(2)
493 spacing: units.gu(1)488 }
494489
495 ListItems.Header{490 Label {
496 text: i18n.tr("Event Details")491 anchors {
497 __foregroundColor: Theme.palette.normal.baseText492 left: parent.left
498 }493 right: parent.right
499494 }
500 TextField {495
501 id: titleEdit496 text: i18n.tr("Event details")
502 objectName: "newEventName"497 elide: Text.ElideRight
503498 }
504 anchors {499
505 left: parent.left500 TextField {
506 right: parent.right501 id: titleEdit
507 margins: units.gu(2)502 objectName: "newEventName"
508 }503
509504 anchors {
510 placeholderText: i18n.tr("Event Name")505 left: parent.left
511 onFocusChanged: {506 right: parent.right
512 if(titleEdit.focus) {507 }
513 flickable.makeMeVisible(titleEdit);508 inputMethodHints: Qt.ImhNoPredictiveText
514 }509 placeholderText: i18n.tr("Event Name")
515 }510
516 }511 onActiveFocusChanged: {
517512 if(titleEdit.activeFocus) {
518 TextArea{513 flickable.makeMeVisible(titleEdit);
519 id: messageEdit514 }
520 objectName: "eventDescriptionInput"515 }
521516 }
522 anchors {517
523 left: parent.left518 TextArea{
524 right: parent.right519 id: messageEdit
525 margins: units.gu(2)520 objectName: "eventDescriptionInput"
526 }521
527522 anchors {
528 placeholderText: i18n.tr("Description")523 left: parent.left
529 onFocusChanged: {524 right: parent.right
530 if(messageEdit.focus) {525 }
531 flickable.makeMeVisible(messageEdit);526 placeholderText: i18n.tr("Description")
532 }527
533 }528 onActiveFocusChanged: {
534 }529 if(messageEdit.activeFocus) {
535530 flickable.makeMeVisible(messageEdit);
536 TextField {531 }
537 id: locationEdit532 }
538 objectName: "eventLocationInput"533 }
539534
540 anchors {535 TextField {
541 left: parent.left536 id: locationEdit
542 right: parent.right537 objectName: "eventLocationInput"
543 margins: units.gu(2)538
544 }539 anchors {
545540 left: parent.left
546 inputMethodHints: Qt.ImhNoPredictiveText541 right: parent.right
547 placeholderText: i18n.tr("Location")542 }
548543 inputMethodHints: Qt.ImhNoPredictiveText
549 onFocusChanged: {544 placeholderText: i18n.tr("Location")
550 if(locationEdit.focus) {545
551 flickable.makeMeVisible(locationEdit);546 onActiveFocusChanged: {
552 }547 if(locationEdit.activeFocus) {
553 }548 flickable.makeMeVisible(locationEdit);
554 }549 }
555 }550 }
556551 }
557 Column {552 }
558 width: parent.width553 }
559 spacing: units.gu(1)554
560555 // ListItem to hold calendars selector
561 ListItems.Header {556 ListItem {
562 text: i18n.tr("Calendar")557 height: chooseCalendarColumn.height + (eventDetailsColumn.anchors.topMargin*2)
563 __foregroundColor: Theme.palette.normal.baseText558
564 }559 Column {
565560 id: chooseCalendarColumn
566 OptionSelector{561 spacing: units.gu(2)
567 id: calendarsOption562 anchors {
568 objectName: "calendarsOption"563 left: parent.left
569564 right: parent.right
570 anchors {565 top: parent.top
571 left: parent.left566 margins: units.gu(2)
572 right: parent.right567 }
573 margins: units.gu(2)568
574 }569 Label {
575570 width: parent.width
576 containerHeight: itemHeight * 4571 anchors {
577 model: root.model ? root.model.getWritableAndSelectedCollections() : []572 left: parent.left
578573 right: parent.right
579 delegate: OptionSelectorDelegate{574 }
580 text: modelData.name575 text: i18n.tr("Choose calendar")
581576 elide: Text.ElideRight
582 UbuntuShape{577 }
583 id: calColor578
584 width: height579 ListItems.ItemSelector {
585 height: parent.height - units.gu(2)580 id: calendarsOption
586 color: modelData.color581 model: root.model.getWritableCollections();
587 anchors {582 delegate: OptionSelectorDelegate { text: modelData.name }
588 right: parent.right583 }
589 rightMargin: units.gu(4)584
590 verticalCenter: parent.verticalCenter585 }
591 }586 }
592 }587
593 }588
594 onExpandedChanged: Qt.inputMethod.hide();589 // add guest field
595 }590 ListItem {
596 }591 id: addGuestListItem
597592 height: addGusestColumn.height + (addGusestColumn.anchors.margins*2)
598 Column {593
599 width: parent.width594 Column {
600 spacing: units.gu(1)595 id: addGusestColumn
601596 anchors {
602 ListItems.Header {597 left: parent.left
603 text: i18n.tr("Guests")598 right: parent.right
604 __foregroundColor: Theme.palette.normal.baseText599 top: parent.top
605 }600 margins: units.gu(2)
606601 }
607 Button{602
608 id: addGuestButton603 Behavior on height {
609 objectName: "addGuestButton"604 UbuntuNumberAnimation {}
610605 }
611 property var contactsPopup: null606
612607 Label {
613 text: i18n.tr("Add Guest")608 width: parent.width
614 anchors {609 text: i18n.tr("Event details")
615 left: parent.left610 elide: Text.ElideRight
616 right: parent.right611 }
617 margins: units.gu(2)612
618 }613 Item {
619614 width: parent.width
620 onClicked: {615 height: units.gu(1)
621 if (contactsPopup)616 }
622 return617
623618 ListModel{
624 flickable.makeMeVisible(addGuestButton)619 id: contactModel
625 contactsPopup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), addGuestButton);620 }
626 contactsPopup.contactSelected.connect( function(contact, emailAddress) {621
627 if(!internal.isContactAlreadyAdded(contact, emailAddress) ) {622 Component {
628 var t = internal.contactToAttendee(contact, emailAddress);623 id: addedGusestDelegate
629 contactModel.append({"contact": t});624 Item {
630 }625 width: delegateRow.width + units.gu(1)
631626 height: units.gu(3)
632 });627
633 contactsPopup.Component.onDestruction.connect( function() {628 Rectangle {
634 addGuestButton.contactsPopup = null629 anchors.fill: parent
635 })630 color: delegateMouseArea.pressed ? UbuntuColors.lightGrey : "transparent"
636 }631 }
637 }632
638633 Row {
639 UbuntuShape {634 id: delegateRow
640 anchors {635 height: parent.height
641 left: parent.left636 spacing: units.gu(0.5)
642 right: parent.right637 anchors.horizontalCenter: parent.horizontalCenter
643 margins: units.gu(2)638
644 }639 UbuntuShape {
645640 id: rec
646 height: contactList.height641 height: parent.height - units.gu(0.5)
647642 anchors.verticalCenter: parent.verticalCenter
648 Column{643 width: height
649 id: contactList644 color: "green"
650 objectName: "guestList"645 Text {
651646 anchors.centerIn: parent
652 spacing: units.gu(1)647 text: contact.name.charAt(0).toUpperCase()
653 width: parent.width648 font.bold: true
654 clip: true649 color: "white"
655
656 ListModel{
657 id: contactModel
658 }
659
660 Repeater{
661 model: contactModel
662 delegate: ListItem {
663 objectName: "eventGuest%1".arg(index)
664
665 ListItemLayout {
666 title.text: contact.name
667 subtitle.text: contact.emailAddress
668 }
669
670 leadingActions: ListItemActions {
671 actions: Action {
672 iconName: "delete"
673 onTriggered: {
674 contactModel.remove(index)
675 }
676 }650 }
677 }651 }
678 }652 Label {
679 }653 id: lab
680 }654 anchors.verticalCenter: parent.verticalCenter
681 }655 text: contact.name
682656 }
683 ListItems.ThinDivider {657 }
684 visible: (event != undefined) && (event.itemType === Type.Event)658
685 }659 MouseArea {
686660 id: delegateMouseArea
661 anchors.fill: parent
662 onClicked: contactModel.remove(index)
663
664 }
665 }
666 }
667
668 // Add guest section (this is now in development)
669 Item {
670 width: parent.width
671 height: suggestionsListView.height + units.gu(0.5)
672 Behavior on height {
673 UbuntuNumberAnimation {}
674 }
675
676 Flow {
677 id: suggestionsListView
678 width: parent.width
679 spacing: units.gu(1.5)
680 move: Transition {
681 NumberAnimation {
682 properties: "x,y"
683 }
684 }
685 add: Transition {
686 NumberAnimation {
687 properties: "x,y"
688 }
689 }
690
691 Repeater {
692 model: contactModel
693 delegate: addedGusestDelegate
694 }
695 }
696 }
697
698 ContactChoicePopup {
699 id: lol2
700 width: parent.width
701
702 onContactSelected: {
703 if(!internal.isContactAlreadyAdded(contact, emailAddress) ) {
704 var t = internal.contactToAttendee(contact, emailAddress);
705 contactModel.append({"contact": t});
706 }
707 }
708 }
709 }
687 }710 }
688711
689 ListItem {712 ListItem {
@@ -768,6 +791,12 @@
768 }791 }
769 }792 }
770793
794 // Scrollbar
795 Scrollbar{
796 flickableItem: flickable
797 align: Qt.AlignTrailing
798 }
799
771 // used to keep the field visible when the keyboard appear or dismiss800 // used to keep the field visible when the keyboard appear or dismiss
772 KeyboardRectangle {801 KeyboardRectangle {
773 id: keyboardRectangle802 id: keyboardRectangle
@@ -783,14 +812,7 @@
783 PauseAnimation { duration: 200 }812 PauseAnimation { duration: 200 }
784 ScriptAction {813 ScriptAction {
785 script: {814 script: {
786 if (addGuestButton.contactsPopup) {815 flickable.makeMeVisible(flickable.activeItem)
787 // WORKAROUND: causes the popover to follow the buttom position when keyboard appears
788 flickable.makeMeVisible(addGuestButton)
789 addGuestButton.contactsPopup.caller = null
790 addGuestButton.contactsPopup.caller = addGuestButton
791 } else {
792 flickable.makeMeVisible(flickable.activeItem)
793 }
794 }816 }
795 }817 }
796 }818 }
@@ -827,8 +849,7 @@
827 return false;849 return false;
828 }850 }
829851
830 function attendeeFromData(id, name, emailAddress)852 function attendeeFromData(id, name, emailAddress) {
831 {
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");
833 attendee.name = name854 attendee.name = name
834 attendee.emailAddress = emailAddress855 attendee.emailAddress = emailAddress
835856
=== modified file 'NewEventTimePicker.qml'
--- NewEventTimePicker.qml 2016-03-22 20:09:08 +0000
+++ NewEventTimePicker.qml 2016-05-12 13:36:24 +0000
@@ -1,76 +1,107 @@
1import QtQuick 2.41import QtQuick 2.4
2import Ubuntu.Components.ListItems 1.0 as ListItem2import Ubuntu.Components 1.3
3import Ubuntu.Components.Themes.Ambiance 1.03import Ubuntu.Components.Themes.Ambiance 1.0
4import Ubuntu.Components.Pickers 1.04import Ubuntu.Components.Pickers 1.3
55
6Column {6ListItem {
7 id: dateTimeInput7 id: dateTimeInput
8 property alias header: listHeader.text8
99 property string headerText //header label ("From" or "To")
10 property date dateTime;10 property date dateTime //keep date from DatePicker
11 property bool showTimePicker;11 property bool showTimePicker //if true then user is able to set time on event
12
13 // when new date set in DatePicker then this will be run.
14 onDateTimeChanged: {
15 layout.summary.text = dateTime.toLocaleDateString() // set date
16 secondLabel.text = Qt.formatTime(dateTime, "hh:mm AP").replace(/\./g, "") // set time
17 }
1218
13 function clearFocus() {19 function clearFocus() {
14 dateInput.focus = false;20 dateBG.focus = false;
15 timeInput.focus = false;21 timeBG.focus = false;
16 }22 }
1723
24 // function to open date/time picker
18 function openDatePicker (element, caller, callerProperty, mode) {25 function openDatePicker (element, caller, callerProperty, mode) {
19 element.highlighted = true;26 element.highlighted = true;
20 var picker = PickerPanel.openDatePicker(caller, callerProperty, mode);27 var picker = PickerPanel.openDatePicker(caller, callerProperty, mode);
21 if (!picker) return;28 if (!picker) return;
22 picker.closed.connect(function () {29 picker.closed.connect(function () { element.highlighted = false; });
23 element.highlighted = false;30 }
24 });31
25 }32 height: layout.height + divider.height
2633
27 onDateTimeChanged: {34 // backgroud color of full date fabel, to be shown when user click on date and DatePicker is visable
28 dateInput.text = dateTime.toLocaleDateString();35 Rectangle {
29 timeInput.text = Qt.formatTime(dateTime);36 id: dateBG
30 }37
3138 property bool highlighted: false
32 ListItem.Header {39
33 id: listHeader40 height: layout.summary.height + units.gu(3.5)
34 __foregroundColor: Theme.palette.normal.baseText41 width: showTimePicker ? layout.title.width + units.gu(3) : layout.width
35 }42 anchors.bottom: parent.bottom
3643 color: highlighted || abstractButtonDate.pressed ? UbuntuColors.lightGrey : "transparent"
37 Item {44 }
38 anchors {45
39 left: parent.left46 // backgroud color of time label, to be shown when user click on date and DatePicker is visable
40 right: parent.right47 Rectangle {
41 margins: units.gu(2)48 id: timeBG
42 }49
4350 property bool highlighted: false
44 height: dateInput.height51
4552 height: dateBG.height
46 NewEventEntryField{53 width: slot.width + units.gu(4)
47 id: dateInput54 anchors.bottom: parent.bottom
48 objectName: "dateInput"55 anchors.right: parent.right
4956 color: (highlighted || abstractButtonTime.pressed) ? UbuntuColors.lightGrey : "transparent"
50 text: ""57 }
51 anchors.left: parent.left58
52 width: !showTimePicker ? parent.width : 4 * parent.width / 559 // ListItemLayout to keep full date label and time label
5360 ListItemLayout {
54 MouseArea{61 id: layout
55 anchors.fill: parent62
56 onClicked: openDatePicker(dateInput, dateTimeInput, "dateTime", "Years|Months|Days")63 title.text: headerText
57 }64 title.color: Theme.palette.selected.overlayText
58 }65 title.font.pixelSize: FontUtils.sizeToPixels("small")
5966 subtitle.text: " "
60 NewEventEntryField{67 summary.color: dateBG.highlighted ? "white" : Theme.palette.selected.fieldText
61 id: timeInput68 summary.font.pixelSize: FontUtils.sizeToPixels("medium")
62 objectName: "timeInput"69
6370 // Item to hold Trailing tile label item
64 text: ""71 Item {
65 anchors.right: parent.right72 id: slot
66 width: parent.width / 573
74 width: secondLabel.width
75 height: parent.height
67 visible: showTimePicker76 visible: showTimePicker
68 horizontalAlignment: Text.AlignRight77 SlotsLayout.overrideVerticalPositioning: true
6978
70 MouseArea{79 // label to keep time [ 10:20 AM ]
71 anchors.fill: parent80 Label {
72 onClicked: openDatePicker(timeInput, dateTimeInput, "dateTime", "Hours|Minutes")81 id: secondLabel
82
83 fontSize: "medium"
84 color: timeBG.highlighted ? "white" : Theme.palette.selected.fieldText
85 y: layout.mainSlot.y + layout.summary.y + layout.summary.baselineOffset - baselineOffset
73 }86 }
74 }87 }
75 }88 }
89
90 // AbstractButton to be triggered when user click on full date
91 AbstractButton {
92 id: abstractButtonDate
93
94 anchors.fill: dateBG
95 onClicked: { openDatePicker(dateBG, dateTimeInput, "dateTime", "Years|Months|Days")}
96 }
97
98 // AbstractButton to be triggered when user click on time
99 AbstractButton {
100 id: abstractButtonTime
101
102 anchors.fill: timeBG
103 visible: showTimePicker
104 onClicked: { openDatePicker(timeBG, dateTimeInput, "dateTime", "Hours|Minutes")}
105 }
106
76}107}
77108
=== modified file 'po/com.ubuntu.calendar.pot'
--- po/com.ubuntu.calendar.pot 2016-04-29 18:22:02 +0000
+++ po/com.ubuntu.calendar.pot 2016-05-12 13:36:24 +0000
@@ -1,6 +1,6 @@
1# SOME DESCRIPTIVE TITLE.1# SOME DESCRIPTIVE TITLE.
2# Copyright (C) YEAR Canonical Ltd.2# Copyright (C) YEAR Canonical Ltd.
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.
4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5#5#
6#, fuzzy6#, fuzzy
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: \n"9"Project-Id-Version: \n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2016-04-29 15:21-0300\n"11"POT-Creation-Date: 2016-05-03 09:46-0300\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -123,7 +123,7 @@
123#. TRANSLATORS: this is a time formatting string,123#. TRANSLATORS: this is a time formatting string,
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.
125#. It's used in the header of the month and week views125#. It's used in the header of the month and week views
126#: ../DayView.qml:122 ../MonthView.qml:76 ../WeekView.qml:154126#: ../DayView.qml:122 ../MonthView.qml:76 ../WeekView.qml:150
127msgid "MMMM yyyy"127msgid "MMMM yyyy"
128msgstr ""128msgstr ""
129129

Subscribers

People subscribed via source and target branches

to status/vote changes: