Merge lp:~renatofilho/dialer-app/addressbook-components into lp:dialer-app

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 416
Merged at revision: 410
Proposed branch: lp:~renatofilho/dialer-app/addressbook-components
Merge into: lp:dialer-app
Diff against target: 992 lines (+625/-42)
23 files modified
debian/control (+3/-2)
debian/dialer-app-autopilot.install (+1/-0)
debian/dialer-app.install (+2/-0)
src/dialerapplication.cpp (+4/-0)
src/qml/CMakeLists.txt (+2/-0)
src/qml/ContactEditorPage/CMakeLists.txt (+7/-0)
src/qml/ContactEditorPage/DialerContactEditorPage.qml (+60/-0)
src/qml/ContactViewPage/CMakeLists.txt (+7/-0)
src/qml/ContactViewPage/DialerContactViewPage.qml (+139/-0)
src/qml/ContactsPage/ContactsPage.qml (+55/-7)
src/qml/DialerPage/DialerPage.qml (+1/-0)
src/qml/HistoryPage/HistoryDetailsPage.qml (+1/-1)
src/qml/HistoryPage/HistoryPage.qml (+1/-1)
src/qml/dialer-app.qml (+35/-17)
tests/CMakeLists.txt (+4/-1)
tests/autopilot/CMakeLists.txt (+0/-2)
tests/autopilot/dialer_app/__init__.py (+95/-0)
tests/autopilot/dialer_app/fixture_setup.py (+37/-0)
tests/autopilot/dialer_app/tests/__init__.py (+8/-4)
tests/autopilot/dialer_app/tests/test_contacts.py (+45/-0)
tests/autopilot/dialer_app/tests/test_logs.py (+78/-7)
tests/data/CMakeLists.txt (+10/-0)
tests/data/vcard.vcf (+30/-0)
To merge this branch: bzr merge lp:~renatofilho/dialer-app/addressbook-components
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) packaging Approve
PS Jenkins bot continuous-integration Needs Fixing
Gustavo Pichorim Boiko (community) Approve
Review via email: mp+257914@code.launchpad.net

Commit message

Make use of the new address book components instead of launch the address-book-app.

To post a comment you must log in.
400. By Renato Araujo Oliveira Filho

Added new dependency.

401. By Renato Araujo Oliveira Filho

Updated dialer app install file.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
402. By Renato Araujo Oliveira Filho

Fixed build deps.

403. By Renato Araujo Oliveira Filho

Fixed add number to contact use case.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
404. By Renato Araujo Oliveira Filho

Update autopilot test.

405. By Renato Araujo Oliveira Filho

Trunk merged.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
406. By Renato Araujo Oliveira Filho

Trigger a call if clicked on contact phone on contact view page.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
407. By Renato Araujo Oliveira Filho

Update test log to check if the contact was created with the correct phone number.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
408. By Renato Araujo Oliveira Filho

Create autopilot test for contacts page.

409. By Renato Araujo Oliveira Filho

Removed debug messages.
Updated autopilot install file with the new data dir.

410. By Renato Araujo Oliveira Filho

Trunk merged.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
411. By Renato Araujo Oliveira Filho

Add missing test.

412. By Renato Araujo Oliveira Filho

Fixed debian package.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

Are there any related MPs required for this MP to build/function as expected?
YES: https://code.launchpad.net/~renatofilho/address-book-app/split-app/+merge/258937

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 UI labels, did you update the pot file?
NO LABEL CHANGE

If you changed the packaging (debian), did you add a core-dev as a reviewer to this MP?
NO PACKAGE CHANGE

413. By Renato Araujo Oliveira Filho

Avoid fetch contact twice while adding a new number.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

dialer-app-autopilot needs to depend on address-book-app-autopilot for the tests to work

review: Needs Fixing
414. By Renato Araujo Oliveira Filho

Added 'address-book-app-autopilot' into autopilot dep list.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
415. By Renato Araujo Oliveira Filho

Install vcard files into autopilot data dir.

416. By Renato Araujo Oliveira Filho

Updated header.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
417. By Renato Araujo Oliveira Filho

Trunk merged.

418. By Renato Araujo Oliveira Filho

Fixed flake8.

Revision history for this message
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.
No: this change needs changes on address-book-app to work

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
419. By Renato Araujo Oliveira Filho

call external urls as ("<action>:<value>") instead of ("<action>:///<value>")

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Packaging changes look fine.

