Merge lp:~renatofilho/address-book-app/release-2014-06-27 into lp:address-book-app
- release-2014-06-27
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Gustavo Pichorim Boiko | ||||
Approved revision: | 196 | ||||
Merged at revision: | 215 | ||||
Proposed branch: | lp:~renatofilho/address-book-app/release-2014-06-27 | ||||
Merge into: | lp:address-book-app | ||||
Diff against target: |
1436 lines (+681/-178) 18 files modified
click/CMakeLists.txt (+4/-0) debian/address-book-app.install (+1/-0) debian/control (+5/-3) po/address-book-app.pot (+99/-36) src/app/addressbookapp.cpp (+7/-1) src/imports/ContactEdit/ContactDetailAvatarEditor.qml (+1/-1) src/imports/ContactList/CMakeLists.txt (+1/-0) src/imports/ContactList/ContactListPage.qml (+33/-12) src/imports/ContactList/VCardImportDialog.qml (+94/-0) src/imports/MainWindow.qml (+14/-0) src/imports/Ubuntu/Contacts/CMakeLists.txt (+1/-0) src/imports/Ubuntu/Contacts/ContactAvatar.qml (+1/-1) src/imports/Ubuntu/Contacts/ContactDelegate.qml (+84/-10) src/imports/Ubuntu/Contacts/ContactListView.qml (+149/-32) src/imports/Ubuntu/Contacts/ContactSimpleListView.qml (+1/-80) src/imports/Ubuntu/Contacts/Contacts.js (+2/-2) src/imports/Ubuntu/Contacts/MostCalledModel.qml (+183/-0) src/imports/Ubuntu/Contacts/qmldir (+1/-0) |
||||
To merge this branch: | bzr merge lp:~renatofilho/address-book-app/release-2014-06-27 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Gustavo Pichorim Boiko (community) | Approve | ||
Review via email: mp+224809@code.launchpad.net |
Commit message
* Updated pot file.
* Implemented frequently called list.
* Implemented vcard import.
* Search contacts by phone number and name.
Description of the change
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
Gustavo Pichorim Boiko (boiko) wrote : | # |
Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
Yes
Did CI run pass? If not, please explain why.
Yes
Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes
Code looks good and works as expected!
- 197. By Renato Araujo Oliveira Filho
-
Fixed MostCalled list visibility.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:196
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'click/CMakeLists.txt' |
2 | --- click/CMakeLists.txt 2014-03-12 01:34:34 +0000 |
3 | +++ click/CMakeLists.txt 2014-06-27 21:27:44 +0000 |
4 | @@ -9,4 +9,8 @@ |
5 | DESTINATION ${CMAKE_INSTALL_PREFIX}) |
6 | install(FILES address-book-content.json |
7 | DESTINATION ${CMAKE_INSTALL_PREFIX}) |
8 | +else(CLICK_MODE) |
9 | + install(FILES address-book-content.json |
10 | + DESTINATION ${CMAKE_INSTALL_DATADIR}/content-hub/peers |
11 | + RENAME address-book-app) |
12 | endif(CLICK_MODE) |
13 | |
14 | === modified file 'debian/address-book-app.install' |
15 | --- debian/address-book-app.install 2014-02-10 21:09:43 +0000 |
16 | +++ debian/address-book-app.install 2014-06-27 21:27:44 +0000 |
17 | @@ -3,4 +3,5 @@ |
18 | usr/share/address-book-app/imports |
19 | usr/share/applications/address-book-app.desktop |
20 | usr/share/url-dispatcher/urls/ |
21 | +usr/share/content-hub/peers/address-book-app |
22 | usr/share/locale/*/LC_MESSAGES/address-book-app.mo |
23 | |
24 | === modified file 'debian/control' |
25 | --- debian/control 2014-06-11 21:25:08 +0000 |
26 | +++ debian/control 2014-06-27 21:27:44 +0000 |
27 | @@ -25,12 +25,14 @@ |
28 | libqt5versit5, |
29 | qmlscene, |
30 | qtcontact5-galera, |
31 | + qtdeclarative5-qtcontacts-plugin, |
32 | + qtdeclarative5-qtquick2-plugin, |
33 | qtdeclarative5-ubuntu-contacts0.1 (= ${binary:Version}), |
34 | - qtdeclarative5-ubuntu-telephony-phonenumber0.1, |
35 | qtdeclarative5-ubuntu-content0.1, |
36 | + qtdeclarative5-ubuntu-history0.1, |
37 | qtdeclarative5-ubuntu-keyboard-extensions0.1, |
38 | - qtdeclarative5-qtcontacts-plugin, |
39 | - qtdeclarative5-qtquick2-plugin, |
40 | + qtdeclarative5-ubuntu-telephony-phonenumber0.1, |
41 | + qtdeclarative5-ubuntu-telephony0.1, |
42 | ${misc:Depends}, |
43 | ${shlibs:Depends}, |
44 | Description: Address Book application |
45 | |
46 | === modified file 'po/address-book-app.pot' |
47 | --- po/address-book-app.pot 2014-05-13 18:53:02 +0000 |
48 | +++ po/address-book-app.pot 2014-06-27 21:27:44 +0000 |
49 | @@ -8,7 +8,7 @@ |
50 | msgstr "" |
51 | "Project-Id-Version: address-book-app\n" |
52 | "Report-Msgid-Bugs-To: \n" |
53 | -"POT-Creation-Date: 2014-05-13 15:51-0300\n" |
54 | +"POT-Creation-Date: 2014-06-27 09:54-0300\n" |
55 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
56 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
57 | "Language-Team: LANGUAGE <LL@li.org>\n" |
58 | @@ -17,16 +17,22 @@ |
59 | "Content-Type: text/plain; charset=CHARSET\n" |
60 | "Content-Transfer-Encoding: 8bit\n" |
61 | |
62 | -#: src/imports/ContactList/ContactListPage.qml:193 |
63 | -msgid "Add" |
64 | -msgstr "" |
65 | - |
66 | +#: src/imports/ContactList/VCardImportDialog.qml:72 |
67 | +#, qt-format |
68 | +msgid "%1 vCards imported" |
69 | +msgstr "" |
70 | + |
71 | +#: src/imports/ContactEdit/ContactEditor.qml:322 |
72 | +msgid "Add Field" |
73 | +msgstr "" |
74 | + |
75 | +#: src/imports/ContactEdit/AddFieldDialog.qml:59 |
76 | #: src/imports/ContactEdit/ContactDetailAddressesEditor.qml:23 |
77 | #: src/imports/ContactView/ContactDetailAddressesView.qml:24 |
78 | msgid "Address" |
79 | msgstr "" |
80 | |
81 | -#: src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml:73 |
82 | +#: src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml:77 |
83 | #: src/imports/ContactView/ContactDetailSyncTargetView.qml:48 |
84 | msgid "Addressbook" |
85 | msgstr "" |
86 | @@ -35,22 +41,39 @@ |
87 | msgid "Aim" |
88 | msgstr "" |
89 | |
90 | -#: src/imports/Ubuntu/Contacts/ContactListView.qml:66 |
91 | +#: src/imports/Ubuntu/Contacts/ContactListView.qml:316 |
92 | msgid "All" |
93 | msgstr "" |
94 | |
95 | -#: src/imports/ContactEdit/ContactEditor.qml:300 |
96 | -#: src/imports/ContactEdit/EditToolbar.qml:42 |
97 | +#: src/imports/Common/RemoveContactsDialog.qml:51 |
98 | +msgid "Are you sure that you want to remove all selected contacts?" |
99 | +msgstr "" |
100 | + |
101 | +#: src/imports/Common/RemoveContactsDialog.qml:49 |
102 | +msgid "Are you sure that you want to remove this contact?" |
103 | +msgstr "" |
104 | + |
105 | +#: src/imports/ContactEdit/AddFieldDialog.qml:133 |
106 | +#: src/imports/ContactEdit/ContactEditor.qml:372 |
107 | +#: src/imports/ContactList/ContactListPage.qml:324 |
108 | #: src/imports/Ubuntu/Contacts/DialogButtons.qml:37 |
109 | msgid "Cancel" |
110 | msgstr "" |
111 | |
112 | -#: src/imports/ContactEdit/ContactFetchError.qml:26 |
113 | +#: src/imports/ContactList/ContactListPage.qml:252 |
114 | +msgid "Cancel selection" |
115 | +msgstr "" |
116 | + |
117 | +#: src/imports/ContactList/VCardImportDialog.qml:80 |
118 | +msgid "Close" |
119 | +msgstr "" |
120 | + |
121 | +#: src/imports/ContactView/ContactFetchError.qml:26 |
122 | msgid "Contact not found" |
123 | msgstr "" |
124 | |
125 | #: data/address-book-app.desktop.in:6 data/address-book-app.desktop.in:7 |
126 | -#: src/imports/ContactList/ContactListPage.qml:57 |
127 | +#: src/imports/ContactList/ContactListPage.qml:75 |
128 | msgid "Contacts" |
129 | msgstr "" |
130 | |
131 | @@ -62,21 +85,22 @@ |
132 | msgid "Country" |
133 | msgstr "" |
134 | |
135 | -#: src/imports/ContactList/ContactListPage.qml:83 |
136 | -#: src/imports/ContactView/ContactView.qml:181 |
137 | -#: src/imports/Ubuntu/Contacts/ContactSimpleListView.qml:288 |
138 | +#: src/imports/ContactEdit/ContactEditor.qml:337 |
139 | +#: src/imports/ContactList/ContactListPage.qml:148 |
140 | +#: src/imports/ContactList/ContactListPage.qml:277 |
141 | msgid "Delete" |
142 | msgstr "" |
143 | |
144 | -#: src/imports/ContactEdit/EditToolbar.qml:57 |
145 | #: src/imports/Ubuntu/Contacts/DialogButtons.qml:53 |
146 | msgid "Done" |
147 | msgstr "" |
148 | |
149 | -#: src/imports/ContactView/ContactView.qml:193 |
150 | +#: src/imports/ContactEdit/ContactEditor.qml:141 |
151 | +#: src/imports/ContactView/ContactView.qml:219 |
152 | msgid "Edit" |
153 | msgstr "" |
154 | |
155 | +#: src/imports/ContactEdit/AddFieldDialog.qml:57 |
156 | #: src/imports/ContactEdit/ContactDetailEmailsEditor.qml:23 |
157 | #: src/imports/ContactView/ContactDetailEmailsView.qml:23 |
158 | #: src/imports/ContactView/ContactDetailEmailsView.qml:26 |
159 | @@ -95,23 +119,27 @@ |
160 | msgid "Enter an email address" |
161 | msgstr "" |
162 | |
163 | -#: src/imports/ContactEdit/ContactFetchError.qml:25 |
164 | -#: src/imports/MainWindow.qml:94 |
165 | +#: src/imports/ContactView/ContactFetchError.qml:25 |
166 | +#: src/imports/MainWindow.qml:98 |
167 | msgid "Error" |
168 | msgstr "" |
169 | |
170 | -#: src/imports/ContactView/ContactDetailPhoneNumbersView.qml:33 |
171 | +#: src/imports/ContactView/ContactView.qml:195 |
172 | msgid "Favorite" |
173 | msgstr "" |
174 | |
175 | -#: src/imports/Ubuntu/Contacts/ContactListView.qml:93 |
176 | +#: src/imports/Ubuntu/Contacts/ContactListView.qml:348 |
177 | msgid "Favourites" |
178 | msgstr "" |
179 | |
180 | -#: src/imports/ContactEdit/ContactDetailNameEditor.qml:81 |
181 | +#: src/imports/ContactEdit/ContactDetailNameEditor.qml:83 |
182 | msgid "First name" |
183 | msgstr "" |
184 | |
185 | +#: src/imports/Ubuntu/Contacts/ContactListView.qml:427 |
186 | +msgid "Frequently called" |
187 | +msgstr "" |
188 | + |
189 | #: src/imports/Common/ContactDetailGroupWithTypeBase.qml:116 |
190 | #: src/imports/Ubuntu/Contacts/ContactDetailPhoneNumberTypeModel.qml:94 |
191 | msgid "Home" |
192 | @@ -125,19 +153,27 @@ |
193 | msgid "IM" |
194 | msgstr "" |
195 | |
196 | +#: src/imports/ContactList/VCardImportDialog.qml:71 |
197 | +msgid "Import vCards" |
198 | +msgstr "" |
199 | + |
200 | +#: src/imports/ContactList/VCardImportDialog.qml:72 |
201 | +msgid "Importing..." |
202 | +msgstr "" |
203 | + |
204 | #: src/imports/Ubuntu/Contacts/ContactDetailOnlineAccountTypeModel.qml:64 |
205 | msgid "Jabber" |
206 | msgstr "" |
207 | |
208 | -#: src/imports/ContactEdit/ContactDetailNameEditor.qml:81 |
209 | +#: src/imports/ContactEdit/ContactDetailNameEditor.qml:83 |
210 | msgid "Last name" |
211 | msgstr "" |
212 | |
213 | -#: src/imports/ContactEdit/ContactDetailAvatarEditor.qml:85 |
214 | +#: src/imports/ContactEdit/AvatarImport.qml:71 |
215 | msgid "Loading" |
216 | msgstr "" |
217 | |
218 | -#: src/imports/ContactList/ContactListPage.qml:163 |
219 | +#: src/imports/ContactList/ContactListPage.qml:242 |
220 | msgid "Loading..." |
221 | msgstr "" |
222 | |
223 | @@ -153,14 +189,23 @@ |
224 | msgid "Mobile" |
225 | msgstr "" |
226 | |
227 | -#: src/imports/ContactEdit/TextInputDetail.qml:46 |
228 | +#: src/imports/Common/RemoveContactsDialog.qml:44 |
229 | +msgid "Multiple contacts" |
230 | +msgstr "" |
231 | + |
232 | +#: src/imports/ContactEdit/TextInputDetail.qml:77 |
233 | msgid "Next" |
234 | msgstr "" |
235 | |
236 | +#: src/imports/Common/RemoveContactsDialog.qml:74 |
237 | #: src/imports/ContactList/OnlineAccountsMessage.qml:48 |
238 | msgid "No" |
239 | msgstr "" |
240 | |
241 | +#: src/imports/Common/RemoveContactsDialog.qml:40 |
242 | +msgid "No contact selected." |
243 | +msgstr "" |
244 | + |
245 | #: src/imports/ContactEdit/ContactDetailOrganizationsEditor.qml:30 |
246 | msgid "Organization" |
247 | msgstr "" |
248 | @@ -170,6 +215,7 @@ |
249 | msgid "Other" |
250 | msgstr "" |
251 | |
252 | +#: src/imports/ContactEdit/AddFieldDialog.qml:55 |
253 | #: src/imports/ContactEdit/ContactDetailPhoneNumbersEditor.qml:24 |
254 | #: src/imports/ContactView/ContactDetailPhoneNumbersView.qml:30 |
255 | msgid "Phone" |
256 | @@ -179,6 +225,10 @@ |
257 | msgid "Post code" |
258 | msgstr "" |
259 | |
260 | +#: src/imports/ContactEdit/AddFieldDialog.qml:63 |
261 | +msgid "Professional Details" |
262 | +msgstr "" |
263 | + |
264 | #: src/imports/ContactEdit/ContactDetailOrganizationsEditor.qml:23 |
265 | #: src/imports/ContactView/ContactDetailOrganizationsView.qml:27 |
266 | msgid "Professional details" |
267 | @@ -192,19 +242,35 @@ |
268 | msgid "Role" |
269 | msgstr "" |
270 | |
271 | -#: src/imports/ContactEdit/ContactEditor.qml:295 |
272 | +#: src/imports/ContactEdit/ContactEditor.qml:385 |
273 | msgid "Save" |
274 | msgstr "" |
275 | |
276 | -#: src/imports/ContactList/ContactListPage.qml:83 |
277 | -#: src/imports/ContactList/ContactListPage.qml:185 |
278 | +#: src/imports/ContactList/ContactListPage.qml:302 |
279 | +msgid "Search" |
280 | +msgstr "" |
281 | + |
282 | +#: src/imports/ContactList/ContactListPage.qml:277 |
283 | msgid "Select" |
284 | msgstr "" |
285 | |
286 | +#: src/imports/ContactList/ContactListPage.qml:261 |
287 | +msgid "Select All" |
288 | +msgstr "" |
289 | + |
290 | +#: src/imports/ContactList/ContactListPage.qml:75 |
291 | +msgid "Select Contacts" |
292 | +msgstr "" |
293 | + |
294 | +#: src/imports/ContactEdit/AddFieldDialog.qml:116 |
295 | +msgid "Select a field" |
296 | +msgstr "" |
297 | + |
298 | #: src/imports/Ubuntu/Contacts/ContactDetailOnlineAccountTypeModel.qml:67 |
299 | msgid "Skype" |
300 | msgstr "" |
301 | |
302 | +#: src/imports/ContactEdit/AddFieldDialog.qml:61 |
303 | #: src/imports/ContactView/ContactDetailOnlineAccountsView.qml:27 |
304 | msgid "Social" |
305 | msgstr "" |
306 | @@ -213,15 +279,15 @@ |
307 | msgid "Street" |
308 | msgstr "" |
309 | |
310 | -#: src/imports/ContactList/ContactListPage.qml:176 |
311 | +#: src/imports/ContactList/ContactListPage.qml:293 |
312 | msgid "Sync" |
313 | msgstr "" |
314 | |
315 | -#: src/imports/ContactList/ContactListPage.qml:176 |
316 | +#: src/imports/ContactList/ContactListPage.qml:293 |
317 | msgid "Syncing" |
318 | msgstr "" |
319 | |
320 | -#: src/imports/ContactList/ContactListPage.qml:163 |
321 | +#: src/imports/ContactList/ContactListPage.qml:242 |
322 | msgid "Syncing..." |
323 | msgstr "" |
324 | |
325 | @@ -235,14 +301,10 @@ |
326 | |
327 | #. TRANSLATORS: This value is used as default value for phone number format, when no coutry code is provided |
328 | #. the supported values can be found in: https://www.iso.org/obp/ui/#search |
329 | -#: src/imports/ContactEdit/TextInputDetail.qml:41 |
330 | +#: src/imports/ContactEdit/TextInputDetail.qml:73 |
331 | msgid "US" |
332 | msgstr "" |
333 | |
334 | -#: src/imports/Ubuntu/Contacts/ContactDetailPickerPhoneNumberDelegate.qml:111 |
335 | -msgid "View contact's profile" |
336 | -msgstr "" |
337 | - |
338 | #: src/imports/Common/ContactDetailGroupWithTypeBase.qml:117 |
339 | #: src/imports/Ubuntu/Contacts/ContactDetailPhoneNumberTypeModel.qml:96 |
340 | msgid "Work" |
341 | @@ -262,6 +324,7 @@ |
342 | msgid "Yahoo" |
343 | msgstr "" |
344 | |
345 | +#: src/imports/Common/RemoveContactsDialog.qml:62 |
346 | #: src/imports/ContactList/OnlineAccountsMessage.qml:36 |
347 | msgid "Yes" |
348 | msgstr "" |
349 | |
350 | === modified file 'src/app/addressbookapp.cpp' |
351 | --- src/app/addressbookapp.cpp 2014-06-11 21:25:08 +0000 |
352 | +++ src/app/addressbookapp.cpp 2014-06-27 21:27:44 +0000 |
353 | @@ -43,6 +43,7 @@ |
354 | << "[addressbook:///contact?id=<contact-id>" |
355 | << "[addressbook:///create?phone=<phone-number>" |
356 | << "[addressbook:///pick?single=<true/false>" |
357 | + << "[addressbook:///importvcard?url=<vcard-file>" |
358 | << "[--fullscreen]" |
359 | << "[--help]" |
360 | << "[-testability]"; |
361 | @@ -297,6 +298,11 @@ |
362 | args << "single"; |
363 | methodsMetaData.insert("pick", args); |
364 | args.clear(); |
365 | + |
366 | + //vcard |
367 | + args << "url"; |
368 | + methodsMetaData.insert("importvcard", args); |
369 | + args.clear(); |
370 | } |
371 | |
372 | QUrlQuery query(url); |
373 | @@ -356,7 +362,7 @@ |
374 | method.invoke(mainView); |
375 | break; |
376 | case 1: |
377 | - method.invoke(mainView, Q_ARG(QVariant, QVariant(args[0].toUtf8()))); |
378 | + method.invoke(mainView, Q_ARG(QVariant, QVariant(args[0]))); |
379 | break; |
380 | case 2: |
381 | method.invoke(mainView, Q_ARG(QVariant, QVariant(args[0].toUtf8())), |
382 | |
383 | === modified file 'src/imports/ContactEdit/ContactDetailAvatarEditor.qml' |
384 | --- src/imports/ContactEdit/ContactDetailAvatarEditor.qml 2014-06-13 19:54:01 +0000 |
385 | +++ src/imports/ContactEdit/ContactDetailAvatarEditor.qml 2014-06-27 21:27:44 +0000 |
386 | @@ -52,7 +52,7 @@ |
387 | |
388 | if (avatarDetail) { |
389 | var avatarValue = avatarDetail.value(Avatar.ImageUrl) |
390 | - if (avatarValue != "") { |
391 | + if (avatarValue && (avatarValue != "")) { |
392 | avatarUrl = avatarValue |
393 | } |
394 | } |
395 | |
396 | === modified file 'src/imports/ContactList/CMakeLists.txt' |
397 | --- src/imports/ContactList/CMakeLists.txt 2014-05-07 13:14:28 +0000 |
398 | +++ src/imports/ContactList/CMakeLists.txt 2014-06-27 21:27:44 +0000 |
399 | @@ -3,6 +3,7 @@ |
400 | ContactExporter.qml |
401 | OnlineAccountsMessage.qml |
402 | PageWithBottomEdge.qml |
403 | + VCardImportDialog.qml |
404 | ) |
405 | |
406 | install(FILES ${CONTACT_LIST_QMLS} |
407 | |
408 | === modified file 'src/imports/ContactList/ContactListPage.qml' |
409 | --- src/imports/ContactList/ContactListPage.qml 2014-06-17 14:25:22 +0000 |
410 | +++ src/imports/ContactList/ContactListPage.qml 2014-06-27 21:27:44 +0000 |
411 | @@ -58,6 +58,20 @@ |
412 | return newContact |
413 | } |
414 | |
415 | + function createContactWithPhoneNumber(phoneNumber) |
416 | + { |
417 | + var newContact = mainPage.createEmptyContact(phoneNumber) |
418 | + //WORKAROUND: SKD changes the page header as soon as the page get created |
419 | + // setting active false will avoid that |
420 | + mainPage.showBottomEdgePage(Qt.resolvedUrl("../ContactEdit/ContactEditor.qml"), |
421 | + {model: contactList.listModel, |
422 | + contact: newContact, |
423 | + active: false, |
424 | + enabled: false, |
425 | + initialFocusSection: "name"}) |
426 | + |
427 | + } |
428 | + |
429 | title: contactList.isInSelectionMode ? i18n.tr("Select Contacts") : i18n.tr("Contacts") |
430 | |
431 | //bottom edge page |
432 | @@ -121,7 +135,7 @@ |
433 | bottom: keyboard.top |
434 | right: parent.right |
435 | } |
436 | - contactNameFilter: searchField.text |
437 | + filterTerm: searchField.text |
438 | detailToPick: ContactDetail.PhoneNumber |
439 | multiSelectionEnabled: true |
440 | multipleSelection: !pickMode || |
441 | @@ -160,6 +174,8 @@ |
442 | } |
443 | } |
444 | |
445 | + onAddContactClicked: mainPage.createContactWithPhoneNumber(label) |
446 | + |
447 | onInfoRequested: { |
448 | mainPage.state = "" |
449 | pageStack.push(Qt.resolvedUrl("../ContactView/ContactView.qml"), |
450 | @@ -343,6 +359,10 @@ |
451 | __customHeaderContents: searchField |
452 | tools: toolbarItemsSearch |
453 | } |
454 | + PropertyChanges { |
455 | + target: contactList |
456 | + showFavourites: false |
457 | + } |
458 | }, |
459 | State { |
460 | name: "selection" |
461 | @@ -388,21 +408,11 @@ |
462 | |
463 | Connections { |
464 | target: pageStack |
465 | + onCreateContactRequested: mainPage.createContactWithPhoneNumber(phoneNumber) |
466 | onContactRequested: { |
467 | pageStack.push(Qt.resolvedUrl("../ContactView/ContactView.qml"), |
468 | {model: contactList.listModel, contactId: contactId}) |
469 | } |
470 | - onCreateContactRequested: { |
471 | - var newContact = mainPage.createEmptyContact(phoneNumber) |
472 | - //WORKAROUND: SKD changes the page header as soon as the page get created |
473 | - // setting active false will avoid that |
474 | - mainPage.showBottomEdgePage(Qt.resolvedUrl("../ContactEdit/ContactEditor.qml"), |
475 | - {model: contactList.listModel, |
476 | - contact: newContact, |
477 | - active: false, |
478 | - enabled: false, |
479 | - initialFocusSection: "name"}) |
480 | - } |
481 | onEditContatRequested: { |
482 | pageStack.push(Qt.resolvedUrl("../ContactView/ContactView.qml"), |
483 | {model: contactList.listModel, |
484 | @@ -412,6 +422,17 @@ |
485 | onContactCreated: { |
486 | mainPage.contactIndex = contact |
487 | } |
488 | + |
489 | + onImportContactRequested: { |
490 | + if (urls.length > 0) { |
491 | + var importDialog = Qt.createQmlObject("VCardImportDialog{}", |
492 | + mainPage, |
493 | + "VCardImportDialog") |
494 | + if (importDialog) { |
495 | + importDialog.importVCards(contactList.listModel, urls) |
496 | + } |
497 | + } |
498 | + } |
499 | } |
500 | |
501 | KeyboardRectangle { |
502 | |
503 | === added file 'src/imports/ContactList/VCardImportDialog.qml' |
504 | --- src/imports/ContactList/VCardImportDialog.qml 1970-01-01 00:00:00 +0000 |
505 | +++ src/imports/ContactList/VCardImportDialog.qml 2014-06-27 21:27:44 +0000 |
506 | @@ -0,0 +1,94 @@ |
507 | +/* |
508 | + * Copyright (C) 2014 Canonical, Ltd. |
509 | + * |
510 | + * This program is free software; you can redistribute it and/or modify |
511 | + * it under the terms of the GNU General Public License as published by |
512 | + * the Free Software Foundation; version 3. |
513 | + * |
514 | + * This program is distributed in the hope that it will be useful, |
515 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
516 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
517 | + * GNU General Public License for more details. |
518 | + * |
519 | + * You should have received a copy of the GNU General Public License |
520 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
521 | + */ |
522 | + |
523 | +import QtQuick 2.2 |
524 | +import QtContacts 5.0 |
525 | +import Ubuntu.Components 0.1 |
526 | +import Ubuntu.Components.Popups 0.1 as Popups |
527 | + |
528 | +Item { |
529 | + id: root |
530 | + |
531 | + property alias model: modelConnections.target |
532 | + property var vcards: [] |
533 | + property var importedVcards: [] |
534 | + property var importErrors: [] |
535 | + property var dialog: null |
536 | + |
537 | + signal finished() |
538 | + |
539 | + function importVCards(model, vcards) |
540 | + { |
541 | + if (dialog || vcards.length === 0) { |
542 | + return |
543 | + } |
544 | + |
545 | + root.model = model |
546 | + root.vcards = vcards |
547 | + dialog = Popups.PopupUtils.open(importDialogComponent, root) |
548 | + |
549 | + for(var i=0, iMax=vcards.length; i < iMax; i++) { |
550 | + var vcardUrl = vcards[i] |
551 | + model.importContacts(vcardUrl) |
552 | + } |
553 | + } |
554 | + |
555 | + Connections { |
556 | + id: modelConnections |
557 | + |
558 | + onImportCompleted: { |
559 | + var imported = root.importedVcards |
560 | + var importErrors = root.importErrors |
561 | + imported.push(url) |
562 | + if (error !== ContactModel.ImportNoError) { |
563 | + root.importErrors.push(error) |
564 | + console.error("Fail to import vcard:" + error) |
565 | + } |
566 | + root.importedVcards = imported |
567 | + root.importErrors = importErrors |
568 | + } |
569 | + } |
570 | + |
571 | + Component { |
572 | + id: importDialogComponent |
573 | + |
574 | + Popups.Dialog { |
575 | + id: importDialog |
576 | + |
577 | + title: i18n.tr("Import vCards") |
578 | + text: root.importedVcards.length === 0 ? i18n.tr("Importing...") : i18n.tr("%1 vCards imported").arg(root.importedVcards.length) |
579 | + |
580 | + Button { |
581 | + anchors { |
582 | + left: parent.left |
583 | + right: parent.right |
584 | + margins: units.gu(1) |
585 | + } |
586 | + text: i18n.tr("Close") |
587 | + enabled: (root.importedVcards.length === root.vcards.length) |
588 | + onClicked: { |
589 | + root.dialog = null |
590 | + Popups.PopupUtils.close(importDialog) |
591 | + } |
592 | + } |
593 | + |
594 | + Component.onDestruction: root.destroy() |
595 | + } |
596 | + } |
597 | +} |
598 | + |
599 | + |
600 | + |
601 | |
602 | === modified file 'src/imports/MainWindow.qml' |
603 | --- src/imports/MainWindow.qml 2014-06-11 21:25:08 +0000 |
604 | +++ src/imports/MainWindow.qml 2014-06-27 21:27:44 +0000 |
605 | @@ -50,6 +50,10 @@ |
606 | mainStack.push(Qt.createComponent("ContactList/ContactListPage.qml"), { pickMode: true, pickMultipleContacts: !isSingle}) |
607 | } |
608 | |
609 | + function importvcard(_url) { |
610 | + mainStack.importContactRequested([_url]) |
611 | + } |
612 | + |
613 | PageStack { |
614 | id: mainStack |
615 | |
616 | @@ -60,6 +64,7 @@ |
617 | signal editContatRequested(string contactId, string phoneNumber) |
618 | signal contactCreated(QtObject contact) |
619 | signal contactModelError(string errorMessage) |
620 | + signal importContactRequested(var urls) |
621 | |
622 | anchors { |
623 | fill: parent |
624 | @@ -118,5 +123,14 @@ |
625 | {pickMode: true, |
626 | contentHubTransfer: transfer}) |
627 | } |
628 | + onImportRequested: { |
629 | + if (transfer.state === ContentHub.ContentTransfer.Charged) { |
630 | + var urls = [] |
631 | + for(var i=0; i < transfer.items.length; i++) { |
632 | + urls.push(transfer.items[i].url) |
633 | + } |
634 | + mainStack.importContactRequested(urls) |
635 | + } |
636 | + } |
637 | } |
638 | } |
639 | |
640 | === modified file 'src/imports/Ubuntu/Contacts/CMakeLists.txt' |
641 | --- src/imports/Ubuntu/Contacts/CMakeLists.txt 2014-06-09 14:12:58 +0000 |
642 | +++ src/imports/Ubuntu/Contacts/CMakeLists.txt 2014-06-27 21:27:44 +0000 |
643 | @@ -12,6 +12,7 @@ |
644 | DialogButtons.qml |
645 | FastScroll.qml |
646 | FastScroll.js |
647 | + MostCalledModel.qml |
648 | MultipleSelectionListView.qml |
649 | MultipleSelectionVisualModel.qml |
650 | qmldir |
651 | |
652 | === modified file 'src/imports/Ubuntu/Contacts/ContactAvatar.qml' |
653 | --- src/imports/Ubuntu/Contacts/ContactAvatar.qml 2014-06-16 17:25:21 +0000 |
654 | +++ src/imports/Ubuntu/Contacts/ContactAvatar.qml 2014-06-27 21:27:44 +0000 |
655 | @@ -26,7 +26,7 @@ |
656 | property string displayName: ContactsJS.formatToDisplay(contactElement, ContactDetail.Name, [Name.FirstName, Name.LastName]) |
657 | readonly property string defaultAvatar: "image://theme/contact" |
658 | readonly property string avatarUrl: ContactsJS.getAvatar(contactElement, "") |
659 | - readonly property bool useDefaultAvatar: (displayName === "" || contact.tag.tag === "") && (avatarUrl === "") |
660 | + readonly property bool useDefaultAvatar: (contactElement == null) || (displayName === "" || contactElement.tag.tag === "") && (avatarUrl === "") |
661 | |
662 | function reload() |
663 | { |
664 | |
665 | === modified file 'src/imports/Ubuntu/Contacts/ContactDelegate.qml' |
666 | --- src/imports/Ubuntu/Contacts/ContactDelegate.qml 2014-06-18 21:27:05 +0000 |
667 | +++ src/imports/Ubuntu/Contacts/ContactDelegate.qml 2014-06-27 21:27:44 +0000 |
668 | @@ -25,7 +25,9 @@ |
669 | |
670 | property bool showAvatar: true |
671 | property bool selected: false |
672 | + property bool isCurrentItem: false |
673 | property string defaultAvatarUrl: "" |
674 | + property string defaultTitle: "" |
675 | property int titleDetail: ContactDetail.Name |
676 | property variant titleFields: [ Name.FirstName, Name.LastName ] |
677 | property bool detailsShown: false |
678 | @@ -35,16 +37,13 @@ |
679 | signal pressAndHold(int index, QtObject contact) |
680 | signal detailClicked(QtObject contact, QtObject detail, string action) |
681 | signal infoRequested(int index, QtObject contact) |
682 | + signal addContactClicked(string label) |
683 | |
684 | function _onDetailClicked(detail, action) |
685 | { |
686 | detailClicked(contact, detail, action) |
687 | } |
688 | |
689 | - // ListItemWithActions |
690 | - //onItemClicked: root.clicked(index, contact) |
691 | - //onItemPressAndHold: root.pressAndHold(index, contact) |
692 | - |
693 | height: delegate.height |
694 | implicitHeight: delegate.height + (pickerLoader.item ? pickerLoader.item.height : 0) |
695 | width: parent ? parent.width : 0 |
696 | @@ -100,7 +99,7 @@ |
697 | } |
698 | font.pointSize: 88 |
699 | color: UbuntuColors.lightAubergine |
700 | - text: ContactsJS.formatToDisplay(contact, root.titleDetail, root.titleFields) |
701 | + text: contact ? ContactsJS.formatToDisplay(contact, root.titleDetail, root.titleFields, "") : root.defaultTitle |
702 | elide: Text.ElideRight |
703 | } |
704 | |
705 | @@ -113,7 +112,7 @@ |
706 | rightMargin: units.gu(2) |
707 | verticalCenter: parent.verticalCenter |
708 | } |
709 | - name: "contact" |
710 | + name: contact ? "contact" : "new-contact" |
711 | height: units.gu(3) |
712 | width: opacity > 0.0 ? height : 0 |
713 | opacity: root.detailsShown ? 1.0 : 0.0 |
714 | @@ -122,8 +121,14 @@ |
715 | } |
716 | |
717 | MouseArea { |
718 | - anchors.fill: parent |
719 | - onClicked: root.infoRequested(index, contact) |
720 | + anchors.fill: parent |
721 | + onClicked: { |
722 | + if (contact) { |
723 | + root.infoRequested(index, contact) |
724 | + } else { |
725 | + root.addContactClicked(name.text) |
726 | + } |
727 | + } |
728 | } |
729 | } |
730 | |
731 | @@ -139,7 +144,7 @@ |
732 | return Qt.resolvedUrl("ContactDetailPickerPhoneNumberDelegate.qml") |
733 | } |
734 | } |
735 | - active: root.detailsShown |
736 | + active: contact && root.detailsShown |
737 | asynchronous: true |
738 | anchors { |
739 | top: delegate.bottom |
740 | @@ -153,10 +158,79 @@ |
741 | } |
742 | |
743 | onStatusChanged: { |
744 | - if (status == Loader.Ready) { |
745 | + if ((status == Loader.Ready) && contact) { |
746 | pickerLoader.item.updateDetails(contact) |
747 | pickerLoader.item.detailClicked.connect(root._onDetailClicked) |
748 | } |
749 | } |
750 | } |
751 | + |
752 | + Behavior on height { |
753 | + id: behaviorOnHeight |
754 | + |
755 | + enabled: false |
756 | + UbuntuNumberAnimation { } |
757 | + } |
758 | + |
759 | + state: isCurrentItem ? "expanded" : "" |
760 | + states: [ |
761 | + State { |
762 | + name: "expanded" |
763 | + PropertyChanges { |
764 | + target: root |
765 | + clip: true |
766 | + height: root.implicitHeight |
767 | + loaderOpacity: 1.0 |
768 | + // FIXME: Setting detailsShown to true on expanded state cause the property to change to false and true during the state transition, and that |
769 | + // causes the loader to load twice |
770 | + //detailsShown: true |
771 | + } |
772 | + PropertyChanges { |
773 | + target: behaviorOnHeight |
774 | + enabled: true |
775 | + } |
776 | + } |
777 | + ] |
778 | + transitions: [ |
779 | + Transition { |
780 | + from: "expanded" |
781 | + to: "" |
782 | + SequentialAnimation { |
783 | + UbuntuNumberAnimation { |
784 | + target: root |
785 | + properties: "height, loaderOpacity" |
786 | + } |
787 | + PropertyAction { |
788 | + target: root |
789 | + property: "clip" |
790 | + } |
791 | + PropertyAction { |
792 | + target: root |
793 | + property: "detailsShown" |
794 | + value: false |
795 | + } |
796 | + PropertyAction { |
797 | + target: root |
798 | + property: "ListView.delayRemove" |
799 | + value: false |
800 | + } |
801 | + } |
802 | + }, |
803 | + Transition { |
804 | + from: "" |
805 | + to: "expanded" |
806 | + SequentialAnimation { |
807 | + PropertyAction { |
808 | + target: root |
809 | + properties: "detailsShown" |
810 | + value: true |
811 | + } |
812 | + PropertyAction { |
813 | + target: root |
814 | + properties: "ListView.delayRemove" |
815 | + value: true |
816 | + } |
817 | + } |
818 | + } |
819 | + ] |
820 | } |
821 | |
822 | === modified file 'src/imports/Ubuntu/Contacts/ContactListView.qml' |
823 | --- src/imports/Ubuntu/Contacts/ContactListView.qml 2014-06-18 15:56:42 +0000 |
824 | +++ src/imports/Ubuntu/Contacts/ContactListView.qml 2014-06-27 21:27:44 +0000 |
825 | @@ -45,12 +45,12 @@ |
826 | readonly property alias count: view.count |
827 | |
828 | /*! |
829 | - \qmlproperty string contactNameFilter |
830 | + \qmlproperty string contactStringFilter |
831 | |
832 | This property holds a string that will be used to filter contacts on the list |
833 | By default this is set to empty |
834 | */ |
835 | - property string contactNameFilter: "" |
836 | + property string filterTerm: "" |
837 | /*! |
838 | \qmlproperty Filter filter |
839 | |
840 | @@ -223,6 +223,10 @@ |
841 | */ |
842 | signal detailClicked(QtObject contact, QtObject detail, string action) |
843 | /*! |
844 | + This handler is called when a unknown contact is clicked, the label contains the phone number |
845 | + */ |
846 | + signal addContactClicked(string label) |
847 | + /*! |
848 | This handler is called when the contact delegate disapear (height === 0) caused by the function call makeDisappear |
849 | */ |
850 | signal contactDisappeared(QtObject contact) |
851 | @@ -290,7 +294,8 @@ |
852 | Rectangle { |
853 | id: itemHeader |
854 | |
855 | - height: units.gu(2) |
856 | + visible: root.showFavourites && (root.filterTerm.length === 0) |
857 | + height: visible ? units.gu(2) : 0 |
858 | anchors { |
859 | left: parent.left |
860 | right: parent.right |
861 | @@ -311,14 +316,14 @@ |
862 | text: i18n.dtr("address-book-app", "All") |
863 | horizontalAlignment: Text.AlignHCenter |
864 | verticalAlignment: Text.AlignVCenter |
865 | - color: root.showFavourites ? UbuntuColors.warmGrey : UbuntuColors.orange |
866 | + color: view.favouritesIsSelected ? UbuntuColors.warmGrey : UbuntuColors.orange |
867 | MouseArea { |
868 | anchors.fill: parent |
869 | onClicked: { |
870 | //WORKAROUND: clear the model before start populate it with the new contacts |
871 | //otherwise the model will wait for all contacts before show any new contact |
872 | root.changeFilter(root.filter) |
873 | - root.showFavourites = false |
874 | + view.favouritesIsSelected = false |
875 | } |
876 | } |
877 | } |
878 | @@ -343,21 +348,22 @@ |
879 | text: i18n.dtr("address-book-app", "Favourites") |
880 | horizontalAlignment: Text.AlignHCenter |
881 | verticalAlignment: Text.AlignVCenter |
882 | - color: root.showFavourites ? UbuntuColors.orange : UbuntuColors.warmGrey |
883 | + color: view.favouritesIsSelected ? UbuntuColors.orange : UbuntuColors.warmGrey |
884 | MouseArea { |
885 | anchors.fill: parent |
886 | - onClicked: root.showFavourites = true |
887 | + onClicked: view.favouritesIsSelected = true |
888 | } |
889 | } |
890 | } |
891 | } |
892 | |
893 | - onContactNameFilterChanged: contactSearchTimeout.restart() |
894 | + onFilterTermChanged: contactSearchTimeout.restart() |
895 | |
896 | ContactSimpleListView { |
897 | id: view |
898 | |
899 | - property bool showFavourites: false |
900 | + property bool showFavourites: true |
901 | + property bool favouritesIsSelected: false |
902 | |
903 | function getSectionText(index) { |
904 | var tag = listModel.contacts[index].tag.tag |
905 | @@ -371,14 +377,93 @@ |
906 | top: itemHeader.bottom |
907 | left: parent.left |
908 | right: parent.right |
909 | + bottom: parent.bottom |
910 | rightMargin: fastScroll.showing ? fastScroll.width - units.gu(1) : 0 |
911 | - bottom: parent.bottom |
912 | - |
913 | Behavior on rightMargin { |
914 | UbuntuNumberAnimation {} |
915 | } |
916 | } |
917 | |
918 | + header: Column { |
919 | + id: mostCalledView |
920 | + |
921 | + function makeItemVisible(item) |
922 | + { |
923 | + var itemY = mostCalledView.y + item.y |
924 | + var areaY = view.contentY |
925 | + if (itemY < areaY) { |
926 | + view.contentY = itemY |
927 | + } |
928 | + } |
929 | + |
930 | + anchors { |
931 | + left: parent.left |
932 | + right: parent.right |
933 | + } |
934 | + height: visible ? childrenRect.height : 0 |
935 | + visible: view.favouritesIsSelected && (callerRepeat.count > 0) |
936 | + onHeightChanged: { |
937 | + // make selected item fully visible |
938 | + if (calledModel.currentIndex != -1) { |
939 | + mostCalledView.makeItemVisible(callerRepeat.itemAt(calledModel.currentIndex)) |
940 | + } else { |
941 | + // WORKAROUND: The SDK header causes the contactY to move to a wrong postion |
942 | + // this should fix the Y position (630 is the header height) |
943 | + view.contentY = -630 |
944 | + } |
945 | + } |
946 | + |
947 | + Rectangle { |
948 | + color: Theme.palette.normal.background |
949 | + anchors { |
950 | + left: parent.left |
951 | + right: parent.right |
952 | + margins: units.gu(1) |
953 | + } |
954 | + height: units.gu(3) |
955 | + Label { |
956 | + anchors.fill: parent |
957 | + verticalAlignment: Text.AlignVCenter |
958 | + text: i18n.tr("Frequently called") |
959 | + font.pointSize: 76 |
960 | + } |
961 | + ListItem.ThinDivider { |
962 | + anchors { |
963 | + left: parent.left |
964 | + right: parent.right |
965 | + bottom: parent.bottom |
966 | + } |
967 | + } |
968 | + } |
969 | + Repeater { |
970 | + id: callerRepeat |
971 | + |
972 | + model: MostCalledModel { |
973 | + id: calledModel |
974 | + maxCount: 20 |
975 | + |
976 | + onInfoRequested: root.infoRequested(contact) |
977 | + onDetailClicked: root.detailClicked(contact, detail, action) |
978 | + onAddContactClicked: root.addContactClicked(label) |
979 | + onCurrentIndexChanged: { |
980 | + if (currentIndex !== -1) { |
981 | + view.currentIndex = -1 |
982 | + } |
983 | + } |
984 | + } |
985 | + } |
986 | + |
987 | + Connections { |
988 | + target: view |
989 | + onCurrentIndexChanged: { |
990 | + if (view.currentIndex !== -1) { |
991 | + calledModel.currentIndex = -1 |
992 | + } |
993 | + } |
994 | + } |
995 | + } |
996 | + |
997 | + height: Math.min(root.height, contentHeight) |
998 | onError: root.error(message) |
999 | onInfoRequested: root.infoRequested(contact) |
1000 | onDetailClicked: root.detailClicked(contact, detail, action) |
1001 | @@ -400,6 +485,34 @@ |
1002 | matchFlags: DetailFilter.MatchExactly |
1003 | } |
1004 | |
1005 | + UnionFilter { |
1006 | + id: contactTermFilter |
1007 | + |
1008 | + property string value: "" |
1009 | + |
1010 | + DetailFilter { |
1011 | + detail: ContactDetail.DisplayLabel |
1012 | + field: DisplayLabel.Label |
1013 | + value: contactTermFilter.value |
1014 | + matchFlags: DetailFilter.MatchContains |
1015 | + } |
1016 | + |
1017 | + DetailFilter { |
1018 | + detail: ContactDetail.PhoneNumber |
1019 | + field: PhoneNumber.Number |
1020 | + value: contactTermFilter.value |
1021 | + matchFlags: DetailFilter.MatchPhoneNumber |
1022 | + } |
1023 | + |
1024 | + DetailFilter { |
1025 | + detail: ContactDetail.PhoneNumber |
1026 | + field: PhoneNumber.Number |
1027 | + value: contactTermFilter.value |
1028 | + matchFlags: DetailFilter.MatchContains |
1029 | + } |
1030 | + } |
1031 | + |
1032 | + |
1033 | IntersectionFilter { |
1034 | id: contactsFilter |
1035 | |
1036 | @@ -407,29 +520,21 @@ |
1037 | |
1038 | filters: { |
1039 | var filters = [] |
1040 | - if (root.showFavourites) { |
1041 | + if (contactTermFilter.value.length > 0) { |
1042 | + filters.push(contactTermFilter) |
1043 | + } else if (view.showFavourites && view.favouritesIsSelected) { |
1044 | filters.push(favouritesFilter) |
1045 | } |
1046 | + |
1047 | if (root.filter) { |
1048 | filters.push(root.filter) |
1049 | } |
1050 | - if (nameFilter.value && (nameFilter.value.length > 0)) { |
1051 | - filters.push(nameFilter) |
1052 | - } |
1053 | + |
1054 | active = (filters.length > 0) |
1055 | return filters |
1056 | } |
1057 | } |
1058 | |
1059 | - DetailFilter { |
1060 | - id: nameFilter |
1061 | - |
1062 | - detail: ContactDetail.DisplayLabel |
1063 | - field: DisplayLabel.Label |
1064 | - value: root.nameFilter |
1065 | - matchFlags: DetailFilter.MatchContains |
1066 | - } |
1067 | - |
1068 | Timer { |
1069 | id: contactSearchTimeout |
1070 | |
1071 | @@ -437,14 +542,26 @@ |
1072 | repeat: false |
1073 | interval: 300 |
1074 | onTriggered: { |
1075 | - if (root.contactNameFilter === "") { // if the search criteria is empty clear the list before show all contacts |
1076 | - contactList.changeFilter(root.filter) |
1077 | - nameFilter.value = "" |
1078 | + var needUpdate = false |
1079 | + if (root.filterTerm === "") { // if the search criteria is empty clear the list before show all contacts |
1080 | + if (contactTermFilter.value !== "") { |
1081 | + root.changeFilter(root.filter) |
1082 | + contactTermFilter.value = "" |
1083 | + needUpdate = true |
1084 | + } |
1085 | } else { |
1086 | - if (nameFilter.value === "") { // if the search starts clear the list before show results |
1087 | - contactList.changeFilter(root.filter) |
1088 | + if (contactTermFilter.value !== root.filterTerm) { |
1089 | + if (contactTermFilter.value === "") { // if the search starts clear the list before show results |
1090 | + root.changeFilter(root.filter) |
1091 | + } |
1092 | + contactTermFilter.value = root.filterTerm |
1093 | + needUpdate = true |
1094 | } |
1095 | - nameFilter.value = root.contactNameFilter |
1096 | + } |
1097 | + |
1098 | + // manually update if autoUpdate is disabled |
1099 | + if (needUpdate && !root.autoUpdate) { |
1100 | + contactsModel.update() |
1101 | } |
1102 | } |
1103 | } |
1104 | @@ -499,9 +616,9 @@ |
1105 | enabled: view.contentHeight > (view.height * 2) |
1106 | |
1107 | anchors { |
1108 | - top: itemHeader.bottom |
1109 | + top: view.top |
1110 | topMargin: units.gu(0.5) |
1111 | - bottom: parent.bottom |
1112 | + bottom: view.bottom |
1113 | right: parent.right |
1114 | } |
1115 | } |
1116 | |
1117 | === modified file 'src/imports/Ubuntu/Contacts/ContactSimpleListView.qml' |
1118 | --- src/imports/Ubuntu/Contacts/ContactSimpleListView.qml 2014-06-16 17:33:52 +0000 |
1119 | +++ src/imports/Ubuntu/Contacts/ContactSimpleListView.qml 2014-06-27 21:27:44 +0000 |
1120 | @@ -268,34 +268,16 @@ |
1121 | listDelegate: ContactDelegate { |
1122 | id: contactDelegate |
1123 | |
1124 | - // overwrite |
1125 | - function disappeared() |
1126 | - { |
1127 | - contactListView.contactDisappeared(contact) |
1128 | - } |
1129 | - |
1130 | width: parent.width |
1131 | selected: contactListView.multiSelectionEnabled && contactListView.isSelected(contactDelegate) |
1132 | defaultAvatarUrl: contactListView.defaultAvatarImageUrl |
1133 | titleDetail: contactListView.titleDetail |
1134 | titleFields: contactListView.titleFields |
1135 | - |
1136 | - // ListItemWithActions |
1137 | - //locked: contactListView.isInSelectionMode || detailsShown |
1138 | - //triggerActionOnMouseRelease: true |
1139 | - //leftSideAction: contactListView.leftSideAction |
1140 | - //rightSideActions: contactListView.rightSideActions |
1141 | + isCurrentItem: ListView.isCurrentItem |
1142 | |
1143 | onDetailClicked: contactListView.detailClicked(contact, detail, action) |
1144 | onInfoRequested: contactListView._fetchContact(index, contact) |
1145 | |
1146 | - Behavior on height { |
1147 | - id: behaviorOnHeight |
1148 | - |
1149 | - enabled: false |
1150 | - UbuntuNumberAnimation { } |
1151 | - } |
1152 | - |
1153 | // collapse the item before remove it, to avoid crash |
1154 | ListView.onRemove: SequentialAnimation { |
1155 | ScriptAction { |
1156 | @@ -333,67 +315,6 @@ |
1157 | contactListView.selectItem(contactDelegate) |
1158 | } |
1159 | } |
1160 | - state: ListView.isCurrentItem ? "expanded" : "" |
1161 | - states: [ |
1162 | - State { |
1163 | - name: "expanded" |
1164 | - PropertyChanges { |
1165 | - target: contactDelegate |
1166 | - clip: true |
1167 | - height: contactDelegate.implicitHeight |
1168 | - loaderOpacity: 1.0 |
1169 | - // FIXME: Setting detailsShown to true on expanded state cause the property to change to false and true during the state transition, and that |
1170 | - // causes the loader to load twice |
1171 | - //detailsShown: true |
1172 | - } |
1173 | - PropertyChanges { |
1174 | - target: behaviorOnHeight |
1175 | - enabled: true |
1176 | - } |
1177 | - } |
1178 | - ] |
1179 | - transitions: [ |
1180 | - Transition { |
1181 | - from: "expanded" |
1182 | - to: "" |
1183 | - SequentialAnimation { |
1184 | - UbuntuNumberAnimation { |
1185 | - target: contactDelegate |
1186 | - properties: "height, loaderOpacity" |
1187 | - } |
1188 | - PropertyAction { |
1189 | - target: contactDelegate |
1190 | - property: "clip" |
1191 | - } |
1192 | - PropertyAction { |
1193 | - target: contactDelegate |
1194 | - property: "detailsShown" |
1195 | - value: false |
1196 | - } |
1197 | - PropertyAction { |
1198 | - target: contactDelegate |
1199 | - property: "ListView.delayRemove" |
1200 | - value: false |
1201 | - } |
1202 | - } |
1203 | - }, |
1204 | - Transition { |
1205 | - from: "" |
1206 | - to: "expanded" |
1207 | - SequentialAnimation { |
1208 | - PropertyAction { |
1209 | - target: contactDelegate |
1210 | - properties: "detailsShown" |
1211 | - value: true |
1212 | - } |
1213 | - PropertyAction { |
1214 | - target: contactDelegate |
1215 | - properties: "ListView.delayRemove" |
1216 | - value: true |
1217 | - } |
1218 | - } |
1219 | - } |
1220 | - ] |
1221 | } |
1222 | |
1223 | ContactFetch { |
1224 | |
1225 | === modified file 'src/imports/Ubuntu/Contacts/Contacts.js' |
1226 | --- src/imports/Ubuntu/Contacts/Contacts.js 2014-06-06 17:52:58 +0000 |
1227 | +++ src/imports/Ubuntu/Contacts/Contacts.js 2014-06-27 21:27:44 +0000 |
1228 | @@ -2,9 +2,9 @@ |
1229 | var phoneTypeModel = null |
1230 | |
1231 | // Format contact name to be displayed |
1232 | -function formatToDisplay(contact, contactDetail, detailFields, detail) { |
1233 | +function formatToDisplay(contact, contactDetail, detailFields, detail, defaultTitle) { |
1234 | if (!contact) { |
1235 | - return "" |
1236 | + return defaultTitle |
1237 | } |
1238 | |
1239 | if (!detail) { |
1240 | |
1241 | === added file 'src/imports/Ubuntu/Contacts/MostCalledModel.qml' |
1242 | --- src/imports/Ubuntu/Contacts/MostCalledModel.qml 1970-01-01 00:00:00 +0000 |
1243 | +++ src/imports/Ubuntu/Contacts/MostCalledModel.qml 2014-06-27 21:27:44 +0000 |
1244 | @@ -0,0 +1,183 @@ |
1245 | +/* |
1246 | + * Copyright (C) 2012-2013 Canonical, Ltd. |
1247 | + * |
1248 | + * This program is free software; you can redistribute it and/or modify |
1249 | + * it under the terms of the GNU General Public License as published by |
1250 | + * the Free Software Foundation; version 3. |
1251 | + * |
1252 | + * This program is distributed in the hope that it will be useful, |
1253 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1254 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1255 | + * GNU General Public License for more details. |
1256 | + * |
1257 | + * You should have received a copy of the GNU General Public License |
1258 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1259 | + */ |
1260 | + |
1261 | + |
1262 | +import QtQuick 2.2 |
1263 | +import QtContacts 5.0 |
1264 | +import Ubuntu.History 0.1 |
1265 | +import Ubuntu.Telephony 0.1 |
1266 | + |
1267 | +VisualDataModel { |
1268 | + id: root |
1269 | + |
1270 | + property int maxCount: 10 |
1271 | + property var contactModel: null |
1272 | + property var historyModel |
1273 | + property int currentIndex: -1 |
1274 | + |
1275 | + signal clicked(int index, QtObject contact) |
1276 | + signal detailClicked(QtObject contact, QtObject detail, string action) |
1277 | + signal infoRequested(int index, QtObject contact) |
1278 | + signal addContactClicked(string label) |
1279 | + |
1280 | + function filterEntries() |
1281 | + { |
1282 | + var contacts = {} |
1283 | + var interval = new Date() |
1284 | + var secs = (interval.getTime() - 2592000000) // one month ago |
1285 | + interval.setTime(secs) |
1286 | + |
1287 | + var totalCount = 0 |
1288 | + var i = 0; |
1289 | + while(true) { |
1290 | + var event = historyModel.getItem(i) |
1291 | + if (!event) { |
1292 | + break |
1293 | + } |
1294 | + |
1295 | + if (event.timestamp < interval) { |
1296 | + break |
1297 | + } |
1298 | + |
1299 | + var participants = event.participants |
1300 | + for (var p=0; p < participants.length; p++) { |
1301 | + var phoneNumber = participants[p] |
1302 | + if (phoneNumber) { |
1303 | + if (contacts[phoneNumber] === undefined) { |
1304 | + contacts[phoneNumber] = 1 |
1305 | + } else { |
1306 | + var count = contacts[phoneNumber] |
1307 | + contacts[phoneNumber] = count + 1 |
1308 | + } |
1309 | + totalCount += 1 |
1310 | + } |
1311 | + } |
1312 | + i++ |
1313 | + } |
1314 | + |
1315 | + listModel.clear() |
1316 | + if (totalCount == 0) { |
1317 | + return |
1318 | + } |
1319 | + |
1320 | + // sort phones most called first |
1321 | + var mostCalledFirst = [] |
1322 | + for (var key in contacts) { |
1323 | + mostCalledFirst.push([key, contacts[key]]); |
1324 | + } |
1325 | + |
1326 | + mostCalledFirst.sort(function(a, b) { |
1327 | + a = a[1]; |
1328 | + b = b[1]; |
1329 | + |
1330 | + return a < b ? -1 : (a > b ? 1 : 0); |
1331 | + }); |
1332 | + |
1333 | + contacts = {} |
1334 | + for (var i = 0; i < mostCalledFirst.length; i++) { |
1335 | + var key = mostCalledFirst[i][0]; |
1336 | + var value = mostCalledFirst[i][1]; |
1337 | + contacts[key] = value |
1338 | + } |
1339 | + |
1340 | + // get the avarage frequency |
1341 | + var average = totalCount / mostCalledFirst.length |
1342 | + |
1343 | + for (var phone in contacts) { |
1344 | + if (contacts[phone] >= average) { |
1345 | + listModel.insert(0, {"participant": phone}) |
1346 | + if (listModel.count >= root.maxCount) { |
1347 | + return; |
1348 | + } |
1349 | + } |
1350 | + } |
1351 | + } |
1352 | + |
1353 | + model: ListModel { |
1354 | + id: listModel |
1355 | + } |
1356 | + |
1357 | + historyModel: HistoryEventModel { |
1358 | + |
1359 | + function getItem(row) { |
1360 | + while ((row >= count) && (canFetchMore())) { |
1361 | + fetchMore() |
1362 | + } |
1363 | + return get(row) |
1364 | + } |
1365 | + |
1366 | + type: HistoryThreadModel.EventTypeVoice |
1367 | + sort: HistorySort { |
1368 | + sortField: "timestamp" |
1369 | + sortOrder: HistorySort.DescendingOrder |
1370 | + } |
1371 | + Component.onCompleted: root.filterEntries() |
1372 | + } |
1373 | + |
1374 | + |
1375 | + delegate: ContactDelegate { |
1376 | + id: contactDelegate |
1377 | + |
1378 | + readonly property alias contact: contactFetch.contact |
1379 | + |
1380 | + onDetailClicked: root.detailClicked(contact, detail, action) |
1381 | + onInfoRequested: root.infoRequested(index, contact) |
1382 | + onAddContactClicked: root.addContactClicked(label) |
1383 | + |
1384 | + defaultAvatarUrl: "image://theme/contacts" |
1385 | + defaultTitle: participant |
1386 | + width: parent.width |
1387 | + titleDetail: ContactDetail.DisplayLabel |
1388 | + titleFields: [ DisplayLabel.Label ] |
1389 | + isCurrentItem: root.currentIndex === index |
1390 | + |
1391 | + // collapse the item before remove it, to avoid crash |
1392 | + ListView.onRemove: SequentialAnimation { |
1393 | + ScriptAction { |
1394 | + script: { |
1395 | + if (contactDelegate.state !== "") { |
1396 | + historyModel.currentIndex = -1 |
1397 | + } |
1398 | + } |
1399 | + } |
1400 | + } |
1401 | + |
1402 | + onClicked: { |
1403 | + if (root.currentIndex === index) { |
1404 | + root.currentIndex = -1 |
1405 | + return |
1406 | + } else if (detailToPick !== 0) { |
1407 | + root.currentIndex = index |
1408 | + return |
1409 | + } else if (detailToPick == 0) { |
1410 | + contactListView.detailClicked(contact, null, "") |
1411 | + } |
1412 | + } |
1413 | + |
1414 | + ContactWatcher { |
1415 | + id: contactWatcher |
1416 | + |
1417 | + phoneNumber: participant |
1418 | + onContactIdChanged: contactFetch.fetchContact(contactId) |
1419 | + } |
1420 | + |
1421 | + ContactFetch { |
1422 | + id: contactFetch |
1423 | + |
1424 | + model: contactsModel |
1425 | + } |
1426 | + } |
1427 | +} |
1428 | |
1429 | === modified file 'src/imports/Ubuntu/Contacts/qmldir' |
1430 | --- src/imports/Ubuntu/Contacts/qmldir 2014-06-09 15:52:06 +0000 |
1431 | +++ src/imports/Ubuntu/Contacts/qmldir 2014-06-27 21:27:44 +0000 |
1432 | @@ -16,3 +16,4 @@ |
1433 | internal ContactJs Contacts.js |
1434 | internal FastScroll FastScroll.qml |
1435 | internal FastScrollJs FastScroll.js |
1436 | +internal MostCalledModel MostCalledModel.qml |
Are there any related MPs required for this MP to build/function as expected? YES /code.launchpad .net/~renatofil ho/history- service/ qml-fetch- more/+merge/ 224169
* https:/
Is your branch in sync with latest trunk? YES
Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator? YES
Did you successfully run all tests found in your component's Test Plan on device or emulator? YES
If you changed the UI, was the change specified/approved by design? NO UI CHANGE
If you changed the packaging (debian), did you subscribe a core-dev to this MP? NO PACKAGE CHANGED