Merge lp:~renatofilho/ubuntu-calendar-app/fix-add-guest-search-field into lp:ubuntu-calendar-app
- fix-add-guest-search-field
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Renato Araujo Oliveira Filho |
Proposed branch: | lp:~renatofilho/ubuntu-calendar-app/fix-add-guest-search-field |
Merge into: | lp:ubuntu-calendar-app |
Prerequisite: | lp:~renatofilho/ubuntu-calendar-app/sdk-1-3 |
Diff against target: |
343 lines (+117/-43) 3 files modified
ContactChoicePopup.qml (+51/-14) KeyboardRectangle.qml (+1/-0) NewEvent.qml (+65/-29) |
To merge this branch: | bzr merge lp:~renatofilho/ubuntu-calendar-app/fix-add-guest-search-field |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jenkins Bot | continuous-integration | Needs Fixing | |
Ubuntu Calendar Developers | Pending | ||
Review via email: mp+284121@code.launchpad.net |
Commit message
Auto-focus search textfield when adding a guest.
Make sure that the popover stay visible when the keyboard appears.
Disabled auto-prediction for search field.
Description of the change
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
- 749. By Renato Araujo Oliveira Filho
-
Use New ListItem API for guest list.
Update swipe actions to work using the ListItem.
leadingActions
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:749
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 750. By Renato Araujo Oliveira Filho
-
Merged: ~renatofilho/
ubuntu- calendar- app/sdk- 1-3 - 751. By Renato Araujo Oliveira Filho
-
Make sure that guest list still visible after the VKB appears.
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:750
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:751
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 752. By Renato Araujo Oliveira Filho
-
Show a contact entry for each emailAddress in contact selection.
Does not allow select contacts with empty e-mail. - 753. By Renato Araujo Oliveira Filho
-
Merged: ~renatofilho/
ubuntu- calendar- app/sdk- 1-3
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:753
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 754. By Renato Araujo Oliveira Filho
-
Trunk merged.
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:754
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:754
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
it was merged in another MR.
Unmerged revisions
- 754. By Renato Araujo Oliveira Filho
-
Trunk merged.
Preview Diff
1 | === modified file 'ContactChoicePopup.qml' | |||
2 | --- ContactChoicePopup.qml 2016-01-29 14:35:14 +0000 | |||
3 | +++ ContactChoicePopup.qml 2016-02-10 13:30:08 +0000 | |||
4 | @@ -29,7 +29,7 @@ | |||
5 | 29 | id: root | 29 | id: root |
6 | 30 | objectName: "contactPopover" | 30 | objectName: "contactPopover" |
7 | 31 | 31 | ||
9 | 32 | signal contactSelected(var contact); | 32 | signal contactSelected(var contact, string emailAddress); |
10 | 33 | 33 | ||
11 | 34 | Label { | 34 | Label { |
12 | 35 | id: noContact | 35 | id: noContact |
13 | @@ -40,24 +40,27 @@ | |||
14 | 40 | 40 | ||
15 | 41 | UnionFilter { | 41 | UnionFilter { |
16 | 42 | id: filter | 42 | id: filter |
17 | 43 | |||
18 | 44 | property string searchString: "" | ||
19 | 45 | |||
20 | 43 | filters: [ | 46 | filters: [ |
21 | 44 | DetailFilter{ | 47 | DetailFilter{ |
22 | 45 | detail: ContactDetail.Name | 48 | detail: ContactDetail.Name |
23 | 46 | field: Name.FirstName | 49 | field: Name.FirstName |
24 | 47 | matchFlags: Filter.MatchContains | 50 | matchFlags: Filter.MatchContains |
26 | 48 | value: searchBox.text | 51 | value: filter.searchString |
27 | 49 | }, | 52 | }, |
28 | 50 | DetailFilter{ | 53 | DetailFilter{ |
29 | 51 | detail: ContactDetail.Name | 54 | detail: ContactDetail.Name |
30 | 52 | field: Name.LastName | 55 | field: Name.LastName |
31 | 53 | matchFlags: Filter.MatchContains | 56 | matchFlags: Filter.MatchContains |
33 | 54 | value: searchBox.text | 57 | value: filter.searchString |
34 | 55 | }, | 58 | }, |
35 | 56 | DetailFilter{ | 59 | DetailFilter{ |
36 | 57 | detail: ContactDetail.DisplayLabel | 60 | detail: ContactDetail.DisplayLabel |
37 | 58 | field: DisplayLabel.Label | 61 | field: DisplayLabel.Label |
38 | 59 | matchFlags: Filter.MatchContains | 62 | matchFlags: Filter.MatchContains |
40 | 60 | value: searchBox.text | 63 | value: filter.searchString |
41 | 61 | } | 64 | } |
42 | 62 | ] | 65 | ] |
43 | 63 | } | 66 | } |
44 | @@ -69,6 +72,16 @@ | |||
45 | 69 | autoUpdate: true | 72 | autoUpdate: true |
46 | 70 | } | 73 | } |
47 | 71 | 74 | ||
48 | 75 | Timer { | ||
49 | 76 | id: idleSearch | ||
50 | 77 | |||
51 | 78 | interval: 500 | ||
52 | 79 | repeat: false | ||
53 | 80 | onTriggered: { | ||
54 | 81 | filter.searchString = searchBox.text | ||
55 | 82 | } | ||
56 | 83 | } | ||
57 | 84 | |||
58 | 72 | Column { | 85 | Column { |
59 | 73 | anchors.top: parent.top | 86 | anchors.top: parent.top |
60 | 74 | anchors.left: parent.left | 87 | anchors.left: parent.left |
61 | @@ -81,12 +94,16 @@ | |||
62 | 81 | focus: true | 94 | focus: true |
63 | 82 | width: parent.width | 95 | width: parent.width |
64 | 83 | placeholderText: i18n.tr("Search contact") | 96 | placeholderText: i18n.tr("Search contact") |
65 | 97 | inputMethodHints: Qt.ImhNoPredictiveText | ||
66 | 84 | primaryItem: Icon { | 98 | primaryItem: Icon { |
67 | 85 | height: parent.height*0.5 | 99 | height: parent.height*0.5 |
68 | 86 | width: parent.height*0.5 | 100 | width: parent.height*0.5 |
69 | 87 | anchors.verticalCenter: parent.verticalCenter | 101 | anchors.verticalCenter: parent.verticalCenter |
70 | 88 | name:"find" | 102 | name:"find" |
72 | 89 | } | 103 | } |
73 | 104 | onTextChanged: { | ||
74 | 105 | idleSearch.restart() | ||
75 | 106 | } | ||
76 | 90 | } | 107 | } |
77 | 91 | 108 | ||
78 | 92 | ListView { | 109 | ListView { |
79 | @@ -96,17 +113,37 @@ | |||
80 | 96 | model: contactModel | 113 | model: contactModel |
81 | 97 | height: units.gu(15) | 114 | height: units.gu(15) |
82 | 98 | clip: true | 115 | clip: true |
92 | 99 | delegate: Standard{ | 116 | delegate: Column { |
93 | 100 | objectName: "contactPopoverList%1".arg(index) | 117 | width: contactList.width |
94 | 101 | property var item: contactModel.contacts[index] | 118 | Repeater { |
95 | 102 | height: units.gu(4) | 119 | anchors { |
96 | 103 | text: item ? item.displayLabel.label : "" | 120 | left: parent.left |
97 | 104 | 121 | right: parent.right | |
98 | 105 | onClicked: { | 122 | } |
99 | 106 | root.contactSelected(item); | 123 | height: childrenRect.height |
100 | 107 | onClicked: PopupUtils.close(root) | 124 | |
101 | 125 | model: Math.max(1, contact.emails.length) | ||
102 | 126 | delegate: ListItem { | ||
103 | 127 | property string emailAddress: contact.emails.length > index ? contact.emails[index].emailAddress : "" | ||
104 | 128 | |||
105 | 129 | opacity: emailAddress.length > 0 ? 1.0 : 0.3 | ||
106 | 130 | width: contactList.width | ||
107 | 131 | objectName: "contactPopoverList%1".arg(index) | ||
108 | 132 | ListItemLayout { | ||
109 | 133 | title.text: contact.displayLabel.label | ||
110 | 134 | subtitle.text: emailAddress | ||
111 | 135 | } | ||
112 | 136 | onClicked: { | ||
113 | 137 | if (emailAddress.length > 0) { | ||
114 | 138 | root.contactSelected(contact, emailAddress); | ||
115 | 139 | onClicked: PopupUtils.close(root) | ||
116 | 140 | } | ||
117 | 141 | } | ||
118 | 142 | } | ||
119 | 108 | } | 143 | } |
120 | 109 | } | 144 | } |
121 | 110 | } | 145 | } |
122 | 111 | } | 146 | } |
123 | 147 | |||
124 | 148 | Component.onCompleted: searchBox.forceActiveFocus() | ||
125 | 112 | } | 149 | } |
126 | 113 | 150 | ||
127 | === modified file 'KeyboardRectangle.qml' | |||
128 | --- KeyboardRectangle.qml 2016-01-25 13:20:32 +0000 | |||
129 | +++ KeyboardRectangle.qml 2016-02-10 13:30:08 +0000 | |||
130 | @@ -20,6 +20,7 @@ | |||
131 | 20 | 20 | ||
132 | 21 | Item { | 21 | Item { |
133 | 22 | id: keyboardRect | 22 | id: keyboardRect |
134 | 23 | |||
135 | 23 | anchors.left: parent.left | 24 | anchors.left: parent.left |
136 | 24 | anchors.right: parent.right | 25 | anchors.right: parent.right |
137 | 25 | anchors.bottom: parent.bottom | 26 | anchors.bottom: parent.bottom |
138 | 26 | 27 | ||
139 | === modified file 'NewEvent.qml' | |||
140 | --- NewEvent.qml 2016-02-02 22:54:03 +0000 | |||
141 | +++ NewEvent.qml 2016-02-10 13:30:08 +0000 | |||
142 | @@ -20,7 +20,7 @@ | |||
143 | 20 | import QtOrganizer 5.0 | 20 | import QtOrganizer 5.0 |
144 | 21 | import Ubuntu.Components 1.3 | 21 | import Ubuntu.Components 1.3 |
145 | 22 | import Ubuntu.Components.Popups 1.0 | 22 | import Ubuntu.Components.Popups 1.0 |
147 | 23 | import Ubuntu.Components.ListItems 1.0 as ListItem | 23 | import Ubuntu.Components.ListItems 1.0 as ListItems |
148 | 24 | import Ubuntu.Components.Themes.Ambiance 1.0 | 24 | import Ubuntu.Components.Themes.Ambiance 1.0 |
149 | 25 | import Ubuntu.Components.Pickers 1.0 | 25 | import Ubuntu.Components.Pickers 1.0 |
150 | 26 | import QtOrganizer 5.0 | 26 | import QtOrganizer 5.0 |
151 | @@ -411,7 +411,7 @@ | |||
152 | 411 | } | 411 | } |
153 | 412 | } | 412 | } |
154 | 413 | 413 | ||
156 | 414 | ListItem.Standard { | 414 | ListItems.Standard { |
157 | 415 | anchors { | 415 | anchors { |
158 | 416 | left: parent.left | 416 | left: parent.left |
159 | 417 | right: parent.right | 417 | right: parent.right |
160 | @@ -426,13 +426,13 @@ | |||
161 | 426 | } | 426 | } |
162 | 427 | } | 427 | } |
163 | 428 | 428 | ||
165 | 429 | ListItem.ThinDivider {} | 429 | ListItems.ThinDivider {} |
166 | 430 | 430 | ||
167 | 431 | Column { | 431 | Column { |
168 | 432 | width: parent.width | 432 | width: parent.width |
169 | 433 | spacing: units.gu(1) | 433 | spacing: units.gu(1) |
170 | 434 | 434 | ||
172 | 435 | ListItem.Header{ | 435 | ListItems.Header{ |
173 | 436 | text: i18n.tr("Event Details") | 436 | text: i18n.tr("Event Details") |
174 | 437 | } | 437 | } |
175 | 438 | 438 | ||
176 | @@ -496,7 +496,7 @@ | |||
177 | 496 | width: parent.width | 496 | width: parent.width |
178 | 497 | spacing: units.gu(1) | 497 | spacing: units.gu(1) |
179 | 498 | 498 | ||
181 | 499 | ListItem.Header { | 499 | ListItems.Header { |
182 | 500 | text: i18n.tr("Calendar") | 500 | text: i18n.tr("Calendar") |
183 | 501 | } | 501 | } |
184 | 502 | 502 | ||
185 | @@ -534,29 +534,51 @@ | |||
186 | 534 | width: parent.width | 534 | width: parent.width |
187 | 535 | spacing: units.gu(1) | 535 | spacing: units.gu(1) |
188 | 536 | 536 | ||
190 | 537 | ListItem.Header { | 537 | ListItems.Header { |
191 | 538 | text: i18n.tr("Guests") | 538 | text: i18n.tr("Guests") |
192 | 539 | } | 539 | } |
193 | 540 | 540 | ||
194 | 541 | Button{ | 541 | Button{ |
195 | 542 | id: addGuestButton | ||
196 | 543 | objectName: "addGuestButton" | ||
197 | 544 | |||
198 | 545 | property var contactsPopup: null | ||
199 | 546 | |||
200 | 542 | text: i18n.tr("Add Guest") | 547 | text: i18n.tr("Add Guest") |
201 | 543 | objectName: "addGuestButton" | ||
202 | 544 | |||
203 | 545 | anchors { | 548 | anchors { |
204 | 546 | left: parent.left | 549 | left: parent.left |
205 | 547 | right: parent.right | 550 | right: parent.right |
206 | 548 | margins: units.gu(2) | 551 | margins: units.gu(2) |
207 | 549 | } | 552 | } |
208 | 550 | 553 | ||
209 | 554 | // WORKAROUND: causes the popover to follow the buttom position when keyboard appears | ||
210 | 555 | Connections { | ||
211 | 556 | target: keyboard | ||
212 | 557 | onHeightChanged: { | ||
213 | 558 | if (addGuestButton.contactsPopup) { | ||
214 | 559 | addGuestButton.contactsPopup.caller = null | ||
215 | 560 | addGuestButton.contactsPopup.caller = addGuestButton | ||
216 | 561 | } | ||
217 | 562 | } | ||
218 | 563 | } | ||
219 | 564 | |||
220 | 551 | onClicked: { | 565 | onClicked: { |
225 | 552 | var popup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), contactList); | 566 | if (contactsPopup) |
226 | 553 | popup.contactSelected.connect( function(contact) { | 567 | return |
227 | 554 | var t = internal.contactToAttendee(contact); | 568 | |
228 | 555 | if( !internal.isContactAlreadyAdded(contact) ) { | 569 | flickable.makeMeVisible(addGuestButton) |
229 | 570 | contactsPopup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), addGuestButton); | ||
230 | 571 | contactsPopup.contactSelected.connect( function(contact, emailAddress) { | ||
231 | 572 | if(!internal.isContactAlreadyAdded(contact, emailAddress) ) { | ||
232 | 573 | var t = internal.contactToAttendee(contact, emailAddress); | ||
233 | 556 | contactModel.append(t); | 574 | contactModel.append(t); |
234 | 557 | contactList.array.push(t); | 575 | contactList.array.push(t); |
235 | 558 | } | 576 | } |
236 | 577 | |||
237 | 559 | }); | 578 | }); |
238 | 579 | contactsPopup.Component.onDestruction.connect( function() { | ||
239 | 580 | addGuestButton.contactsPopup = null | ||
240 | 581 | }) | ||
241 | 560 | } | 582 | } |
242 | 561 | } | 583 | } |
243 | 562 | 584 | ||
244 | @@ -585,27 +607,35 @@ | |||
245 | 585 | 607 | ||
246 | 586 | Repeater{ | 608 | Repeater{ |
247 | 587 | model: contactModel | 609 | model: contactModel |
249 | 588 | delegate: ListItem.Standard { | 610 | delegate: ListItem { |
250 | 589 | objectName: "eventGuest%1".arg(index) | 611 | objectName: "eventGuest%1".arg(index) |
257 | 590 | height: units.gu(4) | 612 | |
258 | 591 | text: name | 613 | ListItemLayout { |
259 | 592 | removable: true | 614 | title.text: name |
260 | 593 | onItemRemoved: { | 615 | subtitle.text: emailAddress |
261 | 594 | contactList.array.splice(index, 1) | 616 | } |
262 | 595 | contactModel.remove(index) | 617 | |
263 | 618 | leadingActions: ListItemActions { | ||
264 | 619 | actions: Action { | ||
265 | 620 | iconName: "delete" | ||
266 | 621 | onTriggered: { | ||
267 | 622 | contactList.array.splice(index, 1) | ||
268 | 623 | contactModel.remove(index) | ||
269 | 624 | } | ||
270 | 625 | } | ||
271 | 596 | } | 626 | } |
272 | 597 | } | 627 | } |
273 | 598 | } | 628 | } |
274 | 599 | } | 629 | } |
275 | 600 | } | 630 | } |
276 | 601 | 631 | ||
278 | 602 | ListItem.ThinDivider { | 632 | ListItems.ThinDivider { |
279 | 603 | visible: event.itemType === Type.Event | 633 | visible: event.itemType === Type.Event |
280 | 604 | } | 634 | } |
281 | 605 | 635 | ||
282 | 606 | } | 636 | } |
283 | 607 | 637 | ||
285 | 608 | ListItem.Subtitled{ | 638 | ListItems.Subtitled{ |
286 | 609 | id:thisHappens | 639 | id:thisHappens |
287 | 610 | objectName :"thisHappens" | 640 | objectName :"thisHappens" |
288 | 611 | 641 | ||
289 | @@ -621,11 +651,11 @@ | |||
290 | 621 | onClicked: pageStack.push(Qt.resolvedUrl("EventRepetition.qml"),{"eventRoot": root,"isEdit":isEdit}); | 651 | onClicked: pageStack.push(Qt.resolvedUrl("EventRepetition.qml"),{"eventRoot": root,"isEdit":isEdit}); |
291 | 622 | } | 652 | } |
292 | 623 | 653 | ||
294 | 624 | ListItem.ThinDivider { | 654 | ListItems.ThinDivider { |
295 | 625 | visible: event.itemType === Type.Event | 655 | visible: event.itemType === Type.Event |
296 | 626 | } | 656 | } |
297 | 627 | 657 | ||
299 | 628 | ListItem.Subtitled{ | 658 | ListItems.Subtitled{ |
300 | 629 | id:eventReminder | 659 | id:eventReminder |
301 | 630 | objectName : "eventReminder" | 660 | objectName : "eventReminder" |
302 | 631 | 661 | ||
303 | @@ -658,7 +688,7 @@ | |||
304 | 658 | "eventTitle": titleEdit.text}) | 688 | "eventTitle": titleEdit.text}) |
305 | 659 | } | 689 | } |
306 | 660 | 690 | ||
308 | 661 | ListItem.ThinDivider {} | 691 | ListItems.ThinDivider {} |
309 | 662 | } | 692 | } |
310 | 663 | } | 693 | } |
311 | 664 | // used to keep the field visible when the keyboard appear or dismiss | 694 | // used to keep the field visible when the keyboard appear or dismiss |
312 | @@ -685,20 +715,26 @@ | |||
313 | 685 | messageEdit.focus = false | 715 | messageEdit.focus = false |
314 | 686 | } | 716 | } |
315 | 687 | 717 | ||
317 | 688 | function isContactAlreadyAdded(contact) { | 718 | function isContactAlreadyAdded(contact, emailAddress) { |
318 | 689 | for(var i=0; i < contactList.array.length ; ++i) { | 719 | for(var i=0; i < contactList.array.length ; ++i) { |
319 | 690 | var attendee = contactList.array[i]; | 720 | var attendee = contactList.array[i]; |
322 | 691 | if( attendee.attendeeId === contact.contactId) { | 721 | if (emailAddress.length > 0) { |
323 | 692 | return true; | 722 | if (attendee.emailAddress === emailAddress) { |
324 | 723 | return true; | ||
325 | 724 | } | ||
326 | 725 | } else { | ||
327 | 726 | if (attendee.attendeeId === contact.contactId) { | ||
328 | 727 | return true | ||
329 | 728 | } | ||
330 | 693 | } | 729 | } |
331 | 694 | } | 730 | } |
332 | 695 | return false; | 731 | return false; |
333 | 696 | } | 732 | } |
334 | 697 | 733 | ||
336 | 698 | function contactToAttendee(contact) { | 734 | function contactToAttendee(contact, emailAddress) { |
337 | 699 | var attendee = Qt.createQmlObject("import QtOrganizer 5.0; EventAttendee{}", event, "NewEvent.qml"); | 735 | var attendee = Qt.createQmlObject("import QtOrganizer 5.0; EventAttendee{}", event, "NewEvent.qml"); |
338 | 700 | attendee.name = contact.displayLabel.label | 736 | attendee.name = contact.displayLabel.label |
340 | 701 | attendee.emailAddress = contact.email.emailAddress; | 737 | attendee.emailAddress = emailAddress; |
341 | 702 | attendee.attendeeId = contact.contactId; | 738 | attendee.attendeeId = contact.contactId; |
342 | 703 | return attendee; | 739 | return attendee; |
343 | 704 | } | 740 | } |
FAILED: Continuous integration, rev:748 /core-apps- jenkins. ubuntu. com/job/ run-ap- tests-ci/ 192/ /core-apps- jenkins. ubuntu. com/job/ generic- update- mp/478/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /core-apps- jenkins. ubuntu. com/job/ run-ap- tests-ci/ 192/rebuild
https:/