review: Approve (packaging)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-04-27 22:15:19 +0000
3+++ debian/control 2015-05-15 15:18:10 +0000
4@@ -16,7 +16,7 @@
5 qtdeclarative5-dev (>= 5.0),
6 qtdeclarative5-dev-tools,
7 qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin,
8- qtdeclarative5-ubuntu-contacts0.1,
9+ qtdeclarative5-ubuntu-addressbook0.1,
10 qtdeclarative5-qtcontacts-plugin,
11 qtdeclarative5-ubuntu-telephony-phonenumber0.1,
12 qtdeclarative5-ubuntu-history0.1,
13@@ -39,7 +39,7 @@
14 qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin,
15 qtdeclarative5-ubuntu-telephony-phonenumber0.1,
16 qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
17- qtdeclarative5-ubuntu-contacts0.1 (>= 0.2+14.10.20140805),
18+ qtdeclarative5-ubuntu-addressbook0.1,
19 qtdeclarative5-qtcontacts-plugin,
20 Recommends: unity8 (>= 7.81.0~),
21 Description: Dialer application for Ubuntu
22@@ -50,6 +50,7 @@
23 Section: debug
24 Depends: ${misc:Depends},
25 ${python3:Depends},
26+ address-book-app-autopilot,
27 autopilot-qt5,
28 dbus,
29 libqt5test5,
30
31=== modified file 'debian/dialer-app-autopilot.install'
32--- debian/dialer-app-autopilot.install 2013-07-16 14:05:40 +0000
33+++ debian/dialer-app-autopilot.install 2015-05-15 15:18:10 +0000
34@@ -1,1 +1,2 @@
35 usr/lib/python*/dist-packages/dialer_app/*
36+usr/lib/python*/dist-packages/dialer_app/testdata/*
37
38=== modified file 'debian/dialer-app.install'
39--- debian/dialer-app.install 2014-08-22 14:51:14 +0000
40+++ debian/dialer-app.install 2015-05-15 15:18:10 +0000
41@@ -6,6 +6,8 @@
42 usr/share/dialer-app/HistoryPage
43 usr/share/dialer-app/DialerPage
44 usr/share/dialer-app/ContactsPage
45+usr/share/dialer-app/ContactViewPage
46+usr/share/dialer-app/ContactEditorPage
47 usr/share/dialer-app/Dialogs
48 usr/share/dialer-app/assets
49 usr/share/dialer-app/MMI
50
51=== modified file 'src/dialerapplication.cpp'
52--- src/dialerapplication.cpp 2014-11-13 14:41:07 +0000
53+++ src/dialerapplication.cpp 2015-05-15 15:18:10 +0000
54@@ -143,6 +143,10 @@
55 m_view->rootContext()->setContextProperty("QTCONTACTS_MANAGER_OVERRIDE", contactsBackend);
56 }
57
58+ // used by autopilot tests to load vcards during tests
59+ QByteArray testData = qgetenv("QTCONTACTS_PRELOAD_VCARD");
60+ m_view->rootContext()->setContextProperty("QTCONTACTS_PRELOAD_VCARD", testData);
61+
62 QString pluginPath = ubuntuPhonePluginPath();
63 if (!pluginPath.isNull()) {
64 m_view->engine()->addImportPath(pluginPath);
65
66=== modified file 'src/qml/CMakeLists.txt'
67--- src/qml/CMakeLists.txt 2014-08-27 16:07:33 +0000
68+++ src/qml/CMakeLists.txt 2015-05-15 15:18:10 +0000
69@@ -16,4 +16,6 @@
70 add_subdirectory(HistoryPage)
71 add_subdirectory(LiveCallPage)
72 add_subdirectory(ContactsPage)
73+add_subdirectory(ContactViewPage)
74+add_subdirectory(ContactEditorPage)
75 add_subdirectory(Dialogs)
76
77=== added directory 'src/qml/ContactEditorPage'
78=== added file 'src/qml/ContactEditorPage/CMakeLists.txt'
79--- src/qml/ContactEditorPage/CMakeLists.txt 1970-01-01 00:00:00 +0000
80+++ src/qml/ContactEditorPage/CMakeLists.txt 2015-05-15 15:18:10 +0000
81@@ -0,0 +1,7 @@
82+file(GLOB CONTACT_EDITOR_QML_JS_FILES *.qml *.js)
83+
84+# make the files visible on qtcreator
85+add_custom_target(dialer_contacteditor_QMlFiles ALL SOURCES ${CONTACT_EDITOR_QML_JS_FILES})
86+
87+install(FILES ${CONTACT_EDITOR_QML_JS_FILES} DESTINATION ${DIALER_APP_DIR}/ContactEditorPage)
88+
89
90=== added file 'src/qml/ContactEditorPage/DialerContactEditorPage.qml'
91--- src/qml/ContactEditorPage/DialerContactEditorPage.qml 1970-01-01 00:00:00 +0000
92+++ src/qml/ContactEditorPage/DialerContactEditorPage.qml 2015-05-15 15:18:10 +0000
93@@ -0,0 +1,60 @@
94+/*
95+ * Copyright 2015 Canonical Ltd.
96+ *
97+ * This file is part of dialer-app.
98+ *
99+ * dialer-app is free software; you can redistribute it and/or modify
100+ * it under the terms of the GNU General Public License as published by
101+ * the Free Software Foundation; version 3.
102+ *
103+ * dialer-app is distributed in the hope that it will be useful,
104+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
105+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
106+ * GNU General Public License for more details.
107+ *
108+ * You should have received a copy of the GNU General Public License
109+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
110+ */
111+
112+import QtQuick 2.2
113+import QtContacts 5.0
114+
115+import Ubuntu.Components 1.1
116+
117+import Ubuntu.AddressBook.ContactEditor 0.1
118+
119+ContactEditorPage {
120+ id: root
121+ objectName: "contactEditorPage"
122+
123+ property var contactListPage: null
124+
125+ head.backAction: Action {
126+ objectName: "cancel"
127+
128+ text: i18n.tr("Cancel")
129+ iconName: "back"
130+ onTriggered: {
131+ root.cancel()
132+ root.active = false
133+ }
134+ }
135+
136+ head.actions: [
137+ Action {
138+ objectName: "save"
139+
140+ text: i18n.tr("Save")
141+ iconName: "ok"
142+ enabled: root.isContactValid
143+ onTriggered: root.save()
144+ }
145+ ]
146+
147+ onContactSaved: {
148+ if (root.contactListPage) {
149+ root.contactListPage.moveListToContact(contact)
150+ root.contactListPage.phoneToAdd = ""
151+ }
152+ }
153+}
154
155=== added directory 'src/qml/ContactViewPage'
156=== added file 'src/qml/ContactViewPage/CMakeLists.txt'
157--- src/qml/ContactViewPage/CMakeLists.txt 1970-01-01 00:00:00 +0000
158+++ src/qml/ContactViewPage/CMakeLists.txt 2015-05-15 15:18:10 +0000
159@@ -0,0 +1,7 @@
160+file(GLOB CONTACT_VIEW_QML_JS_FILES *.qml *.js)
161+
162+# make the files visible on qtcreator
163+add_custom_target(dialer_contactviewpage_QMlFiles ALL SOURCES ${CONTACT_VIEW_QML_JS_FILES})
164+
165+install(FILES ${CONTACT_VIEW_QML_JS_FILES} DESTINATION ${DIALER_APP_DIR}/ContactViewPage)
166+
167
168=== added file 'src/qml/ContactViewPage/DialerContactViewPage.qml'
169--- src/qml/ContactViewPage/DialerContactViewPage.qml 1970-01-01 00:00:00 +0000
170+++ src/qml/ContactViewPage/DialerContactViewPage.qml 2015-05-15 15:18:10 +0000
171@@ -0,0 +1,139 @@
172+/*
173+ * Copyright 2015 Canonical Ltd.
174+ *
175+ * This file is part of dialer-app.
176+ *
177+ * dialer-app is free software; you can redistribute it and/or modify
178+ * it under the terms of the GNU General Public License as published by
179+ * the Free Software Foundation; version 3.
180+ *
181+ * dialer-app is distributed in the hope that it will be useful,
182+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
183+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
184+ * GNU General Public License for more details.
185+ *
186+ * You should have received a copy of the GNU General Public License
187+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
188+ */
189+
190+
191+import QtQuick 2.2
192+import QtContacts 5.0
193+
194+import Ubuntu.Components 1.1
195+import Ubuntu.Components.Popups 1.0 as Popups
196+import Ubuntu.Contacts 0.1
197+
198+import Ubuntu.AddressBook.Base 0.1
199+import Ubuntu.AddressBook.ContactView 0.1
200+import Ubuntu.AddressBook.ContactShare 0.1
201+
202+ContactViewPage {
203+ id: root
204+ objectName: "contactViewPage"
205+
206+ readonly property string contactEditorPageURL: Qt.resolvedUrl("../ContactEditorPage/DialerContactEditorPage.qml")
207+ property string addPhoneToContact: ""
208+ property var contactListPage: null
209+
210+ function addPhoneToContactImpl(contact, phoneNumber)
211+ {
212+ var detailSourceTemplate = "import QtContacts 5.0; PhoneNumber{ number: \"" + phoneNumber.trim() + "\" }"
213+ var newDetail = Qt.createQmlObject(detailSourceTemplate, contact)
214+ if (newDetail) {
215+ contact.addDetail(newDetail)
216+ pageStack.push(root.contactEditorPageURL,
217+ { model: root.model,
218+ contact: contact,
219+ initialFocusSection: "phones",
220+ newDetails: [newDetail],
221+ contactListPage: root.contactListPage })
222+ root.addPhoneToContact = ""
223+ } else {
224+ console.warn("Fail to create phone number detail")
225+ }
226+ }
227+
228+ head.actions: [
229+ Action {
230+ objectName: "share"
231+ text: i18n.tr("Share")
232+ iconName: "share"
233+ onTriggered: {
234+ pageStack.push(root.contactShareComponent,
235+ {contactModel: root.model, contacts: [root.contact]})
236+ }
237+ },
238+ Action {
239+ objectName: "edit"
240+ text: i18n.tr("Edit")
241+ iconName: "edit"
242+ onTriggered: {
243+ pageStack.push(contactEditorPageURL,
244+ { model: root.model,
245+ contact: root.contact,
246+ contactListPage: root.contactListPage })
247+ }
248+ }
249+ ]
250+
251+ extensions: ContactDetailSyncTargetView {
252+ contact: root.contact
253+ anchors {
254+ left: parent.left
255+ right: parent.right
256+ }
257+ height: implicitHeight
258+ }
259+
260+ onContactRemoved: pageStack.pop()
261+ onActionTrigerred: {
262+ if ((action == "tel") || (action == "default")) {
263+ if (callManager.hasCalls) {
264+ mainView.call(detail.number, mainView.account.accountId);
265+ } else {
266+ mainView.populateDialpad(detail.number)
267+ }
268+ } else {
269+ Qt.openUrlExternally(("%1:%2").arg(action).arg(detail.value(0)))
270+ }
271+ }
272+
273+ Component {
274+ id: contactShareComponent
275+ ContactSharePage {}
276+ }
277+
278+ onContactFetched: {
279+ root.contact = contact
280+ if (root.active && root.addPhoneToContact != "") {
281+ root.addPhoneToContactImpl(contact, root.addPhoneToContact)
282+ root.addPhoneToContact = ""
283+ }
284+ }
285+
286+ Component {
287+ id: contactModelComponent
288+
289+ ContactModel {
290+ id: contactModelHelper
291+
292+ manager: (typeof(QTCONTACTS_MANAGER_OVERRIDE) !== "undefined") &&
293+ (QTCONTACTS_MANAGER_OVERRIDE != "") ? QTCONTACTS_MANAGER_OVERRIDE : "galera"
294+ autoUpdate: false
295+ }
296+ }
297+
298+ onActiveChanged: {
299+ if (active && root.contact && root.addPhoneToContact != "") {
300+ root.addPhoneToContactImpl(contact, root.addPhoneToContact)
301+ root.addPhoneToContact = ""
302+ }
303+ }
304+
305+ Component.onCompleted: {
306+ if (!root.model) {
307+ root.model = contactModelComponent.createObject(root)
308+ }
309+ }
310+}
311
312=== modified file 'src/qml/ContactsPage/ContactsPage.qml'
313--- src/qml/ContactsPage/ContactsPage.qml 2015-02-06 00:12:03 +0000
314+++ src/qml/ContactsPage/ContactsPage.qml 2015-05-15 15:18:10 +0000
315@@ -27,10 +27,30 @@
316 id: contactsPage
317 objectName: "contactsPage"
318
319- property QtObject contact
320+ property string phoneToAdd: ""
321+ property QtObject contactIndex: null
322+
323+ function moveListToContact(contact)
324+ {
325+ if (active) {
326+ contactsPage.contactIndex = null
327+ contactList.positionViewAtContact(contact)
328+ } else {
329+ contactsPage.contactIndex = contact
330+ }
331+ }
332+
333+ Connections {
334+ target: contactList.listModel
335+ onContactsChanged: {
336+ if (contactsPage.contactIndex) {
337+ contactList.positionViewAtContact(contactsPage.contactIndex)
338+ contactsPage.contactIndex = null
339+ }
340+ }
341+ }
342
343 title: i18n.tr("Contacts")
344-
345 TextField {
346 id: searchField
347
348@@ -138,17 +158,36 @@
349 }
350
351 showAddNewButton: true
352- showImportOptions: (contactList.count === 0) && (filterTerm === "")
353- onAddNewContactClicked: mainView.createNewContactForPhone(" ")
354- onInfoRequested: mainView.viewContact(contact.contactId)
355+ showImportOptions: (contactList.count === 0) &&
356+ (filterTerm === "") &&
357+ (contactsPage.phoneToAdd === "")
358+ onAddNewContactClicked: {
359+ var newContact = ContactsJS.createEmptyContact(contactsPage.phoneToAdd, contactsPage)
360+ pageStack.push(Qt.resolvedUrl("../ContactEditorPage/DialerContactEditorPage.qml"),
361+ { model: contactList.listModel,
362+ contact: newContact,
363+ initialFocusSection: (contactsPage.phoneToAdd != "" ? "phones" : "name"),
364+ contactListPage: contactsPage
365+ })
366+ }
367+ onInfoRequested: mainView.viewContact(contact.contactId, contactList.listModel)
368
369 filterTerm: searchField.text
370- detailToPick: ContactDetail.PhoneNumber
371+ detailToPick: (contactsPage.phoneToAdd != "") ? -1 : ContactDetail.PhoneNumber
372 onDetailClicked: {
373 if (action === "message") {
374 Qt.openUrlExternally("message:///" + encodeURIComponent(detail.number))
375 return
376 }
377+
378+ if (contactsPage.phoneToAdd != "") {
379+ mainView.addPhoneToContact(contact,
380+ contactsPage.phoneToAdd,
381+ contactsPage,
382+ contactList.listModel)
383+ return
384+ }
385+
386 pageStackNormalMode.pop()
387 if (callManager.hasCalls) {
388 mainView.call(detail.number, mainView.account.accountId);
389@@ -156,7 +195,16 @@
390 mainView.populateDialpad(detail.number)
391 }
392 }
393- onAddDetailClicked: mainView.addPhoneToContact(contact.contactId, " ")
394+ onAddDetailClicked: mainView.addPhoneToContact(contact.contactId,
395+ " ",
396+ contactsPage,
397+ contactList.listModel)
398+ }
399+
400+ Component.onCompleted: {
401+ if (QTCONTACTS_PRELOAD_VCARD !== "") {
402+ contactList.listModel.importContacts("file://" + QTCONTACTS_PRELOAD_VCARD)
403+ }
404 }
405
406 KeyboardRectagle {
407
408=== modified file 'src/qml/DialerPage/DialerPage.qml'
409--- src/qml/DialerPage/DialerPage.qml 2015-04-08 22:41:26 +0000
410+++ src/qml/DialerPage/DialerPage.qml 2015-05-15 15:18:10 +0000
411@@ -37,6 +37,7 @@
412 property list<Action> actionsGreeter
413 property list<Action> actionsNormal: [
414 Action {
415+ objectName: "contacts"
416 iconName: "contact"
417 text: i18n.tr("Contacts")
418 onTriggered: pageStackNormalMode.push(Qt.resolvedUrl("../ContactsPage/ContactsPage.qml"))
419
420=== modified file 'src/qml/HistoryPage/HistoryDetailsPage.qml'
421--- src/qml/HistoryPage/HistoryDetailsPage.qml 2015-04-09 19:49:26 +0000
422+++ src/qml/HistoryPage/HistoryDetailsPage.qml 2015-05-15 15:18:10 +0000
423@@ -57,7 +57,7 @@
424 if (unknownContact) {
425 mainView.addNewPhone(phoneNumber)
426 } else {
427- mainView.viewContact(contactWatcher.contactId)
428+ mainView.viewContact(contactWatcher.contactId, null)
429 }
430 }
431 },
432
433=== modified file 'src/qml/HistoryPage/HistoryPage.qml'
434--- src/qml/HistoryPage/HistoryPage.qml 2015-05-06 20:06:37 +0000
435+++ src/qml/HistoryPage/HistoryPage.qml 2015-05-15 15:18:10 +0000
436@@ -347,7 +347,7 @@
437 if (unknownContact) {
438 mainView.addNewPhone(phoneNumber)
439 } else {
440- mainView.viewContact(contactId)
441+ mainView.viewContact(contactId, null)
442 }
443 }
444 visible: knownNumber
445
446=== modified file 'src/qml/dialer-app.qml'
447--- src/qml/dialer-app.qml 2015-04-21 14:28:14 +0000
448+++ src/qml/dialer-app.qml 2015-05-15 15:18:10 +0000
449@@ -18,9 +18,11 @@
450
451 import QtQuick 2.0
452 import Qt.labs.settings 1.0
453+
454 import Ubuntu.Components 1.1
455 import Ubuntu.Components.Popups 0.1
456 import Ubuntu.Telephony 0.1
457+import Ubuntu.Contacts 0.1
458
459 MainView {
460 id: mainView
461@@ -69,7 +71,7 @@
462 if (pageStackNormalMode.depth > 2 && pageStackNormalMode.currentPage.objectName == "contactsPage") {
463 pageStackNormalMode.pop();
464 }
465-
466+
467 // pop live call views from both stacks if we have no calls.
468 if (pageStackNormalMode.depth > 1 && pageStackNormalMode.currentPage.objectName == "pageLiveCall") {
469 pageStackNormalMode.pop();
470@@ -175,22 +177,38 @@
471 return false;
472 }
473
474- function createNewContactForPhone(phoneNumber)
475+ function addNewPhone(phoneNumber)
476 {
477- Qt.openUrlExternally("addressbook:///create?callback=dialer-app.desktop&phone=" + encodeURIComponent(phoneNumber))
478- }
479-
480- function viewContact(contactId) {
481- Qt.openUrlExternally("addressbook:///contact?callback=dialer-app.desktop&id=" + encodeURIComponent(contactId))
482- }
483-
484- function addNewPhone(phoneNumber) {
485- Qt.openUrlExternally("addressbook:///addnewphone?callback=dialer-app.desktop&phone=" + encodeURIComponent(phoneNumber))
486- }
487-
488- function addPhoneToContact(contactId, phoneNumber) {
489- Qt.openUrlExternally("addressbook:///addphone?callback=dialer-app.desktop&id=%1&phone=%2".arg(encodeURIComponent(contactId))
490- .arg(encodeURIComponent(phoneNumber)))
491+ pageStackNormalMode.push(Qt.resolvedUrl("ContactsPage/ContactsPage.qml"),
492+ {"phoneToAdd": phoneNumber})
493+ }
494+
495+ function viewContact(contactId, model) {
496+ var initialPropers = {}
497+ if (model) {
498+ initialPropers = {"contactId": contactId, "model": model}
499+ } else {
500+ initialPropers = {"contactId": contactId}
501+ }
502+ pageStackNormalMode.push(Qt.resolvedUrl("ContactViewPage/DialerContactViewPage.qml"),
503+ initialPropers)
504+ }
505+
506+ function addPhoneToContact(contact, phoneNumber, contactListPage, model) {
507+ var initialPropers = {"addPhoneToContact": phoneNumber,
508+ "contactListPage": contactListPage}
509+
510+ if (model) {
511+ initialPropers["model"] = model
512+ }
513+ if (typeof(contact) == 'string') {
514+ initialPropers["contactId"] = contact
515+ } else {
516+ initialPropers["contact"] = contact
517+ }
518+
519+ pageStackNormalMode.push(Qt.resolvedUrl("ContactViewPage/DialerContactViewPage.qml"),
520+ initialPropers)
521 }
522
523 function sendMessage(phoneNumber) {
524@@ -396,7 +414,7 @@
525 if (currentStack.currentPage.objectName == "pageLiveCall") {
526 return;
527 }
528-
529+
530 currentStack.push(Qt.resolvedUrl("LiveCallPage/LiveCall.qml"), properties)
531 }
532
533
534=== modified file 'tests/CMakeLists.txt'
535--- tests/CMakeLists.txt 2014-09-02 21:54:21 +0000
536+++ tests/CMakeLists.txt 2015-05-15 15:18:10 +0000
537@@ -1,3 +1,6 @@
538+execute_process(COMMAND python3 -c "from distutils.sysconfig import get_python_lib; print (get_python_lib())"
539+ OUTPUT_VARIABLE PYTHON_PACKAGE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
540+
541 add_subdirectory(qml)
542-
543+add_subdirectory(data)
544 add_subdirectory(autopilot)
545
546=== modified file 'tests/autopilot/CMakeLists.txt'
547--- tests/autopilot/CMakeLists.txt 2014-08-13 17:24:42 +0000
548+++ tests/autopilot/CMakeLists.txt 2015-05-15 15:18:10 +0000
549@@ -1,7 +1,5 @@
550 set(AUTOPILOT_DIR dialer_app)
551
552-execute_process(COMMAND python3 -c "from distutils.sysconfig import get_python_lib; print (get_python_lib())"
553- OUTPUT_VARIABLE PYTHON_PACKAGE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
554
555 install(DIRECTORY ${AUTOPILOT_DIR}
556 DESTINATION ${PYTHON_PACKAGE_DIR}
557
558=== modified file 'tests/autopilot/dialer_app/__init__.py'
559--- tests/autopilot/dialer_app/__init__.py 2015-04-27 22:15:19 +0000
560+++ tests/autopilot/dialer_app/__init__.py 2015-05-15 15:18:10 +0000
561@@ -12,6 +12,9 @@
562 import logging
563
564 import ubuntuuitoolkit
565+
566+from address_book_app.address_book import _common
567+from address_book_app import address_book
568 from autopilot import exceptions as autopilot_exceptions
569
570
571@@ -30,6 +33,18 @@
572 self.hasCalls.wait_for(True)
573 return self.wait_select_single(LiveCall, active=True)
574
575+ @property
576+ def contacts_page(self):
577+ return self._get_page(ContactsPage, 'contactsPage')
578+
579+ @property
580+ def contact_editor_page(self):
581+ return self._get_page(DialerContactEditorPage, 'contactEditorPage')
582+
583+ @property
584+ def contact_view_page(self):
585+ return self._get_page(DialerContactViewPage, 'contactViewPage')
586+
587 def get_first_log(self):
588 return self.wait_select_single(objectName="historyDelegate0")
589
590@@ -63,6 +78,11 @@
591
592 return dialog.visible
593
594+ def _get_page(self, page_type, page_name):
595+ page = self.wait_select_single(
596+ page_type, objectName=page_name, active=True)
597+ return page
598+
599
600 class LiveCall(MainView):
601
602@@ -197,3 +217,78 @@
603 self.dial_number(number, formattedNumber)
604 self.click_call_button()
605 return self.get_root_instance().wait_select_single(LiveCall)
606+
607+ def get_header(self):
608+ """Return the Header custom proxy object of the Page."""
609+ return self.get_root_instance().select_single(
610+ 'MainView').get_header()
611+
612+ def click_contacts_button(self):
613+ self.get_header().click_action_button('contacts')
614+
615+
616+class DialerContactViewPage(address_book.ContactViewPage):
617+ """Autopilot custom proxy object for DialerContactViewPage components."""
618+
619+ def call_phone(self, index):
620+ phone_group = self.select_single(
621+ 'ContactDetailGroupWithTypeView',
622+ objectName='phones')
623+
624+ call_buttons = phone_group.select_many(
625+ "ActionButton",
626+ objectName="tel-contact")
627+ self.pointing_device.click_object(call_buttons[index])
628+
629+
630+class DialerContactEditorPage(address_book.ContactEditorPage):
631+ """Autopilot custom proxy object for DialerContactEditorPage components."""
632+
633+ def save(self):
634+ """
635+ Press the 'Save' button
636+ """
637+ header = self.get_header(main_window_name='MainView')
638+ header.click_action_button('save')
639+
640+
641+class ContactsPage(_common.PageWithHeader):
642+ """Autopilot custom proxy object for ContactsPage components."""
643+
644+ def _click_button(self, button):
645+ """Generic way to click a button"""
646+ self.visible.wait_for(True)
647+ button.visible.wait_for(True)
648+ self.pointing_device.click_object(button)
649+ return button
650+
651+ def _get_add_new_button(self):
652+ """Return the add-new button"""
653+ return self.wait_select_single('ContactListButtonDelegate',
654+ objectName='addNewButton')
655+
656+ def click_add_new(self):
657+ self._click_button(self._get_add_new_button())
658+
659+ def click_contact(self, index):
660+ contact_delegate = self._get_contact_delegate(index)
661+ self.pointing_device.click_object(contact_delegate)
662+
663+ def open_contact(self, index):
664+ contact_delegate = self._get_contact_delegate(index)
665+ self.pointing_device.click_object(contact_delegate)
666+ contact_delegate.state.wait_for('expanded')
667+ details_button = contact_delegate.wait_select_single(
668+ objectName='infoIcon')
669+ self.pointing_device.click_object(details_button)
670+ return self.get_root_instance().select_single(
671+ DialerContactViewPage, objectName='contactViewPage')
672+
673+ def _get_contact_delegate(self, index):
674+ contact_delegates = self._get_sorted_contact_delegates()
675+ return contact_delegates[index]
676+
677+ def _get_sorted_contact_delegates(self):
678+ contact_delegates = self.select_many('ContactDelegate', visible=True)
679+ return sorted(
680+ contact_delegates, key=lambda delegate: delegate.globalRect.y)
681
682=== modified file 'tests/autopilot/dialer_app/fixture_setup.py'
683--- tests/autopilot/dialer_app/fixture_setup.py 2015-04-30 18:26:46 +0000
684+++ tests/autopilot/dialer_app/fixture_setup.py 2015-05-15 15:18:10 +0000
685@@ -24,6 +24,7 @@
686 import dbusmock
687 from autopilot.platform import model
688 import dbus
689+from ubuntuuitoolkit import fixture_setup
690
691
692 class TestabilityEnvironment(fixtures.Fixture):
693@@ -136,6 +137,42 @@
694 subprocess.call(['mc-tool', 'reconnect', 'ofono/ofono/account0'])
695
696
697+class UseMemoryContactBackend(fixtures.Fixture):
698+
699+ def setUp(self):
700+ super().setUp()
701+ self.useFixture(
702+ fixtures.EnvironmentVariable(
703+ 'QTCONTACTS_MANAGER_OVERRIDE', newvalue='memory')
704+ )
705+ self.useFixture(
706+ fixture_setup.InitctlEnvironmentVariable(
707+ QTCONTACTS_MANAGER_OVERRIDE='memory')
708+ )
709+
710+
711+class PreloadVcards(fixtures.Fixture):
712+ AUTOPILOT_DIR = "/usr/lib/python3/dist-packages/dialer_app/"
713+ VCARD_PATH_BIN = ("%s/testdata/vcard.vcf" % AUTOPILOT_DIR)
714+ VCARD_PATH_DEV = os.path.abspath("../data/vcard.vcf")
715+
716+ def setUp(self):
717+ super().setUp()
718+ vcard_full_path = PreloadVcards.VCARD_PATH_BIN
719+ if os.path.isfile(PreloadVcards.VCARD_PATH_DEV):
720+ vcard_full_path = PreloadVcards.VCARD_PATH_DEV
721+
722+ print("Loading contacts from: %s" % vcard_full_path)
723+ self.useFixture(
724+ fixtures.EnvironmentVariable(
725+ 'QTCONTACTS_PRELOAD_VCARD', newvalue=vcard_full_path)
726+ )
727+ self.useFixture(
728+ fixture_setup.InitctlEnvironmentVariable(
729+ QTCONTACTS_PRELOAD_VCARD=vcard_full_path)
730+ )
731+
732+
733 class MockNotificationSystem(fixtures.Fixture):
734
735 def setUp(self):
736
737=== modified file 'tests/autopilot/dialer_app/tests/__init__.py'
738--- tests/autopilot/dialer_app/tests/__init__.py 2015-04-29 21:53:05 +0000
739+++ tests/autopilot/dialer_app/tests/__init__.py 2015-05-15 15:18:10 +0000
740@@ -82,7 +82,8 @@
741
742 def create_config_file(self, firstLaunch=False):
743 self.user_config_dir = tempfile.mkdtemp(suffix='', prefix='dialer-app')
744- self.app_config_dir = (self.user_config_dir + '/com.ubuntu.dialer-app/')
745+ self.app_config_dir = (self.user_config_dir +
746+ '/com.ubuntu.dialer-app/')
747 os.makedirs(self.app_config_dir)
748 config_file_path = (self.app_config_dir + '/DialerApp.conf')
749
750@@ -91,13 +92,16 @@
751 else:
752 first_launch_flag = 'false'
753 with open(config_file_path, 'w') as config_file:
754- config_file.write('[General]\nhintNecessary=%s\n' % (first_launch_flag))
755+ config_file.write(
756+ '[General]\nhintNecessary=%s\n' % (first_launch_flag))
757
758 self.useFixture(
759- fixtures.EnvironmentVariable('XDG_CONFIG_HOME', newvalue=self.user_config_dir)
760+ fixtures.EnvironmentVariable('XDG_CONFIG_HOME',
761+ newvalue=self.user_config_dir)
762 )
763 self.useFixture(
764- fixture_setup.InitctlEnvironmentVariable(XDG_CONFIG_HOME=self.user_config_dir)
765+ fixture_setup.InitctlEnvironmentVariable(
766+ XDG_CONFIG_HOME=self.user_config_dir)
767 )
768
769 @property
770
771=== added file 'tests/autopilot/dialer_app/tests/test_contacts.py'
772--- tests/autopilot/dialer_app/tests/test_contacts.py 1970-01-01 00:00:00 +0000
773+++ tests/autopilot/dialer_app/tests/test_contacts.py 2015-05-15 15:18:10 +0000
774@@ -0,0 +1,45 @@
775+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
776+# Copyright 2015 Canonical
777+# Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
778+#
779+# This file is part of dialer-app.
780+#
781+# dialer-app is free software: you can redistribute it and/or modify it
782+# under the terms of the GNU General Public License version 3, as published
783+# by the Free Software Foundation.
784+
785+"""Tests for the Dialer App"""
786+
787+from autopilot.matchers import Eventually
788+from testtools.matchers import Equals
789+
790+from dialer_app.tests import DialerAppTestCase
791+from dialer_app import fixture_setup
792+
793+
794+class TestContacts(DialerAppTestCase):
795+ """Tests for the contacts interaction with the app."""
796+
797+ def setUp(self):
798+ # set the fixtures before launching the app
799+ testability_environment = fixture_setup.TestabilityEnvironment()
800+ self.useFixture(testability_environment)
801+ memory_backend = fixture_setup.UseMemoryContactBackend()
802+ self.useFixture(memory_backend)
803+ preload_data = fixture_setup.PreloadVcards()
804+ self.useFixture(preload_data)
805+
806+ # now launch the app
807+ super().setUp()
808+
809+ def _get_main_view(self, proxy_object):
810+ return proxy_object.wait_select_single('QQuickView')
811+
812+ def test_call_a_contact_from_contact_view(self):
813+ dialer_page = self.main_view.dialer_page
814+ dialer_page.click_contacts_button()
815+ contact_view_page = self.main_view.contacts_page.open_contact(0)
816+
817+ contact_view_page.call_phone(0)
818+ entry = dialer_page._get_keypad_entry()
819+ self.assertThat(entry.value, Eventually(Equals('444-44')))
820
821=== modified file 'tests/autopilot/dialer_app/tests/test_logs.py'
822--- tests/autopilot/dialer_app/tests/test_logs.py 2015-04-29 21:53:05 +0000
823+++ tests/autopilot/dialer_app/tests/test_logs.py 2015-05-15 15:18:10 +0000
824@@ -19,13 +19,12 @@
825 fixture_setup as url_dispatcher_fixtures
826 )
827
828+from address_book_app.address_book import data
829 from dialer_app.tests import DialerAppTestCase
830 from dialer_app import fixture_setup
831 from dialer_app import ListItemWithActions
832
833
834-@skipIf(model() == 'Desktop',
835- 'only run on Ubuntu touch platforms')
836 class TestCallLogs(DialerAppTestCase):
837 """Tests for the call log panel."""
838
839@@ -37,6 +36,10 @@
840 self.useFixture(fill_history)
841 self.fake_url_dispatcher = url_dispatcher_fixtures.FakeURLDispatcher()
842 self.useFixture(self.fake_url_dispatcher)
843+ memory_backend = fixture_setup.UseMemoryContactBackend()
844+ self.useFixture(memory_backend)
845+ preload_data = fixture_setup.PreloadVcards()
846+ self.useFixture(preload_data)
847
848 # now launch the app
849 super().setUp()
850@@ -52,6 +55,7 @@
851 except fake_dispatcher.FakeDispatcherException:
852 return None
853
854+ @skipIf(model() == 'Desktop', 'only run on Ubuntu touch platforms')
855 def test_call_log_item_opens_messaging(self):
856 """Ensure tapping on 'send text message' item of a call log opens
857 the messaging app.
858@@ -74,11 +78,78 @@
859 ListItemWithActions.HistoryDelegate, objectName='historyDelegate0')
860 delegate.add_contact()
861
862- self.assertThat(
863- self.get_last_dispatch_url_call_parameter,
864- Eventually(Equals(
865- 'addressbook:///addnewphone?callback=dialer-app.desktop&'
866- 'phone=800')))
867+ contacts_page = self.main_view.contacts_page
868+ self.assertThat(
869+ contacts_page.phoneToAdd, Eventually(Equals('800')))
870+
871+ # click add new button
872+ contacts_page.click_add_new()
873+
874+ # wait page be ready for edit
875+ contact_editor_page = self.main_view.contact_editor_page
876+ self.main_view.contact_editor_page.wait_get_focus('phones')
877+
878+ # fill contact name
879+ test_contact = data.Contact('FirstName', 'LastName')
880+ test_contact.professional_details = []
881+ contact_editor_page.fill_form(test_contact)
882+
883+ # save contact
884+ contact_editor_page.save()
885+
886+ # contact view will appear with the new contact data
887+ contact_view_page = contacts_page.open_contact(3)
888+ self.assertThat(contact_view_page.visible, Eventually(Equals(True)))
889+
890+ # check if contact contains the new phone number
891+ phone_group = contact_view_page.select_single(
892+ 'ContactDetailGroupWithTypeView',
893+ objectName='phones')
894+ self.assertThat(phone_group.detailsCount, Eventually(Equals(1)))
895+
896+ # check if the new value is correct
897+ phone_label_1 = contact_view_page.select_single(
898+ "Label",
899+ objectName="label_phoneNumber_0.0")
900+ self.assertThat(phone_label_1.text, Eventually(Equals('800')))
901+
902+ def test_add_number_into_old_contact_from_log(self):
903+ """Ensure tapping on 'add new contact' item of a call log opens
904+ the address-book app to allow add the numbe into a contact
905+
906+ """
907+ delegate = self.main_view.wait_select_single(
908+ ListItemWithActions.HistoryDelegate, objectName='historyDelegate0')
909+ delegate.add_contact()
910+
911+ contacts_page = self.main_view.contacts_page
912+ self.assertThat(
913+ contacts_page.phoneToAdd, Eventually(Equals('800')))
914+
915+ # click on first contact to add number
916+ contacts_page.click_contact(0)
917+
918+ # wait page be ready for edit
919+ contact_editor_page = self.main_view.contact_editor_page
920+ contact_editor_page.wait_get_focus('phones')
921+
922+ # save contact
923+ contact_editor_page.save()
924+
925+ # contact view will appear with the new contact data
926+ contact_view_page = self.main_view.contact_view_page
927+
928+ # check if contact contains the new phone number
929+ phone_group = contact_view_page.select_single(
930+ 'ContactDetailGroupWithTypeView',
931+ objectName='phones')
932+ self.assertThat(phone_group.detailsCount, Eventually(Equals(2)))
933+
934+ # check if the new value is correct
935+ phone_label_1 = contact_view_page.select_single(
936+ "Label",
937+ objectName="label_phoneNumber_1.0")
938+ self.assertThat(phone_label_1.text, Eventually(Equals('800')))
939
940
941 class TestSwipeItemTutorial(DialerAppTestCase):
942
943=== added directory 'tests/data'
944=== added file 'tests/data/CMakeLists.txt'
945--- tests/data/CMakeLists.txt 1970-01-01 00:00:00 +0000
946+++ tests/data/CMakeLists.txt 2015-05-15 15:18:10 +0000
947@@ -0,0 +1,10 @@
948+project(test_data)
949+
950+set(AUTOPILOT_DATA
951+ vcard.vcf
952+)
953+
954+install(FILES ${AUTOPILOT_DATA}
955+ DESTINATION ${PYTHON_PACKAGE_DIR}/dialer_app/testdata/
956+)
957+
958
959=== added file 'tests/data/vcard.vcf'
960--- tests/data/vcard.vcf 1970-01-01 00:00:00 +0000
961+++ tests/data/vcard.vcf 2015-05-15 15:18:10 +0000
962@@ -0,0 +1,30 @@
963+BEGIN:VCARD
964+VERSION:3.0
965+UID:47bbbfcab7c9b8ef0e7375074d22ff54905174bd
966+X-QTPROJECT-EXTENDED-DETAIL:CLIENTPIDMAP;[\n "1"\n]\n
967+N:teste3;teste3;;;
968+FN:teste3 teste3
969+X-QTPROJECT-FAVORITE:false;0
970+TEL:3333333
971+CATEGORIES:T
972+END:VCARD
973+BEGIN:VCARD
974+VERSION:3.0
975+UID:e5bb57fc852541dfc9ad29d583a36f1c353b65ed
976+X-QTPROJECT-EXTENDED-DETAIL:CLIENTPIDMAP;[\n "1"\n]\n
977+N:test34;teste;;;
978+FN:teste test34
979+X-QTPROJECT-FAVORITE:false;0
980+TEL:44444
981+CATEGORIES:T
982+END:VCARD
983+BEGIN:VCARD
984+VERSION:3.0
985+UID:0d753ce1005dde92f69e4ddb62222240691693a0
986+X-QTPROJECT-EXTENDED-DETAIL:CLIENTPIDMAP;[\n "1"\n]\n
987+N:teste2;teste;;;
988+FN:teste teste2
989+X-QTPROJECT-FAVORITE:false;0
990+TEL:111111
991+CATEGORIES:T
992+END:VCARD

Subscribers

People subscribed via source and target branches