Merge lp:~renatofilho/address-book-app/new-visual-contact-editor into lp:~phablet-team/address-book-app/staging
- new-visual-contact-editor
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Tiago Salem Herrmann |
Approved revision: | 215 |
Merged at revision: | 190 |
Proposed branch: | lp:~renatofilho/address-book-app/new-visual-contact-editor |
Merge into: | lp:~phablet-team/address-book-app/staging |
Prerequisite: | lp:~renatofilho/address-book-app/new-visual-contact-view |
Diff against target: |
1303 lines (+540/-278) 24 files modified
src/app/imagescalethread.cpp (+1/-1) src/imports/Common/ContactDetailItem.qml (+1/-0) src/imports/ContactEdit/AddFieldDialog.qml (+142/-0) src/imports/ContactEdit/AvatarImport.qml (+78/-0) src/imports/ContactEdit/CMakeLists.txt (+2/-0) src/imports/ContactEdit/ContactDetailAvatarEditor.qml (+45/-94) src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml (+4/-30) src/imports/ContactEdit/ContactDetailNameEditor.qml (+1/-0) src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml (+8/-2) src/imports/ContactEdit/ContactDetailWithTypeEditor.qml (+27/-27) src/imports/ContactEdit/ContactEditor.qml (+95/-28) src/imports/ContactEdit/TextInputDetail.qml (+1/-0) src/imports/ContactEdit/ValueSelector.qml (+12/-15) src/imports/ContactList/ContactListPage.qml (+1/-4) src/imports/ContactView/BasicFieldView.qml (+2/-2) src/imports/ContactView/ContactDetailAvatarView.qml (+6/-2) src/imports/ContactView/ContactDetailGroupWithTypeView.qml (+2/-0) src/imports/ContactView/ContactView.qml (+2/-1) src/imports/Ubuntu/Contacts/ContactAvatar.qml (+11/-3) src/imports/Ubuntu/Contacts/MultipleSelectionListView.qml (+9/-1) tests/autopilot/address_book_app/pages/_contact_editor.py (+42/-20) tests/autopilot/address_book_app/tests/__init__.py (+1/-2) tests/autopilot/address_book_app/tests/test_add_contact.py (+20/-32) tests/autopilot/address_book_app/tests/test_edit_contact.py (+27/-14) |
To merge this branch: | bzr merge lp:~renatofilho/address-book-app/new-visual-contact-editor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Tiago Salem Herrmann (community) | Approve | ||
Review via email: mp+223009@code.launchpad.net |
Commit message
Update contact editor page visuals.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:194
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:198
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:199
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:201
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:204
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:205
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Leo Arias (elopio) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:206
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:209
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:209
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:210
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Tiago Salem Herrmann (tiagosh) wrote : | # |
looks good to me now.
Thanks.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:211
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:213
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:213
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:215
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:215
http://
Executed test runs:
None: http://
None: http://
None: http://
None: http://
None: http://
None: http://
None: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'src/app/imagescalethread.cpp' | |||
2 | --- src/app/imagescalethread.cpp 2013-10-15 14:34:03 +0000 | |||
3 | +++ src/app/imagescalethread.cpp 2014-06-18 14:13:24 +0000 | |||
4 | @@ -57,7 +57,7 @@ | |||
5 | 57 | } | 57 | } |
6 | 58 | 58 | ||
7 | 59 | // Create the temporary file | 59 | // Create the temporary file |
9 | 60 | m_tmpFile = new QTemporaryFile(); | 60 | m_tmpFile = new QTemporaryFile("avatar_XXXXXX.png"); |
10 | 61 | if (!m_tmpFile->open()) { | 61 | if (!m_tmpFile->open()) { |
11 | 62 | return; | 62 | return; |
12 | 63 | } | 63 | } |
13 | 64 | 64 | ||
14 | === modified file 'src/imports/Common/ContactDetailItem.qml' | |||
15 | --- src/imports/Common/ContactDetailItem.qml 2014-05-16 00:06:46 +0000 | |||
16 | +++ src/imports/Common/ContactDetailItem.qml 2014-06-18 14:13:24 +0000 | |||
17 | @@ -23,6 +23,7 @@ | |||
18 | 23 | 23 | ||
19 | 24 | readonly property alias fieldDelegates: fieldsColumn.children | 24 | readonly property alias fieldDelegates: fieldsColumn.children |
20 | 25 | property Component fieldDelegate: null | 25 | property Component fieldDelegate: null |
21 | 26 | property alias spacing: fieldsColumn.spacing | ||
22 | 26 | 27 | ||
23 | 27 | implicitHeight: fieldsColumn.height | 28 | implicitHeight: fieldsColumn.height |
24 | 28 | Column { | 29 | Column { |
25 | 29 | 30 | ||
26 | === added file 'src/imports/ContactEdit/AddFieldDialog.qml' | |||
27 | --- src/imports/ContactEdit/AddFieldDialog.qml 1970-01-01 00:00:00 +0000 | |||
28 | +++ src/imports/ContactEdit/AddFieldDialog.qml 2014-06-18 14:13:24 +0000 | |||
29 | @@ -0,0 +1,142 @@ | |||
30 | 1 | /* | ||
31 | 2 | * Copyright (C) 2012-2014 Canonical, Ltd. | ||
32 | 3 | * | ||
33 | 4 | * This program is free software; you can redistribute it and/or modify | ||
34 | 5 | * it under the terms of the GNU General Public License as published by | ||
35 | 6 | * the Free Software Foundation; version 3. | ||
36 | 7 | * | ||
37 | 8 | * This program is distributed in the hope that it will be useful, | ||
38 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
39 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
40 | 11 | * GNU General Public License for more details. | ||
41 | 12 | * | ||
42 | 13 | * You should have received a copy of the GNU General Public License | ||
43 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
44 | 15 | */ | ||
45 | 16 | |||
46 | 17 | import QtQuick 2.2 | ||
47 | 18 | import Ubuntu.Components 0.1 | ||
48 | 19 | import QtContacts 5.0 | ||
49 | 20 | import Ubuntu.Components.Popups 0.1 as Popups | ||
50 | 21 | |||
51 | 22 | |||
52 | 23 | Item { | ||
53 | 24 | id: root | ||
54 | 25 | |||
55 | 26 | property QtObject contact: null | ||
56 | 27 | property var currentDialog: null | ||
57 | 28 | readonly property var validDetails: [ ContactDetail.PhoneNumber, | ||
58 | 29 | ContactDetail.Email, | ||
59 | 30 | ContactDetail.Address, | ||
60 | 31 | ContactDetail.OnlineAccount, | ||
61 | 32 | ContactDetail.Organization | ||
62 | 33 | // TODO: Not supported yet | ||
63 | 34 | // ContactDetail.Birthday, | ||
64 | 35 | // ContactDetail.Note, | ||
65 | 36 | // ContactDetail.Url | ||
66 | 37 | ] | ||
67 | 38 | readonly property var singleValueDetails: [ ContactDetail.Organization ] | ||
68 | 39 | signal fieldSelected(string fieldName, string qmlTypeName) | ||
69 | 40 | |||
70 | 41 | function showOptions() | ||
71 | 42 | { | ||
72 | 43 | if (currentDialog == null) { | ||
73 | 44 | // make sure the OSK disappear | ||
74 | 45 | root.forceActiveFocus() | ||
75 | 46 | currentDialog = PopupUtils.open(addFieldDialog, null) | ||
76 | 47 | } | ||
77 | 48 | } | ||
78 | 49 | |||
79 | 50 | function nameFromEnum(value) | ||
80 | 51 | { | ||
81 | 52 | switch (value) | ||
82 | 53 | { | ||
83 | 54 | case ContactDetail.PhoneNumber: | ||
84 | 55 | return i18n.tr("Phone") | ||
85 | 56 | case ContactDetail.Email: | ||
86 | 57 | return i18n.tr("Email") | ||
87 | 58 | case ContactDetail.Address: | ||
88 | 59 | return i18n.tr("Address") | ||
89 | 60 | case ContactDetail.OnlineAccount: | ||
90 | 61 | return i18n.tr("Social") | ||
91 | 62 | case ContactDetail.Organization: | ||
92 | 63 | return i18n.tr("Professional Details") | ||
93 | 64 | default: | ||
94 | 65 | console.error("Invalid contact detail enum value:" + value) | ||
95 | 66 | return "" | ||
96 | 67 | } | ||
97 | 68 | } | ||
98 | 69 | |||
99 | 70 | function qmlTypeFromEnum(value) | ||
100 | 71 | { | ||
101 | 72 | switch (value) | ||
102 | 73 | { | ||
103 | 74 | case ContactDetail.PhoneNumber: | ||
104 | 75 | return "PhoneNumber" | ||
105 | 76 | case ContactDetail.Email: | ||
106 | 77 | return "EmailAddress" | ||
107 | 78 | case ContactDetail.Address: | ||
108 | 79 | return "Address" | ||
109 | 80 | case ContactDetail.OnlineAccount: | ||
110 | 81 | return "OnlineAccount" | ||
111 | 82 | case ContactDetail.Organization: | ||
112 | 83 | return "Organization" | ||
113 | 84 | default: | ||
114 | 85 | console.error("Invalid contact detail enum value:" + value) | ||
115 | 86 | return "" | ||
116 | 87 | } | ||
117 | 88 | } | ||
118 | 89 | |||
119 | 90 | // check which details will be allowed to create | ||
120 | 91 | // some details we only support one value | ||
121 | 92 | function filterSingleDetails(details, contact) | ||
122 | 93 | { | ||
123 | 94 | var result = [] | ||
124 | 95 | for(var i=0; i < details.length; i++) { | ||
125 | 96 | var det = details[i] | ||
126 | 97 | if (singleValueDetails.indexOf(det) != -1) { | ||
127 | 98 | if (contact.details(det).length === 0) { | ||
128 | 99 | result.push(det) | ||
129 | 100 | } | ||
130 | 101 | } else { | ||
131 | 102 | result.push(det) | ||
132 | 103 | } | ||
133 | 104 | } | ||
134 | 105 | return result | ||
135 | 106 | } | ||
136 | 107 | |||
137 | 108 | visible: false | ||
138 | 109 | Component { | ||
139 | 110 | id: addFieldDialog | ||
140 | 111 | |||
141 | 112 | Popups.Dialog { | ||
142 | 113 | id: dialogue | ||
143 | 114 | objectName: "addFieldDialog" | ||
144 | 115 | |||
145 | 116 | title: i18n.tr("Select a field") | ||
146 | 117 | Repeater { | ||
147 | 118 | model: root.filterSingleDetails(validDetails, root.contact) | ||
148 | 119 | Button { | ||
149 | 120 | objectName: text | ||
150 | 121 | |||
151 | 122 | text: root.nameFromEnum(modelData) | ||
152 | 123 | onClicked: { | ||
153 | 124 | root.fieldSelected(text, root.qmlTypeFromEnum(modelData)) | ||
154 | 125 | PopupUtils.close(root.currentDialog) | ||
155 | 126 | root.currentDialog = null | ||
156 | 127 | } | ||
157 | 128 | } | ||
158 | 129 | } | ||
159 | 130 | Button { | ||
160 | 131 | objectName: "cancel" | ||
161 | 132 | |||
162 | 133 | text: i18n.tr("Cancel") | ||
163 | 134 | gradient: UbuntuColors.greyGradient | ||
164 | 135 | onClicked: { | ||
165 | 136 | PopupUtils.close(root.currentDialog) | ||
166 | 137 | root.currentDialog = null | ||
167 | 138 | } | ||
168 | 139 | } | ||
169 | 140 | } | ||
170 | 141 | } | ||
171 | 142 | } | ||
172 | 0 | 143 | ||
173 | === added file 'src/imports/ContactEdit/AvatarImport.qml' | |||
174 | --- src/imports/ContactEdit/AvatarImport.qml 1970-01-01 00:00:00 +0000 | |||
175 | +++ src/imports/ContactEdit/AvatarImport.qml 2014-06-18 14:13:24 +0000 | |||
176 | @@ -0,0 +1,78 @@ | |||
177 | 1 | /* | ||
178 | 2 | * Copyright (C) 2012-2014 Canonical, Ltd. | ||
179 | 3 | * | ||
180 | 4 | * This program is free software; you can redistribute it and/or modify | ||
181 | 5 | * it under the terms of the GNU General Public License as published by | ||
182 | 6 | * the Free Software Foundation; version 3. | ||
183 | 7 | * | ||
184 | 8 | * This program is distributed in the hope that it will be useful, | ||
185 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
186 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
187 | 11 | * GNU General Public License for more details. | ||
188 | 12 | * | ||
189 | 13 | * You should have received a copy of the GNU General Public License | ||
190 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
191 | 15 | */ | ||
192 | 16 | |||
193 | 17 | import QtQuick 2.2 | ||
194 | 18 | import Ubuntu.Components 0.1 | ||
195 | 19 | import Ubuntu.Components.Popups 0.1 as Popups | ||
196 | 20 | import Ubuntu.Content 0.1 as ContentHub | ||
197 | 21 | |||
198 | 22 | Item { | ||
199 | 23 | id: root | ||
200 | 24 | |||
201 | 25 | property var activeTransfer: null | ||
202 | 26 | property var loadingDialog: null | ||
203 | 27 | |||
204 | 28 | signal avatarReceived(string avatarUrl) | ||
205 | 29 | |||
206 | 30 | function requestNewAvatar() | ||
207 | 31 | { | ||
208 | 32 | if (!root.loadingDialog) { | ||
209 | 33 | root.loadingDialog = PopupUtils.open(loadingDialog, null) | ||
210 | 34 | root.activeTransfer = defaultSource.request(); | ||
211 | 35 | } | ||
212 | 36 | } | ||
213 | 37 | |||
214 | 38 | ContentHub.ContentPeer { | ||
215 | 39 | id: defaultSource | ||
216 | 40 | |||
217 | 41 | contentType: ContentHub.ContentType.Pictures | ||
218 | 42 | handler: ContentHub.ContentHandler.Source | ||
219 | 43 | selectionType: ContentHub.ContentTransfer.Single | ||
220 | 44 | } | ||
221 | 45 | |||
222 | 46 | Connections { | ||
223 | 47 | target: root.activeTransfer | ||
224 | 48 | onStateChanged: { | ||
225 | 49 | var done = ((root.activeTransfer.state === ContentHub.ContentTransfer.Charged) || | ||
226 | 50 | (root.activeTransfer.state === ContentHub.ContentTransfer.Aborted)); | ||
227 | 51 | |||
228 | 52 | if (root.activeTransfer.state === ContentHub.ContentTransfer.Charged) { | ||
229 | 53 | if (root.activeTransfer.items.length > 0) { | ||
230 | 54 | root.avatarReceived(root.activeTransfer.items[0].url) | ||
231 | 55 | } | ||
232 | 56 | } | ||
233 | 57 | |||
234 | 58 | if (done) { | ||
235 | 59 | PopupUtils.close(root.loadingDialog) | ||
236 | 60 | root.loadingDialog = null | ||
237 | 61 | } | ||
238 | 62 | } | ||
239 | 63 | } | ||
240 | 64 | |||
241 | 65 | Component { | ||
242 | 66 | id: loadingDialog | ||
243 | 67 | |||
244 | 68 | Popups.Dialog { | ||
245 | 69 | id: dialogue | ||
246 | 70 | |||
247 | 71 | title: i18n.tr("Loading") | ||
248 | 72 | ActivityIndicator { | ||
249 | 73 | running: true | ||
250 | 74 | visible: running | ||
251 | 75 | } | ||
252 | 76 | } | ||
253 | 77 | } | ||
254 | 78 | } | ||
255 | 0 | 79 | ||
256 | === modified file 'src/imports/ContactEdit/CMakeLists.txt' | |||
257 | --- src/imports/ContactEdit/CMakeLists.txt 2014-06-09 22:45:19 +0000 | |||
258 | +++ src/imports/ContactEdit/CMakeLists.txt 2014-06-18 14:13:24 +0000 | |||
259 | @@ -1,4 +1,6 @@ | |||
260 | 1 | set(CONTACT_EDIT_QMLS | 1 | set(CONTACT_EDIT_QMLS |
261 | 2 | AvatarImport.qml | ||
262 | 3 | AddFieldDialog.qml | ||
263 | 2 | ContactDetailAddressesEditor.qml | 4 | ContactDetailAddressesEditor.qml |
264 | 3 | ContactDetailAvatarEditor.qml | 5 | ContactDetailAvatarEditor.qml |
265 | 4 | ContactDetailEmailsEditor.qml | 6 | ContactDetailEmailsEditor.qml |
266 | 5 | 7 | ||
267 | === modified file 'src/imports/ContactEdit/ContactDetailAvatarEditor.qml' | |||
268 | --- src/imports/ContactEdit/ContactDetailAvatarEditor.qml 2014-05-06 13:18:07 +0000 | |||
269 | +++ src/imports/ContactEdit/ContactDetailAvatarEditor.qml 2014-06-18 14:13:24 +0000 | |||
270 | @@ -17,15 +17,13 @@ | |||
271 | 17 | import QtQuick 2.2 | 17 | import QtQuick 2.2 |
272 | 18 | import Ubuntu.Components 0.1 | 18 | import Ubuntu.Components 0.1 |
273 | 19 | import QtContacts 5.0 | 19 | import QtContacts 5.0 |
274 | 20 | import Ubuntu.Content 0.1 | ||
275 | 21 | import Ubuntu.Components.Popups 0.1 as Popups | ||
276 | 22 | 20 | ||
277 | 23 | import "../Common" | 21 | import "../Common" |
278 | 24 | 22 | ||
279 | 25 | ContactDetailBase { | 23 | ContactDetailBase { |
280 | 26 | id: root | 24 | id: root |
281 | 27 | 25 | ||
283 | 28 | readonly property string defaultAvatar: Qt.resolvedUrl("../../artwork/contact-default-profile.png") | 26 | readonly property string defaultAvatar: "image://theme/contact" |
284 | 29 | 27 | ||
285 | 30 | function isEmpty() { | 28 | function isEmpty() { |
286 | 31 | return false; | 29 | return false; |
287 | @@ -62,98 +60,51 @@ | |||
288 | 62 | } | 60 | } |
289 | 63 | 61 | ||
290 | 64 | detail: contact ? contact.detail(ContactDetail.Avatar) : null | 62 | detail: contact ? contact.detail(ContactDetail.Avatar) : null |
382 | 65 | implicitHeight: units.gu(17) | 63 | implicitHeight: units.gu(8) |
383 | 66 | 64 | implicitWidth: units.gu(8) | |
384 | 67 | Image { | 65 | |
385 | 68 | id: avatarImage | 66 | UbuntuShape { |
386 | 69 | 67 | id: avatar | |
387 | 70 | anchors.fill: parent | 68 | |
388 | 71 | source: root.getAvatar(root.detail) | 69 | radius: "medium" |
389 | 72 | asynchronous: true | 70 | anchors.fill: parent |
390 | 73 | fillMode: Image.PreserveAspectCrop | 71 | image: Image { |
391 | 74 | // When updating the avatar using the content picker the temporary file returned | 72 | id: avatarImage |
392 | 75 | // can contain the same name as the previous one and if the cache is enabled this | 73 | |
393 | 76 | // will cause the image to not be updated | 74 | fillMode: Image.PreserveAspectCrop |
394 | 77 | cache: false | 75 | asynchronous: true |
395 | 78 | 76 | source: root.getAvatar(root.detail) | |
396 | 79 | Component { | 77 | height: units.gu(8) |
397 | 80 | id: loadingDialog | 78 | width: units.gu(8) |
398 | 81 | 79 | ||
399 | 82 | Popups.Dialog { | 80 | // When updating the avatar using the content picker the temporary file returned |
400 | 83 | id: dialogue | 81 | // can contain the same name as the previous one and if the cache is enabled this |
401 | 84 | 82 | // will cause the image to not be updated | |
402 | 85 | title: i18n.tr("Loading") | 83 | cache: false |
403 | 86 | 84 | } | |
404 | 87 | ActivityIndicator { | 85 | } |
405 | 88 | id: activity | 86 | |
406 | 89 | 87 | AvatarImport { | |
407 | 90 | anchors.centerIn: parent | 88 | id: avatarImport |
408 | 91 | running: true | 89 | |
409 | 92 | visible: running | 90 | onAvatarReceived: { |
410 | 93 | } | 91 | // remove the previous image, this is nessary to make sure that the new image |
411 | 94 | } | 92 | // get updated otherwise if the new image has the same name the image will not |
412 | 95 | } | 93 | // be updated |
413 | 96 | 94 | avatarImage.source = "" | |
414 | 97 | Icon { | 95 | // Update with the new value |
415 | 98 | anchors { | 96 | avatarImage.source = application.copyImage(root.contact, avatarUrl); |
416 | 99 | right: parent.right | 97 | } |
417 | 100 | rightMargin: units.gu(1.5) | 98 | } |
418 | 101 | bottom: parent.bottom | 99 | |
419 | 102 | bottomMargin: units.gu(2) | 100 | MouseArea { |
420 | 103 | } | 101 | anchors.fill: parent |
421 | 104 | width: units.gu(3) | 102 | onClicked: { |
422 | 105 | height: width | 103 | // make sure the OSK disappear |
423 | 106 | name: "import-image" | 104 | root.forceActiveFocus() |
424 | 107 | color: "white" | 105 | avatarImport.requestNewAvatar() |
334 | 108 | } | ||
335 | 109 | |||
336 | 110 | ContentPeer { | ||
337 | 111 | id: defaultSource | ||
338 | 112 | contentType: ContentType.Pictures | ||
339 | 113 | handler: ContentHandler.Source | ||
340 | 114 | selectionType: ContentTransfer.Single | ||
341 | 115 | } | ||
342 | 116 | |||
343 | 117 | MouseArea { | ||
344 | 118 | id: changeButton | ||
345 | 119 | |||
346 | 120 | property var activeTransfer | ||
347 | 121 | property var loadingDialog: null | ||
348 | 122 | |||
349 | 123 | anchors.fill: parent | ||
350 | 124 | onClicked: { | ||
351 | 125 | // make sure the OSK disappear | ||
352 | 126 | root.forceActiveFocus() | ||
353 | 127 | if (!changeButton.loadingDialog) { | ||
354 | 128 | changeButton.loadingDialog = PopupUtils.open(loadingDialog, null) | ||
355 | 129 | changeButton.activeTransfer = defaultSource.request(); | ||
356 | 130 | } | ||
357 | 131 | } | ||
358 | 132 | |||
359 | 133 | Connections { | ||
360 | 134 | target: changeButton.activeTransfer != null ? changeButton.activeTransfer : null | ||
361 | 135 | onStateChanged: { | ||
362 | 136 | var done = ((changeButton.activeTransfer.state === ContentTransfer.Charged) || | ||
363 | 137 | (changeButton.activeTransfer.state === ContentTransfer.Aborted)); | ||
364 | 138 | |||
365 | 139 | if (changeButton.activeTransfer.state === ContentTransfer.Charged) { | ||
366 | 140 | if (changeButton.activeTransfer.items.length > 0) { | ||
367 | 141 | // remove the previous image, this is nessary to make sure that the new image | ||
368 | 142 | // get updated otherwise if the new image has the same name the image will not | ||
369 | 143 | // be updated | ||
370 | 144 | avatarImage.source = "" | ||
371 | 145 | // Update with the new valu | ||
372 | 146 | avatarImage.source = application.copyImage(root.contact, changeButton.activeTransfer.items[0].url); | ||
373 | 147 | } | ||
374 | 148 | } | ||
375 | 149 | |||
376 | 150 | if (done) { | ||
377 | 151 | PopupUtils.close(changeButton.loadingDialog) | ||
378 | 152 | changeButton.loadingDialog = null | ||
379 | 153 | } | ||
380 | 154 | } | ||
381 | 155 | } | ||
425 | 156 | } | 106 | } |
426 | 157 | } | 107 | } |
427 | 158 | } | 108 | } |
428 | 159 | 109 | ||
429 | 110 | |||
430 | 160 | 111 | ||
431 | === modified file 'src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml' | |||
432 | --- src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml 2014-05-22 06:56:03 +0000 | |||
433 | +++ src/imports/ContactEdit/ContactDetailGroupWithTypeEditor.qml 2014-06-18 14:13:24 +0000 | |||
434 | @@ -95,7 +95,7 @@ | |||
435 | 95 | 95 | ||
436 | 96 | return changed | 96 | return changed |
437 | 97 | } | 97 | } |
439 | 98 | minimumHeight: units.gu(5) | 98 | |
440 | 99 | headerDelegate: ListItem.Empty { | 99 | headerDelegate: ListItem.Empty { |
441 | 100 | id: header | 100 | id: header |
442 | 101 | highlightWhenPressed: false | 101 | highlightWhenPressed: false |
443 | @@ -104,6 +104,9 @@ | |||
444 | 104 | height: units.gu(5) | 104 | height: units.gu(5) |
445 | 105 | // disable listview mouse area | 105 | // disable listview mouse area |
446 | 106 | __mouseArea.visible: false | 106 | __mouseArea.visible: false |
447 | 107 | divider.anchors.leftMargin: units.gu(2) | ||
448 | 108 | divider.anchors.rightMargin: units.gu(2) | ||
449 | 109 | |||
450 | 107 | Label { | 110 | Label { |
451 | 108 | anchors { | 111 | anchors { |
452 | 109 | verticalCenter: parent.verticalCenter | 112 | verticalCenter: parent.verticalCenter |
453 | @@ -117,35 +120,6 @@ | |||
454 | 117 | // style | 120 | // style |
455 | 118 | fontSize: "medium" | 121 | fontSize: "medium" |
456 | 119 | } | 122 | } |
457 | 120 | |||
458 | 121 | Icon { | ||
459 | 122 | objectName: "newDetailButton" | ||
460 | 123 | |||
461 | 124 | anchors { | ||
462 | 125 | verticalCenter: parent.verticalCenter | ||
463 | 126 | right: parent.right | ||
464 | 127 | rightMargin: units.gu(2) | ||
465 | 128 | } | ||
466 | 129 | width: units.gu(2) | ||
467 | 130 | height: units.gu(2) | ||
468 | 131 | name: "add" | ||
469 | 132 | } | ||
470 | 133 | |||
471 | 134 | // Mouse area fill all title area to avoid problems with swipe from the right gesture | ||
472 | 135 | MouseArea { | ||
473 | 136 | anchors.fill: parent | ||
474 | 137 | onClicked: { | ||
475 | 138 | if (detailQmlTypeName) { | ||
476 | 139 | var newDetail = Qt.createQmlObject("import QtContacts 5.0; " + detailQmlTypeName + "{}", root) | ||
477 | 140 | if (newDetail) { | ||
478 | 141 | var newDetailsCopy = root.newDetails | ||
479 | 142 | newDetailsCopy.push(newDetail) | ||
480 | 143 | root.newDetails = newDetailsCopy | ||
481 | 144 | root.contact.addDetail(newDetail) | ||
482 | 145 | } | ||
483 | 146 | } | ||
484 | 147 | } | ||
485 | 148 | } | ||
486 | 149 | } | 123 | } |
487 | 150 | 124 | ||
488 | 151 | detailDelegate: ContactDetailWithTypeEditor { | 125 | detailDelegate: ContactDetailWithTypeEditor { |
489 | 152 | 126 | ||
490 | === modified file 'src/imports/ContactEdit/ContactDetailNameEditor.qml' | |||
491 | --- src/imports/ContactEdit/ContactDetailNameEditor.qml 2014-05-09 20:00:09 +0000 | |||
492 | +++ src/imports/ContactEdit/ContactDetailNameEditor.qml 2014-06-18 14:13:24 +0000 | |||
493 | @@ -51,6 +51,7 @@ | |||
494 | 51 | return changed | 51 | return changed |
495 | 52 | } | 52 | } |
496 | 53 | 53 | ||
497 | 54 | spacing: units.gu(1) | ||
498 | 54 | detail: root.contact ? root.contact.name : null | 55 | detail: root.contact ? root.contact.name : null |
499 | 55 | fields: [ QtContacts.Name.FirstName, QtContacts.Name.LastName ] | 56 | fields: [ QtContacts.Name.FirstName, QtContacts.Name.LastName ] |
500 | 56 | 57 | ||
501 | 57 | 58 | ||
502 | === modified file 'src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml' | |||
503 | --- src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml 2014-05-28 15:22:38 +0000 | |||
504 | +++ src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml 2014-06-18 14:13:24 +0000 | |||
505 | @@ -84,6 +84,12 @@ | |||
506 | 84 | height: units.gu(4) | 84 | height: units.gu(4) |
507 | 85 | } | 85 | } |
508 | 86 | 86 | ||
509 | 87 | ListItem.ThinDivider { | ||
510 | 88 | id: divider | ||
511 | 89 | |||
512 | 90 | anchors.top: label.bottom | ||
513 | 91 | } | ||
514 | 92 | |||
515 | 87 | OptionSelector { | 93 | OptionSelector { |
516 | 88 | id: sources | 94 | id: sources |
517 | 89 | 95 | ||
518 | @@ -91,8 +97,8 @@ | |||
519 | 91 | anchors { | 97 | anchors { |
520 | 92 | left: parent.left | 98 | left: parent.left |
521 | 93 | leftMargin: units.gu(2) | 99 | leftMargin: units.gu(2) |
524 | 94 | top: label.bottom | 100 | top: divider.bottom |
525 | 95 | topMargin: units.gu(1) | 101 | topMargin: units.gu(2) |
526 | 96 | right: parent.right | 102 | right: parent.right |
527 | 97 | rightMargin: units.gu(2) | 103 | rightMargin: units.gu(2) |
528 | 98 | bottom: parent.bottom | 104 | bottom: parent.bottom |
529 | 99 | 105 | ||
530 | === modified file 'src/imports/ContactEdit/ContactDetailWithTypeEditor.qml' | |||
531 | --- src/imports/ContactEdit/ContactDetailWithTypeEditor.qml 2014-05-16 01:59:36 +0000 | |||
532 | +++ src/imports/ContactEdit/ContactDetailWithTypeEditor.qml 2014-06-18 14:13:24 +0000 | |||
533 | @@ -73,41 +73,19 @@ | |||
534 | 73 | enabled: root.detail ? !root.detail.readOnly : false | 73 | enabled: root.detail ? !root.detail.readOnly : false |
535 | 74 | implicitHeight: detailTypeSelector.height + fieldValues.height + units.gu(2) | 74 | implicitHeight: detailTypeSelector.height + fieldValues.height + units.gu(2) |
536 | 75 | opacity: enabled ? 1.0 : 0.5 | 75 | opacity: enabled ? 1.0 : 0.5 |
544 | 76 | ValueSelector { | 76 | |
545 | 77 | id: detailTypeSelector | 77 | Column { |
546 | 78 | objectName: detail ? "type_" + detailToString(detail.type, -1) + "_" + index : "" | 78 | id: fieldValues |
547 | 79 | 79 | ||
541 | 80 | readOnly: root.detail ? root.detail.readOnly : false | ||
542 | 81 | visible: (currentIndex != -1) | ||
543 | 82 | active: root.active | ||
548 | 83 | anchors { | 80 | anchors { |
549 | 84 | left: parent.left | 81 | left: parent.left |
551 | 85 | leftMargin: units.gu(3) | 82 | leftMargin: units.gu(2) |
552 | 86 | right: parent.right | 83 | right: parent.right |
553 | 87 | rightMargin: units.gu(2) | 84 | rightMargin: units.gu(2) |
554 | 88 | top: parent.top | 85 | top: parent.top |
555 | 89 | topMargin: units.gu(1) | 86 | topMargin: units.gu(1) |
556 | 90 | } | 87 | } |
557 | 91 | |||
558 | 92 | height: visible ? (root.active ? units.gu(4) : units.gu(3)) : 0 | ||
559 | 93 | onExpandedChanged: { | ||
560 | 94 | // Make sure that the inputfield get focus when clicking on type selector | ||
561 | 95 | if (expanded) { | ||
562 | 96 | root.forceActiveFocus() | ||
563 | 97 | } | ||
564 | 98 | } | ||
565 | 99 | } | ||
566 | 100 | |||
567 | 101 | Column { | ||
568 | 102 | id: fieldValues | ||
569 | 103 | |||
570 | 104 | anchors { | ||
571 | 105 | left: detailTypeSelector.left | ||
572 | 106 | right: detailTypeSelector.right | ||
573 | 107 | top: detailTypeSelector.bottom | ||
574 | 108 | } | ||
575 | 109 | height: childrenRect.height | 88 | height: childrenRect.height |
576 | 110 | |||
577 | 111 | Repeater { | 89 | Repeater { |
578 | 112 | id: fieldRepeater | 90 | id: fieldRepeater |
579 | 113 | 91 | ||
580 | @@ -141,4 +119,26 @@ | |||
581 | 141 | } | 119 | } |
582 | 142 | } | 120 | } |
583 | 143 | } | 121 | } |
584 | 122 | |||
585 | 123 | ValueSelector { | ||
586 | 124 | id: detailTypeSelector | ||
587 | 125 | objectName: detail ? "type_" + detailToString(detail.type, -1) + "_" + index : "" | ||
588 | 126 | |||
589 | 127 | anchors { | ||
590 | 128 | left: fieldValues.left | ||
591 | 129 | right: fieldValues.right | ||
592 | 130 | top: fieldValues.bottom | ||
593 | 131 | } | ||
594 | 132 | |||
595 | 133 | readOnly: root.detail ? root.detail.readOnly : false | ||
596 | 134 | visible: (currentIndex != -1) | ||
597 | 135 | active: root.active | ||
598 | 136 | height: visible ? (root.active ? units.gu(4) : units.gu(3)) : 0 | ||
599 | 137 | onExpandedChanged: { | ||
600 | 138 | // Make sure that the inputfield get focus when clicking on type selector | ||
601 | 139 | if (expanded) { | ||
602 | 140 | root.forceActiveFocus() | ||
603 | 141 | } | ||
604 | 142 | } | ||
605 | 143 | } | ||
606 | 144 | } | 144 | } |
607 | 145 | 145 | ||
608 | === modified file 'src/imports/ContactEdit/ContactEditor.qml' | |||
609 | --- src/imports/ContactEdit/ContactEditor.qml 2014-06-16 12:59:15 +0000 | |||
610 | +++ src/imports/ContactEdit/ContactEditor.qml 2014-06-18 14:13:24 +0000 | |||
611 | @@ -161,7 +161,7 @@ | |||
612 | 161 | fill: parent | 161 | fill: parent |
613 | 162 | bottomMargin: keyboard.height | 162 | bottomMargin: keyboard.height |
614 | 163 | } | 163 | } |
616 | 164 | contentHeight: contents.height | 164 | contentHeight: contents.height + units.gu(2) |
617 | 165 | contentWidth: parent.width | 165 | contentWidth: parent.width |
618 | 166 | 166 | ||
619 | 167 | //after add a new field we need to wait for the contentHeight to change to scroll to the correct position | 167 | //after add a new field we need to wait for the contentHeight to change to scroll to the correct position |
620 | @@ -172,32 +172,48 @@ | |||
621 | 172 | 172 | ||
622 | 173 | anchors { | 173 | anchors { |
623 | 174 | top: parent.top | 174 | top: parent.top |
624 | 175 | topMargin: units.gu(2) | ||
625 | 175 | left: parent.left | 176 | left: parent.left |
626 | 176 | right: parent.right | 177 | right: parent.right |
627 | 177 | } | 178 | } |
628 | 178 | height: childrenRect.height | 179 | height: childrenRect.height |
629 | 179 | 180 | ||
651 | 180 | ContactDetailNameEditor { | 181 | Row { |
652 | 181 | id: nameEditor | 182 | function save() |
653 | 182 | 183 | { | |
654 | 183 | 184 | var avatarSave = avatarEditor.save() | |
655 | 184 | anchors { | 185 | var nameSave = nameEditor.save(); |
656 | 185 | left: parent.left | 186 | |
657 | 186 | right: parent.right | 187 | return (nameSave || avatarSave); |
658 | 187 | } | 188 | } |
659 | 188 | height: nameEditor.implicitHeight + units.gu(3) | 189 | |
660 | 189 | contact: contactEditor.contact | 190 | function isEmpty() |
661 | 190 | } | 191 | { |
662 | 191 | 192 | return (avatarEditor.isEmpty() && nameEditor.isEmpty()) | |
663 | 192 | ContactDetailAvatarEditor { | 193 | } |
664 | 193 | id: avatarEditor | 194 | |
665 | 194 | 195 | anchors { | |
666 | 195 | contact: contactEditor.contact | 196 | left: parent.left |
667 | 196 | anchors { | 197 | leftMargin: units.gu(2) |
668 | 197 | left: parent.left | 198 | right: parent.right |
669 | 198 | right: parent.right | 199 | } |
670 | 199 | } | 200 | height: Math.max(avatarEditor.height, nameEditor.height) - units.gu(4) |
671 | 200 | height: implicitHeight | 201 | |
672 | 202 | ContactDetailAvatarEditor { | ||
673 | 203 | id: avatarEditor | ||
674 | 204 | |||
675 | 205 | contact: contactEditor.contact | ||
676 | 206 | height: implicitHeight | ||
677 | 207 | width: implicitWidth | ||
678 | 208 | } | ||
679 | 209 | |||
680 | 210 | ContactDetailNameEditor { | ||
681 | 211 | id: nameEditor | ||
682 | 212 | |||
683 | 213 | width: parent.width - avatarEditor.width | ||
684 | 214 | height: nameEditor.implicitHeight + units.gu(3) | ||
685 | 215 | contact: contactEditor.contact | ||
686 | 216 | } | ||
687 | 201 | } | 217 | } |
688 | 202 | 218 | ||
689 | 203 | ContactDetailPhoneNumbersEditor { | 219 | ContactDetailPhoneNumbersEditor { |
690 | @@ -272,13 +288,48 @@ | |||
691 | 272 | height: implicitHeight | 288 | height: implicitHeight |
692 | 273 | } | 289 | } |
693 | 274 | 290 | ||
695 | 275 | // We need this extra element to correct align the deleteButton | 291 | ListItem.ThinDivider {} |
696 | 292 | |||
697 | 276 | Item { | 293 | Item { |
698 | 277 | anchors { | 294 | anchors { |
699 | 278 | left: parent.left | 295 | left: parent.left |
700 | 279 | right: parent.right | 296 | right: parent.right |
701 | 280 | } | 297 | } |
703 | 281 | height: deleteButton.height + units.gu(2) | 298 | height: units.gu(2) |
704 | 299 | } | ||
705 | 300 | |||
706 | 301 | Row { | ||
707 | 302 | anchors { | ||
708 | 303 | left: parent.left | ||
709 | 304 | right: parent.right | ||
710 | 305 | margins: units.gu(2) | ||
711 | 306 | } | ||
712 | 307 | height: units.gu(6) | ||
713 | 308 | spacing: units.gu(2) | ||
714 | 309 | |||
715 | 310 | // WORKAROUND: SDK uses a old version of qtquick components | ||
716 | 311 | activeFocusOnTab: true | ||
717 | 312 | onActiveFocusChanged: { | ||
718 | 313 | if (activeFocus) { | ||
719 | 314 | addNewFieldButton.forceActiveFocus() | ||
720 | 315 | } | ||
721 | 316 | } | ||
722 | 317 | |||
723 | 318 | Button { | ||
724 | 319 | id: addNewFieldButton | ||
725 | 320 | objectName: "addNewFieldButton" | ||
726 | 321 | |||
727 | 322 | text: i18n.tr("Add Field") | ||
728 | 323 | gradient: UbuntuColors.greyGradient | ||
729 | 324 | anchors { | ||
730 | 325 | top: parent.top | ||
731 | 326 | bottom: parent.bottom | ||
732 | 327 | bottomMargin: units.gu(2) | ||
733 | 328 | } | ||
734 | 329 | width: (parent.width / 2) - units.gu(1) | ||
735 | 330 | |||
736 | 331 | onClicked: addFieldDialog.showOptions() | ||
737 | 332 | } | ||
738 | 282 | 333 | ||
739 | 283 | Button { | 334 | Button { |
740 | 284 | id: deleteButton | 335 | id: deleteButton |
741 | @@ -286,12 +337,11 @@ | |||
742 | 286 | text: i18n.tr("Delete") | 337 | text: i18n.tr("Delete") |
743 | 287 | visible: !contactEditor.isNewContact | 338 | visible: !contactEditor.isNewContact |
744 | 288 | anchors { | 339 | anchors { |
745 | 289 | margins: units.gu(2) | ||
746 | 290 | top: parent.top | 340 | top: parent.top |
749 | 291 | left: parent.left | 341 | bottom: parent.bottom |
750 | 292 | right: parent.right | 342 | bottomMargin: units.gu(2) |
751 | 293 | } | 343 | } |
753 | 294 | 344 | width: (parent.width / 2) - units.gu(1) | |
754 | 295 | onClicked: { | 345 | onClicked: { |
755 | 296 | var dialog = Popups.PopupUtils.open(removeContactDialog, null) | 346 | var dialog = Popups.PopupUtils.open(removeContactDialog, null) |
756 | 297 | dialog.contacts = [contactEditor.contact] | 347 | dialog.contacts = [contactEditor.contact] |
757 | @@ -351,6 +401,23 @@ | |||
758 | 351 | } | 401 | } |
759 | 352 | } | 402 | } |
760 | 353 | 403 | ||
761 | 404 | AddFieldDialog { | ||
762 | 405 | id: addFieldDialog | ||
763 | 406 | |||
764 | 407 | contact: contactEditor.contact | ||
765 | 408 | onFieldSelected: { | ||
766 | 409 | if (qmlTypeName) { | ||
767 | 410 | var newDetail = Qt.createQmlObject("import QtContacts 5.0; " + qmlTypeName + "{}", addFieldDialog) | ||
768 | 411 | if (newDetail) { | ||
769 | 412 | var newDetailsCopy = contactEditor.newDetails | ||
770 | 413 | newDetailsCopy.push(newDetail) | ||
771 | 414 | contactEditor.newDetails = newDetailsCopy | ||
772 | 415 | contactEditor.contact.addDetail(newDetail) | ||
773 | 416 | } | ||
774 | 417 | } | ||
775 | 418 | } | ||
776 | 419 | } | ||
777 | 420 | |||
778 | 354 | Component { | 421 | Component { |
779 | 355 | id: removeContactDialog | 422 | id: removeContactDialog |
780 | 356 | 423 | ||
781 | 357 | 424 | ||
782 | === modified file 'src/imports/ContactEdit/TextInputDetail.qml' | |||
783 | --- src/imports/ContactEdit/TextInputDetail.qml 2014-05-28 15:19:53 +0000 | |||
784 | +++ src/imports/ContactEdit/TextInputDetail.qml 2014-06-18 14:13:24 +0000 | |||
785 | @@ -80,6 +80,7 @@ | |||
786 | 80 | overlaySpacing: 0 | 80 | overlaySpacing: 0 |
787 | 81 | frameSpacing: 0 | 81 | frameSpacing: 0 |
788 | 82 | background: Item {} | 82 | background: Item {} |
789 | 83 | color: UbuntuColors.lightAubergine | ||
790 | 83 | } | 84 | } |
791 | 84 | onActiveFocusChanged: { | 85 | onActiveFocusChanged: { |
792 | 85 | if (activeFocus) { | 86 | if (activeFocus) { |
793 | 86 | 87 | ||
794 | === modified file 'src/imports/ContactEdit/ValueSelector.qml' | |||
795 | --- src/imports/ContactEdit/ValueSelector.qml 2014-06-06 17:52:58 +0000 | |||
796 | +++ src/imports/ContactEdit/ValueSelector.qml 2014-06-18 14:13:24 +0000 | |||
797 | @@ -59,22 +59,12 @@ | |||
798 | 59 | 59 | ||
799 | 60 | // FIXME: workaround to close list after a while. | 60 | // FIXME: workaround to close list after a while. |
800 | 61 | // we cant rely on focus since it hides the keyboard. | 61 | // we cant rely on focus since it hides the keyboard. |
801 | 62 | MouseArea { | ||
802 | 63 | anchors.fill: parent | ||
803 | 64 | visible: expanded | ||
804 | 65 | onPressed: { | ||
805 | 66 | mouse.accepted = false | ||
806 | 67 | timer.restart() | ||
807 | 68 | } | ||
808 | 69 | propagateComposedEvents: true | ||
809 | 70 | z: 1 | ||
810 | 71 | } | ||
811 | 72 | |||
812 | 73 | Timer { | 62 | Timer { |
813 | 74 | id: timer | 63 | id: timer |
814 | 64 | |||
815 | 75 | interval: 5000 | 65 | interval: 5000 |
816 | 66 | running: false | ||
817 | 76 | onTriggered: state = "" | 67 | onTriggered: state = "" |
818 | 77 | running: false | ||
819 | 78 | } | 68 | } |
820 | 79 | 69 | ||
821 | 80 | Item { | 70 | Item { |
822 | @@ -119,8 +109,12 @@ | |||
823 | 119 | 109 | ||
824 | 120 | MouseArea { | 110 | MouseArea { |
825 | 121 | anchors.fill: parent | 111 | anchors.fill: parent |
828 | 122 | propagateComposedEvents: true | 112 | onClicked: { |
829 | 123 | onClicked: if (!readOnly) root.state = "expanded" | 113 | if (!readOnly) { |
830 | 114 | root.state = "expanded" | ||
831 | 115 | timer.restart() | ||
832 | 116 | } | ||
833 | 117 | } | ||
834 | 124 | } | 118 | } |
835 | 125 | 119 | ||
836 | 126 | ListView { | 120 | ListView { |
837 | @@ -160,7 +154,10 @@ | |||
838 | 160 | width: parent.width + units.gu(0.5) | 154 | width: parent.width + units.gu(0.5) |
839 | 161 | height: parent.height + units.gu(0.5) | 155 | height: parent.height + units.gu(0.5) |
840 | 162 | anchors.centerIn: parent | 156 | anchors.centerIn: parent |
842 | 163 | onClicked: currentIndex = index | 157 | onClicked: { |
843 | 158 | currentIndex = index | ||
844 | 159 | timer.restart() | ||
845 | 160 | } | ||
846 | 164 | } | 161 | } |
847 | 165 | } | 162 | } |
848 | 166 | 163 | ||
849 | 167 | 164 | ||
850 | === modified file 'src/imports/ContactList/ContactListPage.qml' | |||
851 | --- src/imports/ContactList/ContactListPage.qml 2014-06-16 12:59:54 +0000 | |||
852 | +++ src/imports/ContactList/ContactListPage.qml 2014-06-18 14:13:24 +0000 | |||
853 | @@ -43,10 +43,7 @@ | |||
854 | 43 | function createEmptyContact(phoneNumber) { | 43 | function createEmptyContact(phoneNumber) { |
855 | 44 | var details = [ {detail: "PhoneNumber", field: "number", value: phoneNumber}, | 44 | var details = [ {detail: "PhoneNumber", field: "number", value: phoneNumber}, |
856 | 45 | {detail: "EmailAddress", field: "emailAddress", value: ""}, | 45 | {detail: "EmailAddress", field: "emailAddress", value: ""}, |
861 | 46 | {detail: "OnlineAccount", field: "accountUri", value: ""}, | 46 | {detail: "Name", field: "firstName", value: ""} |
858 | 47 | {detail: "Address", field: "street", value: ""}, | ||
859 | 48 | {detail: "Name", field: "firstName", value: ""}, | ||
860 | 49 | {detail: "Organization", field: "name", value: ""} | ||
862 | 50 | ] | 47 | ] |
863 | 51 | 48 | ||
864 | 52 | var newContact = Qt.createQmlObject("import QtContacts 5.0; Contact{ }", mainPage) | 49 | var newContact = Qt.createQmlObject("import QtContacts 5.0; Contact{ }", mainPage) |
865 | 53 | 50 | ||
866 | === modified file 'src/imports/ContactView/BasicFieldView.qml' | |||
867 | --- src/imports/ContactView/BasicFieldView.qml 2014-06-12 18:54:18 +0000 | |||
868 | +++ src/imports/ContactView/BasicFieldView.qml 2014-06-18 14:13:24 +0000 | |||
869 | @@ -50,8 +50,8 @@ | |||
870 | 50 | objectName: detail && fields ? "label_" + detailToString(detail.type, fields[index]) + "_" + root.parentIndex + "." + index : "" | 50 | objectName: detail && fields ? "label_" + detailToString(detail.type, fields[index]) + "_" + root.parentIndex + "." + index : "" |
871 | 51 | 51 | ||
872 | 52 | anchors { | 52 | anchors { |
875 | 53 | left: parent ? parent.left : null | 53 | left: parent ? parent.left : undefined |
876 | 54 | right: parent ? parent.right : null | 54 | right: parent ? parent.right : undefined |
877 | 55 | } | 55 | } |
878 | 56 | height: root.lineHeight | 56 | height: root.lineHeight |
879 | 57 | verticalAlignment: Text.AlignVCenter | 57 | verticalAlignment: Text.AlignVCenter |
880 | 58 | 58 | ||
881 | === modified file 'src/imports/ContactView/ContactDetailAvatarView.qml' | |||
882 | --- src/imports/ContactView/ContactDetailAvatarView.qml 2014-06-12 18:53:50 +0000 | |||
883 | +++ src/imports/ContactView/ContactDetailAvatarView.qml 2014-06-18 14:13:24 +0000 | |||
884 | @@ -24,9 +24,14 @@ | |||
885 | 24 | ContactDetailBase { | 24 | ContactDetailBase { |
886 | 25 | id: root | 25 | id: root |
887 | 26 | 26 | ||
889 | 27 | implicitHeight: units.gu(10) | 27 | implicitHeight: units.gu(8) |
890 | 28 | implicitWidth: units.gu(10) | 28 | implicitWidth: units.gu(10) |
891 | 29 | 29 | ||
892 | 30 | Connections { | ||
893 | 31 | target: root.contact.avatar | ||
894 | 32 | onDetailChanged: avatar.reload() | ||
895 | 33 | } | ||
896 | 34 | |||
897 | 30 | ContactsUI.ContactAvatar { | 35 | ContactsUI.ContactAvatar { |
898 | 31 | id: avatar | 36 | id: avatar |
899 | 32 | 37 | ||
900 | @@ -34,7 +39,6 @@ | |||
901 | 34 | anchors { | 39 | anchors { |
902 | 35 | fill: parent | 40 | fill: parent |
903 | 36 | leftMargin: units.gu(2) | 41 | leftMargin: units.gu(2) |
904 | 37 | topMargin: units.gu(2) | ||
905 | 38 | } | 42 | } |
906 | 39 | } | 43 | } |
907 | 40 | } | 44 | } |
908 | 41 | 45 | ||
909 | === modified file 'src/imports/ContactView/ContactDetailGroupWithTypeView.qml' | |||
910 | --- src/imports/ContactView/ContactDetailGroupWithTypeView.qml 2014-06-12 18:54:18 +0000 | |||
911 | +++ src/imports/ContactView/ContactDetailGroupWithTypeView.qml 2014-06-18 14:13:24 +0000 | |||
912 | @@ -31,6 +31,8 @@ | |||
913 | 31 | headerDelegate: ListItem.Empty { | 31 | headerDelegate: ListItem.Empty { |
914 | 32 | highlightWhenPressed: false | 32 | highlightWhenPressed: false |
915 | 33 | 33 | ||
916 | 34 | divider.anchors.leftMargin: units.gu(2) | ||
917 | 35 | divider.anchors.rightMargin: units.gu(2) | ||
918 | 34 | width: root.width | 36 | width: root.width |
919 | 35 | height: units.gu(5) | 37 | height: units.gu(5) |
920 | 36 | Label { | 38 | Label { |
921 | 37 | 39 | ||
922 | === modified file 'src/imports/ContactView/ContactView.qml' | |||
923 | --- src/imports/ContactView/ContactView.qml 2014-06-13 15:05:40 +0000 | |||
924 | +++ src/imports/ContactView/ContactView.qml 2014-06-18 14:13:24 +0000 | |||
925 | @@ -67,7 +67,7 @@ | |||
926 | 67 | anchors.fill: parent | 67 | anchors.fill: parent |
927 | 68 | //WORKAROUND: There is a bug on SDK page that causes the page to appear flicked with small contents | 68 | //WORKAROUND: There is a bug on SDK page that causes the page to appear flicked with small contents |
928 | 69 | // see bug #1223050 | 69 | // see bug #1223050 |
930 | 70 | contentHeight: Math.max(contents.height, parent.height) | 70 | contentHeight: Math.max(contents.height, parent.height) + units.gu(2) |
931 | 71 | contentWidth: parent.width | 71 | contentWidth: parent.width |
932 | 72 | visible: !busyIndicator.visible | 72 | visible: !busyIndicator.visible |
933 | 73 | 73 | ||
934 | @@ -77,6 +77,7 @@ | |||
935 | 77 | height: childrenRect.height | 77 | height: childrenRect.height |
936 | 78 | anchors { | 78 | anchors { |
937 | 79 | top: parent.top | 79 | top: parent.top |
938 | 80 | topMargin: units.gu(2) | ||
939 | 80 | left: parent.left | 81 | left: parent.left |
940 | 81 | right: parent.right | 82 | right: parent.right |
941 | 82 | } | 83 | } |
942 | 83 | 84 | ||
943 | === modified file 'src/imports/Ubuntu/Contacts/ContactAvatar.qml' | |||
944 | --- src/imports/Ubuntu/Contacts/ContactAvatar.qml 2014-06-06 17:52:58 +0000 | |||
945 | +++ src/imports/Ubuntu/Contacts/ContactAvatar.qml 2014-06-18 14:13:24 +0000 | |||
946 | @@ -24,7 +24,12 @@ | |||
947 | 24 | 24 | ||
948 | 25 | property var contactElement: null | 25 | property var contactElement: null |
949 | 26 | property string displayName: ContactsJS.formatToDisplay(contactElement, ContactDetail.Name, [Name.FirstName, Name.LastName]) | 26 | property string displayName: ContactsJS.formatToDisplay(contactElement, ContactDetail.Name, [Name.FirstName, Name.LastName]) |
951 | 27 | readonly property string avatarUrl: ContactsJS.getAvatar(contactElement, "") | 27 | property string avatarUrl: ContactsJS.getAvatar(contactElement, "") |
952 | 28 | |||
953 | 29 | function reload() | ||
954 | 30 | { | ||
955 | 31 | avatarUrl = ContactsJS.getAvatar(contactElement, "") | ||
956 | 32 | } | ||
957 | 28 | 33 | ||
958 | 29 | radius: "medium" | 34 | radius: "medium" |
959 | 30 | color: Theme.palette.normal.overlay | 35 | color: Theme.palette.normal.overlay |
960 | @@ -34,13 +39,16 @@ | |||
961 | 34 | text: ContactsJS.getNameItials(displayName) | 39 | text: ContactsJS.getNameItials(displayName) |
962 | 35 | font.pointSize: 88 | 40 | font.pointSize: 88 |
963 | 36 | color: UbuntuColors.lightAubergine | 41 | color: UbuntuColors.lightAubergine |
965 | 37 | visible: avatarUrl === "" | 42 | visible: (img.status != Image.Ready) |
966 | 38 | } | 43 | } |
967 | 39 | 44 | ||
968 | 40 | image: Image { | 45 | image: Image { |
969 | 46 | id: img | ||
970 | 47 | |||
971 | 41 | fillMode: Image.PreserveAspectCrop | 48 | fillMode: Image.PreserveAspectCrop |
972 | 42 | asynchronous: true | 49 | asynchronous: true |
973 | 43 | source: avatarUrl | 50 | source: avatarUrl |
975 | 44 | visible: source !== "" | 51 | height: avatar.height |
976 | 52 | width: avatar.width | ||
977 | 45 | } | 53 | } |
978 | 46 | } | 54 | } |
979 | 47 | 55 | ||
980 | === modified file 'src/imports/Ubuntu/Contacts/MultipleSelectionListView.qml' | |||
981 | --- src/imports/Ubuntu/Contacts/MultipleSelectionListView.qml 2014-06-06 17:52:58 +0000 | |||
982 | +++ src/imports/Ubuntu/Contacts/MultipleSelectionListView.qml 2014-06-18 14:13:24 +0000 | |||
983 | @@ -55,7 +55,7 @@ | |||
984 | 55 | \endqml | 55 | \endqml |
985 | 56 | */ | 56 | */ |
986 | 57 | 57 | ||
988 | 58 | UbuntuListView { | 58 | ListView { |
989 | 59 | id: listView | 59 | id: listView |
990 | 60 | 60 | ||
991 | 61 | /*! | 61 | /*! |
992 | @@ -188,4 +188,12 @@ | |||
993 | 188 | MultipleSelectionVisualModel { | 188 | MultipleSelectionVisualModel { |
994 | 189 | id: visualModel | 189 | id: visualModel |
995 | 190 | } | 190 | } |
996 | 191 | |||
997 | 192 | Component.onCompleted: { | ||
998 | 193 | // FIXME: workaround for qtubuntu not returning values depending on the grid unit definition | ||
999 | 194 | // for Flickable.maximumFlickVelocity and Flickable.flickDeceleration | ||
1000 | 195 | var scaleFactor = units.gridUnit / 8; | ||
1001 | 196 | maximumFlickVelocity = maximumFlickVelocity * scaleFactor; | ||
1002 | 197 | flickDeceleration = flickDeceleration * scaleFactor; | ||
1003 | 198 | } | ||
1004 | 191 | } | 199 | } |
1005 | 192 | 200 | ||
1006 | === modified file 'tests/autopilot/address_book_app/pages/_contact_editor.py' | |||
1007 | --- tests/autopilot/address_book_app/pages/_contact_editor.py 2014-05-22 12:50:28 +0000 | |||
1008 | +++ tests/autopilot/address_book_app/pages/_contact_editor.py 2014-06-18 14:13:24 +0000 | |||
1009 | @@ -51,6 +51,36 @@ | |||
1010 | 51 | class ContactEditor(_common.PageWithHeader): | 51 | class ContactEditor(_common.PageWithHeader): |
1011 | 52 | """Custom proxy object for the Contact Editor.""" | 52 | """Custom proxy object for the Contact Editor.""" |
1012 | 53 | 53 | ||
1013 | 54 | _DETAIL_ALIAS = { | ||
1014 | 55 | 'phones': 'Phone', | ||
1015 | 56 | 'emails': 'Email', | ||
1016 | 57 | 'ims': 'Social', | ||
1017 | 58 | 'addresses': 'Address', | ||
1018 | 59 | 'professionalDetails': 'Professional Details' | ||
1019 | 60 | } | ||
1020 | 61 | |||
1021 | 62 | @autopilot.logging.log_action(logger.info) | ||
1022 | 63 | def add_field(self, detail_name): | ||
1023 | 64 | """Create a new field into the edit contact form. | ||
1024 | 65 | |||
1025 | 66 | :param detail_name: The detail field name | ||
1026 | 67 | |||
1027 | 68 | """ | ||
1028 | 69 | |||
1029 | 70 | add_field_button = self.select_single( | ||
1030 | 71 | 'Button', objectName='addNewFieldButton') | ||
1031 | 72 | add_field_button.swipe_into_view() | ||
1032 | 73 | |||
1033 | 74 | self.pointing_device.click_object(add_field_button) | ||
1034 | 75 | |||
1035 | 76 | add_field_dialog = self.get_root_instance().wait_select_single( | ||
1036 | 77 | 'Dialog', objectName='addFieldDialog') | ||
1037 | 78 | new_field_button = add_field_dialog.select_single( | ||
1038 | 79 | 'Button', | ||
1039 | 80 | objectName=self._DETAIL_ALIAS[detail_name]) | ||
1040 | 81 | |||
1041 | 82 | self.pointing_device.click_object(new_field_button) | ||
1042 | 83 | |||
1043 | 54 | @autopilot.logging.log_action(logger.info) | 84 | @autopilot.logging.log_action(logger.info) |
1044 | 55 | def fill_form(self, contact_information): | 85 | def fill_form(self, contact_information): |
1045 | 56 | """Fill the edit contact form. | 86 | """Fill the edit contact form. |
1046 | @@ -90,7 +120,7 @@ | |||
1047 | 90 | def _fill_detail_group(self, object_name, details): | 120 | def _fill_detail_group(self, object_name, details): |
1048 | 91 | editor = self.select_single( | 121 | editor = self.select_single( |
1049 | 92 | ContactDetailGroupWithTypeEditor, objectName=object_name) | 122 | ContactDetailGroupWithTypeEditor, objectName=object_name) |
1051 | 93 | editor.fill(details) | 123 | editor.fill(self, details) |
1052 | 94 | 124 | ||
1053 | 95 | def _get_form_values(self): | 125 | def _get_form_values(self): |
1054 | 96 | first_name = _get_text_field(self, 'first_name').text | 126 | first_name = _get_text_field(self, 'first_name').text |
1055 | @@ -135,12 +165,12 @@ | |||
1056 | 135 | 'professionalDetails': 'base_unknown_{}' | 165 | 'professionalDetails': 'base_unknown_{}' |
1057 | 136 | } | 166 | } |
1058 | 137 | 167 | ||
1060 | 138 | def fill(self, details): | 168 | def fill(self, editor, details): |
1061 | 139 | """Fill a contact detail group.""" | 169 | """Fill a contact detail group.""" |
1063 | 140 | for index, detail in enumerate(details[:-1]): | 170 | for index, detail in enumerate(details): |
1064 | 171 | if self.detailsCount <= index: | ||
1065 | 172 | editor.add_field(self.objectName) | ||
1066 | 141 | self._fill_detail(index, detail) | 173 | self._fill_detail(index, detail) |
1067 | 142 | self._add_detail() | ||
1068 | 143 | self._fill_detail(len(details) - 1, details[-1]) | ||
1069 | 144 | 174 | ||
1070 | 145 | def _fill_detail(self, index, detail): | 175 | def _fill_detail(self, index, detail): |
1071 | 146 | detail_editor = self._get_detail_editor_by_index(index) | 176 | detail_editor = self._get_detail_editor_by_index(index) |
1072 | @@ -175,15 +205,16 @@ | |||
1073 | 175 | """Custom proxy object for the ContactDetailWithTypeEditor widget.""" | 205 | """Custom proxy object for the ContactDetailWithTypeEditor widget.""" |
1074 | 176 | 206 | ||
1075 | 177 | def fill(self, field, index, detail): | 207 | def fill(self, field, index, detail): |
1076 | 208 | self._fill_value(field, index, detail) | ||
1077 | 178 | self._select_type(detail) | 209 | self._select_type(detail) |
1078 | 179 | self._fill_value(field, index, detail) | ||
1079 | 180 | 210 | ||
1080 | 181 | def _select_type(self, detail): | 211 | def _select_type(self, detail): |
1081 | 182 | type_index = detail.TYPES.index(detail.type) | 212 | type_index = detail.TYPES.index(detail.type) |
1086 | 183 | selected_type_index = self._get_selected_type_index() | 213 | value_selector = self.select_single('ValueSelector') |
1087 | 184 | if type_index != selected_type_index: | 214 | |
1088 | 185 | # TODO --elopio - 2014-03-01 | 215 | while(value_selector.currentIndex != type_index): |
1089 | 186 | raise NotImplementedError('Type selection not yet implemented.') | 216 | ubuntuuitoolkit.get_keyboard().press_and_release("Shift+Right") |
1090 | 217 | time.sleep(0.1) | ||
1091 | 187 | 218 | ||
1092 | 188 | def _get_selected_type_index(self): | 219 | def _get_selected_type_index(self): |
1093 | 189 | value_selector = self.select_single('ValueSelector') | 220 | value_selector = self.select_single('ValueSelector') |
1094 | @@ -210,16 +241,7 @@ | |||
1095 | 210 | self._make_field_visible_and_write(text_field, value) | 241 | self._make_field_visible_and_write(text_field, value) |
1096 | 211 | 242 | ||
1097 | 212 | def _make_field_visible_and_write(self, text_field, value): | 243 | def _make_field_visible_and_write(self, text_field, value): |
1108 | 213 | while not text_field.activeFocus: | 244 | text_field.swipe_into_view() |
1099 | 214 | # XXX We should just swipe the text field into view. | ||
1100 | 215 | # Update this once bug http://pad.lv/1286479 is implemented. | ||
1101 | 216 | # --elopio - 2014-03-01 | ||
1102 | 217 | text_field.keyboard.press_and_release('Tab') | ||
1103 | 218 | time.sleep(0.1) | ||
1104 | 219 | contact_editor = self.get_root_instance().select_single( | ||
1105 | 220 | ContactEditor, objectName='contactEditorPage', active=True) | ||
1106 | 221 | contact_editor.wait_to_stop_moving() | ||
1107 | 222 | |||
1109 | 223 | text_field.write(value) | 245 | text_field.write(value) |
1110 | 224 | 246 | ||
1111 | 225 | def _fill_address(self, index, address): | 247 | def _fill_address(self, index, address): |
1112 | 226 | 248 | ||
1113 | === modified file 'tests/autopilot/address_book_app/tests/__init__.py' | |||
1114 | --- tests/autopilot/address_book_app/tests/__init__.py 2014-06-13 00:23:37 +0000 | |||
1115 | +++ tests/autopilot/address_book_app/tests/__init__.py 2014-06-18 14:13:24 +0000 | |||
1116 | @@ -143,6 +143,7 @@ | |||
1117 | 143 | self.pointing_device.click_object(clear_button) | 143 | self.pointing_device.click_object(clear_button) |
1118 | 144 | self.assertThat(field.text, Eventually(Equals(""))) | 144 | self.assertThat(field.text, Eventually(Equals(""))) |
1119 | 145 | 145 | ||
1120 | 146 | # FIXME: Remove this function use ContactEditor.add_field | ||
1121 | 146 | def create_new_detail(self, detailGroup): | 147 | def create_new_detail(self, detailGroup): |
1122 | 147 | detCount = detailGroup.detailsCount | 148 | detCount = detailGroup.detailsCount |
1123 | 148 | add_button = detailGroup.select_single("Icon", | 149 | add_button = detailGroup.select_single("Icon", |
1124 | @@ -155,9 +156,7 @@ | |||
1125 | 155 | list_page = self.main_window.get_contact_list_page() | 156 | list_page = self.main_window.get_contact_list_page() |
1126 | 156 | list_page.open_contact(index) | 157 | list_page.open_contact(index) |
1127 | 157 | 158 | ||
1128 | 158 | list_page = self.main_window.get_contact_list_page() | ||
1129 | 159 | self.assertThat(list_page.visible, Eventually(Equals(False))) | 159 | self.assertThat(list_page.visible, Eventually(Equals(False))) |
1130 | 160 | |||
1131 | 161 | view_page = self.main_window.get_contact_view_page() | 160 | view_page = self.main_window.get_contact_view_page() |
1132 | 162 | self.assertThat(view_page.visible, Eventually(Equals(True))) | 161 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1133 | 163 | 162 | ||
1134 | 164 | 163 | ||
1135 | === modified file 'tests/autopilot/address_book_app/tests/test_add_contact.py' | |||
1136 | --- tests/autopilot/address_book_app/tests/test_add_contact.py 2014-06-08 13:51:45 +0000 | |||
1137 | +++ tests/autopilot/address_book_app/tests/test_add_contact.py 2014-06-18 14:13:24 +0000 | |||
1138 | @@ -173,28 +173,23 @@ | |||
1139 | 173 | self.assertThat(list_view.count, Eventually(Equals(1))) | 173 | self.assertThat(list_view.count, Eventually(Equals(1))) |
1140 | 174 | 174 | ||
1141 | 175 | def test_email_label_save(self): | 175 | def test_email_label_save(self): |
1142 | 176 | # execute add new contact | ||
1143 | 177 | contact_editor = self.app.main_window.go_to_add_contact() | 176 | contact_editor = self.app.main_window.go_to_add_contact() |
1144 | 178 | 177 | ||
1148 | 179 | # fill name | 178 | my_emails = [] |
1149 | 180 | contact_editor.fill_form( | 179 | my_emails.append(data.Email(type_="Home", address="home@email.com")) |
1150 | 181 | data.Contact(first_name='Sherlock', last_name='Holmes')) | 180 | my_emails.append(data.Email(type_="Work", address="work@email.com")) |
1151 | 181 | my_emails.append(data.Email(type_="Other", address="other@email.com")) | ||
1152 | 182 | 182 | ||
1159 | 183 | # Home | 183 | test_contact = data.Contact(first_name="Sherlock", |
1160 | 184 | self.set_email_address(0, "home@email.com", 0) | 184 | last_name="Holmes", |
1161 | 185 | # Work | 185 | emails=my_emails) |
1162 | 186 | self.set_email_address(1, "work@email.com", 1) | 186 | contact_editor.fill_form(test_contact) |
1157 | 187 | # Other | ||
1158 | 188 | self.set_email_address(2, "other@email.com", 2) | ||
1163 | 189 | 187 | ||
1164 | 190 | # Save contact | 188 | # Save contact |
1165 | 191 | self.app.main_window.save() | 189 | self.app.main_window.save() |
1166 | 192 | 190 | ||
1167 | 193 | list_page = self.app.main_window.get_contact_list_page() | 191 | list_page = self.app.main_window.get_contact_list_page() |
1172 | 194 | list_page.open_contact(0) | 192 | view_page = list_page.open_contact(0) |
1169 | 195 | |||
1170 | 196 | # check if contacts was saved with the correct labels | ||
1171 | 197 | view_page = self.app.main_window.get_contact_view_page() | ||
1173 | 198 | self.assertThat(view_page.visible, Eventually(Equals(True))) | 193 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1174 | 199 | 194 | ||
1175 | 200 | # check if we have 3 emails""" | 195 | # check if we have 3 emails""" |
1176 | @@ -223,33 +218,26 @@ | |||
1177 | 223 | self.assertThat(len(emails), Equals(0)) | 218 | self.assertThat(len(emails), Equals(0)) |
1178 | 224 | 219 | ||
1179 | 225 | def test_phone_label_save(self): | 220 | def test_phone_label_save(self): |
1180 | 226 | # execute add new contact | ||
1181 | 227 | contact_editor = self.app.main_window.go_to_add_contact() | 221 | contact_editor = self.app.main_window.go_to_add_contact() |
1182 | 228 | 222 | ||
1186 | 229 | # fill name | 223 | my_phones = [] |
1187 | 230 | contact_editor.fill_form( | 224 | my_phones.append(data.Phone(type_="Home", number="(000) 000-0000")) |
1188 | 231 | data.Contact(first_name='Sherlock', last_name='Holmes')) | 225 | my_phones.append(data.Phone(type_="Work", number="(000) 000-0001")) |
1189 | 226 | my_phones.append(data.Phone(type_="Mobile", number="(000) 000-0002")) | ||
1190 | 227 | my_phones.append(data.Phone(type_="Work Mobile", number="(000) 000-0003")) | ||
1191 | 228 | my_phones.append(data.Phone(type_="Other", number="(000) 000-0004")) | ||
1192 | 232 | 229 | ||
1203 | 233 | # Home | 230 | test_contact = data.Contact(first_name="Sherlock", |
1204 | 234 | self.set_phone_number(0, "(000) 000-0000", 0) | 231 | last_name="Holmes", |
1205 | 235 | # Work | 232 | phones=my_phones) |
1206 | 236 | self.set_phone_number(1, "(000) 000-0001", 1) | 233 | contact_editor.fill_form(test_contact) |
1197 | 237 | # Mobile | ||
1198 | 238 | self.set_phone_number(2, "(000) 000-0002", 2) | ||
1199 | 239 | # Work Mobile | ||
1200 | 240 | self.set_phone_number(3, "(000) 000-0003", 3) | ||
1201 | 241 | # Other | ||
1202 | 242 | self.set_phone_number(4, "(000) 000-0004", 4) | ||
1207 | 243 | 234 | ||
1208 | 244 | # Save contact | 235 | # Save contact |
1209 | 245 | self.app.main_window.save() | 236 | self.app.main_window.save() |
1210 | 246 | 237 | ||
1211 | 247 | # Open contact view | 238 | # Open contact view |
1212 | 248 | list_page = self.app.main_window.get_contact_list_page() | 239 | list_page = self.app.main_window.get_contact_list_page() |
1217 | 249 | list_page.open_contact(0) | 240 | view_page = list_page.open_contact(0) |
1214 | 250 | |||
1215 | 251 | # check if contacts was saved with the correct labels | ||
1216 | 252 | view_page = self.app.main_window.get_contact_view_page() | ||
1218 | 253 | self.assertThat(view_page.visible, Eventually(Equals(True))) | 241 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1219 | 254 | 242 | ||
1220 | 255 | # check if we have five phones""" | 243 | # check if we have five phones""" |
1221 | 256 | 244 | ||
1222 | === modified file 'tests/autopilot/address_book_app/tests/test_edit_contact.py' | |||
1223 | --- tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-05-30 07:11:42 +0000 | |||
1224 | +++ tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-06-18 14:13:24 +0000 | |||
1225 | @@ -37,10 +37,7 @@ | |||
1226 | 37 | edit_page = self.edit_contact(0) | 37 | edit_page = self.edit_contact(0) |
1227 | 38 | 38 | ||
1228 | 39 | # Add a new phone | 39 | # Add a new phone |
1233 | 40 | phoneGroup = edit_page.select_single( | 40 | edit_page.add_field('phones') |
1230 | 41 | "ContactDetailGroupWithTypeEditor", | ||
1231 | 42 | objectName="phones") | ||
1232 | 43 | self.create_new_detail(phoneGroup) | ||
1234 | 44 | 41 | ||
1235 | 45 | # fill phone number | 42 | # fill phone number |
1236 | 46 | phone_number_1 = self.app.main_window.select_single( | 43 | phone_number_1 = self.app.main_window.select_single( |
1237 | @@ -67,11 +64,18 @@ | |||
1238 | 67 | self.assertThat(phone_label_1.text, Eventually(Equals(self.PHONE_NUMBERS[1]))) | 64 | self.assertThat(phone_label_1.text, Eventually(Equals(self.PHONE_NUMBERS[1]))) |
1239 | 68 | 65 | ||
1240 | 69 | def test_remove_phone(self): | 66 | def test_remove_phone(self): |
1243 | 70 | self.add_contact("Fulano", "de Tal", self.PHONE_NUMBERS[1:3]) | 67 | contact_editor = self.app.main_window.go_to_add_contact() |
1244 | 71 | edit_page = self.edit_contact(0) | 68 | my_phones = [] |
1245 | 69 | for n in self.PHONE_NUMBERS[1:3]: | ||
1246 | 70 | my_phones.append(data.Phone(type_='Mobile', number=n)) | ||
1247 | 71 | |||
1248 | 72 | test_contact = data.Contact(first_name="Fulano", | ||
1249 | 73 | last_name="de Tal", | ||
1250 | 74 | phones=my_phones) | ||
1251 | 75 | contact_editor.fill_form(test_contact) | ||
1252 | 72 | 76 | ||
1253 | 73 | # clear phone 1 | 77 | # clear phone 1 |
1255 | 74 | phone_number_1 = edit_page.select_single( | 78 | phone_number_1 = contact_editor.wait_select_single( |
1256 | 75 | "TextInputDetail", | 79 | "TextInputDetail", |
1257 | 76 | objectName="phoneNumber_1") | 80 | objectName="phoneNumber_1") |
1258 | 77 | self.clear_text_on_field(phone_number_1) | 81 | self.clear_text_on_field(phone_number_1) |
1259 | @@ -79,8 +83,11 @@ | |||
1260 | 79 | # Save contact | 83 | # Save contact |
1261 | 80 | self.app.main_window.save() | 84 | self.app.main_window.save() |
1262 | 81 | 85 | ||
1263 | 86 | # Go to contact view | ||
1264 | 87 | list_page = self.main_window.get_contact_list_page() | ||
1265 | 88 | |||
1266 | 82 | # check if we have onlye one phone | 89 | # check if we have onlye one phone |
1268 | 83 | view_page = self.app.main_window.get_contact_view_page() | 90 | view_page = list_page.open_contact(0) |
1269 | 84 | phone_group = view_page.select_single( | 91 | phone_group = view_page.select_single( |
1270 | 85 | "ContactDetailGroupWithTypeView", | 92 | "ContactDetailGroupWithTypeView", |
1271 | 86 | objectName="phones") | 93 | objectName="phones") |
1272 | @@ -95,11 +102,7 @@ | |||
1273 | 95 | def test_add_email(self): | 102 | def test_add_email(self): |
1274 | 96 | self.add_contact("Fulano", "") | 103 | self.add_contact("Fulano", "") |
1275 | 97 | edit_page = self.edit_contact(0) | 104 | edit_page = self.edit_contact(0) |
1281 | 98 | 105 | edit_page.add_field("emails") | |
1277 | 99 | emailGroup = edit_page.select_single( | ||
1278 | 100 | "ContactDetailGroupWithTypeEditor", | ||
1279 | 101 | objectName="emails") | ||
1280 | 102 | self.create_new_detail(emailGroup) | ||
1282 | 103 | 106 | ||
1283 | 104 | # fill email address | 107 | # fill email address |
1284 | 105 | email_field = edit_page.select_single( | 108 | email_field = edit_page.select_single( |
1285 | @@ -174,7 +177,17 @@ | |||
1286 | 174 | self.assertThat(view_page.title, Eventually(Equals("Fulano de Tal"))) | 177 | self.assertThat(view_page.title, Eventually(Equals("Fulano de Tal"))) |
1287 | 175 | 178 | ||
1288 | 176 | def test_im_type(self): | 179 | def test_im_type(self): |
1290 | 177 | self.add_contact("Fulano", "de Tal", im_address=["im@account.com"]) | 180 | contact_editor = self.app.main_window.go_to_add_contact() |
1291 | 181 | alias = data.SocialAlias(type_="Skype", alias="im@account.com") | ||
1292 | 182 | test_contact = data.Contact(first_name="Fulano", | ||
1293 | 183 | last_name="de Tal", | ||
1294 | 184 | social_aliases=[alias]) | ||
1295 | 185 | contact_editor.fill_form(test_contact) | ||
1296 | 186 | |||
1297 | 187 | # Save contact | ||
1298 | 188 | self.app.main_window.save() | ||
1299 | 189 | |||
1300 | 190 | # edit again | ||
1301 | 178 | edit_page = self.edit_contact(0) | 191 | edit_page = self.edit_contact(0) |
1302 | 179 | 192 | ||
1303 | 180 | # Change Im type | 193 | # Change Im type |
FAILED: Continuous integration, rev:193 jenkins. qa.ubuntu. com/job/ phablet- team-address- book-app- staging- ci/133/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/839 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 776 jenkins. qa.ubuntu. com/job/ phablet- team-address- book-app- staging- utopic- amd64-ci/ 133 jenkins. qa.ubuntu. com/job/ phablet- team-address- book-app- staging- utopic- armhf-ci/ 133 jenkins. qa.ubuntu. com/job/ phablet- team-address- book-app- staging- utopic- armhf-ci/ 133/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ phablet- team-address- book-app- staging- utopic- i386-ci/ 133/console jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/1254 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/1539 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/1539/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 8374 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 688/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/915 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/915/ artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/phablet- team-address- book-app- staging- ci/133/ rebuild
http://