Merge lp:~renatofilho/address-book-app/no-most-called into lp:address-book-app
- no-most-called
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Gustavo Pichorim Boiko |
Approved revision: | 667 |
Merged at revision: | 666 |
Proposed branch: | lp:~renatofilho/address-book-app/no-most-called |
Merge into: | lp:address-book-app |
Diff against target: |
822 lines (+1/-727) 9 files modified
debian/control (+1/-3) src/imports/Ubuntu/Contacts/CMakeLists.txt (+0/-4) src/imports/Ubuntu/Contacts/ContactListView.qml (+0/-13) src/imports/Ubuntu/Contacts/MostCalledList.qml (+0/-115) src/imports/Ubuntu/Contacts/MostCalledModel.qml (+0/-102) src/imports/Ubuntu/Contacts/mostcalledproxymodel.cpp (+0/-374) src/imports/Ubuntu/Contacts/mostcalledproxymodel.h (+0/-112) src/imports/Ubuntu/Contacts/plugin.cpp (+0/-2) src/imports/Ubuntu/Contacts/qmldir (+0/-2) |
To merge this branch: | bzr merge lp:~renatofilho/address-book-app/no-most-called |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gustavo Pichorim Boiko (community) | Approve | ||
system-apps-ci-bot | continuous-integration | Approve | |
Review via email: mp+313059@code.launchpad.net |
Commit message
Remove MostCalledList.
It will be moved to dialer-app.
Description of the change
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
- 667. By Renato Araujo Oliveira Filho
-
Remove 'qtdeclarative5
-ubuntu- content1' as dep for 's390x' arch.
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:667
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Gustavo Pichorim Boiko (boiko) wrote : | # |
Looks good!
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2016-11-24 18:54:55 +0000 | |||
3 | +++ debian/control 2016-12-14 13:04:55 +0000 | |||
4 | @@ -23,8 +23,7 @@ | |||
5 | 23 | qtdeclarative5-gsettings1.0 [amd64 armhf i386], | 23 | qtdeclarative5-gsettings1.0 [amd64 armhf i386], |
6 | 24 | qml-module-ofono [amd64 armhf i386], | 24 | qml-module-ofono [amd64 armhf i386], |
7 | 25 | qtdeclarative5-qtcontacts-plugin [amd64 armhf i386], | 25 | qtdeclarative5-qtcontacts-plugin [amd64 armhf i386], |
10 | 26 | qtdeclarative5-ubuntu-content1 [amd64 armhf i386 s390x], | 26 | qtdeclarative5-ubuntu-content1 [amd64 armhf i386], |
9 | 27 | qtdeclarative5-ubuntu-history0.1 [amd64 armhf i386], | ||
11 | 28 | qtdeclarative5-ubuntu-keyboard-extensions0.1 [amd64 armhf i386], | 27 | qtdeclarative5-ubuntu-keyboard-extensions0.1 [amd64 armhf i386], |
12 | 29 | qtdeclarative5-buteo-syncfw0.1 [amd64 armhf i386], | 28 | qtdeclarative5-buteo-syncfw0.1 [amd64 armhf i386], |
13 | 30 | qtdeclarative5-ubuntu-telephony-phonenumber0.1 [amd64 armhf i386], | 29 | qtdeclarative5-ubuntu-telephony-phonenumber0.1 [amd64 armhf i386], |
14 | @@ -59,7 +58,6 @@ | |||
15 | 59 | qtdeclarative5-qtquick2-plugin, | 58 | qtdeclarative5-qtquick2-plugin, |
16 | 60 | qml-module-ofono, | 59 | qml-module-ofono, |
17 | 61 | qtdeclarative5-ubuntu-addressbook0.1 (= ${binary:Version}), | 60 | qtdeclarative5-ubuntu-addressbook0.1 (= ${binary:Version}), |
18 | 62 | qtdeclarative5-ubuntu-history0.1, | ||
19 | 63 | qtdeclarative5-ubuntu-keyboard-extensions0.1, | 61 | qtdeclarative5-ubuntu-keyboard-extensions0.1, |
20 | 64 | qtdeclarative5-ubuntu-telephony-phonenumber0.1 (>= 0.1+14.10.20140715.1), | 62 | qtdeclarative5-ubuntu-telephony-phonenumber0.1 (>= 0.1+14.10.20140715.1), |
21 | 65 | ${misc:Depends}, | 63 | ${misc:Depends}, |
22 | 66 | 64 | ||
23 | === modified file 'src/imports/Ubuntu/Contacts/CMakeLists.txt' | |||
24 | --- src/imports/Ubuntu/Contacts/CMakeLists.txt 2016-01-22 14:51:39 +0000 | |||
25 | +++ src/imports/Ubuntu/Contacts/CMakeLists.txt 2016-12-14 13:04:55 +0000 | |||
26 | @@ -18,8 +18,6 @@ | |||
27 | 18 | FastScroll.qml | 18 | FastScroll.qml |
28 | 19 | ListItemWithActionsCheckBox.qml | 19 | ListItemWithActionsCheckBox.qml |
29 | 20 | ListItemWithActions.qml | 20 | ListItemWithActions.qml |
30 | 21 | MostCalledList.qml | ||
31 | 22 | MostCalledModel.qml | ||
32 | 23 | MultipleSelectionListView.qml | 21 | MultipleSelectionListView.qml |
33 | 24 | MultipleSelectionVisualModel.qml | 22 | MultipleSelectionVisualModel.qml |
34 | 25 | Ofono.qml | 23 | Ofono.qml |
35 | @@ -40,8 +38,6 @@ | |||
36 | 40 | contacts.cpp | 38 | contacts.cpp |
37 | 41 | imagescalethread.h | 39 | imagescalethread.h |
38 | 42 | imagescalethread.cpp | 40 | imagescalethread.cpp |
39 | 43 | mostcalledproxymodel.h | ||
40 | 44 | mostcalledproxymodel.cpp | ||
41 | 45 | plugin.h | 41 | plugin.h |
42 | 46 | plugin.cpp | 42 | plugin.cpp |
43 | 47 | simcardcontacts.h | 43 | simcardcontacts.h |
44 | 48 | 44 | ||
45 | === modified file 'src/imports/Ubuntu/Contacts/ContactListView.qml' | |||
46 | --- src/imports/Ubuntu/Contacts/ContactListView.qml 2016-09-19 20:47:48 +0000 | |||
47 | +++ src/imports/Ubuntu/Contacts/ContactListView.qml 2016-12-14 13:04:55 +0000 | |||
48 | @@ -570,19 +570,6 @@ | |||
49 | 570 | } | 570 | } |
50 | 571 | } | 571 | } |
51 | 572 | } | 572 | } |
52 | 573 | |||
53 | 574 | MostCalledList { | ||
54 | 575 | id: mostCalledView | ||
55 | 576 | |||
56 | 577 | anchors { | ||
57 | 578 | left: parent.left | ||
58 | 579 | right: parent.right | ||
59 | 580 | margins: units.gu(1) | ||
60 | 581 | } | ||
61 | 582 | parentView: view | ||
62 | 583 | visible: view.favouritesIsSelected | ||
63 | 584 | height: visible && (count > 0) ? childrenRect.height : 0 | ||
64 | 585 | } | ||
65 | 586 | } | 573 | } |
66 | 587 | onError: root.error(message) | 574 | onError: root.error(message) |
67 | 588 | onContactClicked: root.contactClicked(contact) | 575 | onContactClicked: root.contactClicked(contact) |
68 | 589 | 576 | ||
69 | === removed file 'src/imports/Ubuntu/Contacts/MostCalledList.qml' | |||
70 | --- src/imports/Ubuntu/Contacts/MostCalledList.qml 2016-05-05 15:55:23 +0000 | |||
71 | +++ src/imports/Ubuntu/Contacts/MostCalledList.qml 1970-01-01 00:00:00 +0000 | |||
72 | @@ -1,115 +0,0 @@ | |||
73 | 1 | /* | ||
74 | 2 | * Copyright (C) 2012-2014 Canonical, Ltd. | ||
75 | 3 | * | ||
76 | 4 | * This program is free software; you can redistribute it and/or modify | ||
77 | 5 | * it under the terms of the GNU General Public License as published by | ||
78 | 6 | * the Free Software Foundation; version 3. | ||
79 | 7 | * | ||
80 | 8 | * This program is distributed in the hope that it will be useful, | ||
81 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
82 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
83 | 11 | * GNU General Public License for more details. | ||
84 | 12 | * | ||
85 | 13 | * You should have received a copy of the GNU General Public License | ||
86 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
87 | 15 | */ | ||
88 | 16 | |||
89 | 17 | import QtQuick 2.4 | ||
90 | 18 | |||
91 | 19 | Column { | ||
92 | 20 | id: root | ||
93 | 21 | |||
94 | 22 | property alias parentView: scrollAnimation.target | ||
95 | 23 | readonly property alias count: callerRepeat.count | ||
96 | 24 | |||
97 | 25 | /* internal */ | ||
98 | 26 | property int _nextCurrentIndex: -1 | ||
99 | 27 | |||
100 | 28 | |||
101 | 29 | function makeItemVisible(item) | ||
102 | 30 | { | ||
103 | 31 | if (!item) { | ||
104 | 32 | return | ||
105 | 33 | } | ||
106 | 34 | |||
107 | 35 | var itemY = parent.y + root.y + item.y | ||
108 | 36 | var areaY = parentView.contentY | ||
109 | 37 | if (itemY < areaY) { | ||
110 | 38 | // move foward | ||
111 | 39 | scrollAnimation.to = itemY | ||
112 | 40 | } else if ((areaY + parentView.height) < (itemY + item.height)) { | ||
113 | 41 | // move backward | ||
114 | 42 | scrollAnimation.to = itemY + item.height | ||
115 | 43 | } else { | ||
116 | 44 | return | ||
117 | 45 | } | ||
118 | 46 | scrollAnimation.restart() | ||
119 | 47 | } | ||
120 | 48 | |||
121 | 49 | SmoothedAnimation { | ||
122 | 50 | id: scrollAnimation | ||
123 | 51 | |||
124 | 52 | property: "contentY" | ||
125 | 53 | velocity: parentView.highlightMoveVelocity | ||
126 | 54 | duration: parentView.highlightMoveDuration | ||
127 | 55 | } | ||
128 | 56 | |||
129 | 57 | SectionDelegate { | ||
130 | 58 | anchors { | ||
131 | 59 | left: parent.left | ||
132 | 60 | right: parent.right | ||
133 | 61 | margins: units.gu(2) | ||
134 | 62 | } | ||
135 | 63 | text: i18n.dtr("address-book-app", "Frequently called") | ||
136 | 64 | visible: (root.count > 0) | ||
137 | 65 | } | ||
138 | 66 | |||
139 | 67 | Repeater { | ||
140 | 68 | id: callerRepeat | ||
141 | 69 | |||
142 | 70 | model: MostCalledModel { | ||
143 | 71 | id: calledModel | ||
144 | 72 | |||
145 | 73 | onContactClicked: parentView.contactClicked(contact) | ||
146 | 74 | onAddContactClicked: parentView.addContactClicked(label) | ||
147 | 75 | onCurrentIndexChanged: { | ||
148 | 76 | if (currentIndex !== -1) { | ||
149 | 77 | parentView.currentIndex = -1 | ||
150 | 78 | root._nextCurrentIndex = currentIndex | ||
151 | 79 | } | ||
152 | 80 | } | ||
153 | 81 | } | ||
154 | 82 | } | ||
155 | 83 | |||
156 | 84 | Connections { | ||
157 | 85 | target: parentView | ||
158 | 86 | onCurrentIndexChanged: { | ||
159 | 87 | if (parentView.currentIndex !== -1) { | ||
160 | 88 | calledModel.currentIndex = -1 | ||
161 | 89 | } | ||
162 | 90 | } | ||
163 | 91 | } | ||
164 | 92 | |||
165 | 93 | onHeightChanged: { | ||
166 | 94 | if (root._nextCurrentIndex != -1) { | ||
167 | 95 | heightChangedTimeout.restart() | ||
168 | 96 | } | ||
169 | 97 | } | ||
170 | 98 | |||
171 | 99 | Timer { | ||
172 | 100 | id: heightChangedTimeout | ||
173 | 101 | interval: 100 | ||
174 | 102 | onTriggered: { | ||
175 | 103 | makeItemVisible(callerRepeat.itemAt(root._nextCurrentIndex)) | ||
176 | 104 | root._nextCurrentIndex = -1 | ||
177 | 105 | } | ||
178 | 106 | } | ||
179 | 107 | |||
180 | 108 | onVisibleChanged: { | ||
181 | 109 | // update the model every time that it became visible | ||
182 | 110 | // in fact calling update only reloads the model data if it has changed | ||
183 | 111 | if (visible) { | ||
184 | 112 | calledModel.model.update() | ||
185 | 113 | } | ||
186 | 114 | } | ||
187 | 115 | } | ||
188 | 116 | 0 | ||
189 | === removed file 'src/imports/Ubuntu/Contacts/MostCalledModel.qml' | |||
190 | --- src/imports/Ubuntu/Contacts/MostCalledModel.qml 2015-10-26 13:18:11 +0000 | |||
191 | +++ src/imports/Ubuntu/Contacts/MostCalledModel.qml 1970-01-01 00:00:00 +0000 | |||
192 | @@ -1,102 +0,0 @@ | |||
193 | 1 | /* | ||
194 | 2 | * Copyright (C) 2012-2015 Canonical, Ltd. | ||
195 | 3 | * | ||
196 | 4 | * This program is free software; you can redistribute it and/or modify | ||
197 | 5 | * it under the terms of the GNU General Public License as published by | ||
198 | 6 | * the Free Software Foundation; version 3. | ||
199 | 7 | * | ||
200 | 8 | * This program is distributed in the hope that it will be useful, | ||
201 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
202 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
203 | 11 | * GNU General Public License for more details. | ||
204 | 12 | * | ||
205 | 13 | * You should have received a copy of the GNU General Public License | ||
206 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
207 | 15 | */ | ||
208 | 16 | |||
209 | 17 | |||
210 | 18 | import QtQuick 2.4 | ||
211 | 19 | import QtContacts 5.0 | ||
212 | 20 | |||
213 | 21 | import Ubuntu.History 0.1 | ||
214 | 22 | import Ubuntu.Contacts 0.1 as ContactUI | ||
215 | 23 | |||
216 | 24 | VisualDataModel { | ||
217 | 25 | id: root | ||
218 | 26 | |||
219 | 27 | property var contactModel: null | ||
220 | 28 | property int currentIndex: -1 | ||
221 | 29 | property alias callAverage: mostCalledModel.callAverage | ||
222 | 30 | |||
223 | 31 | signal contactClicked(int index, QtObject contact) | ||
224 | 32 | signal addContactClicked(string label) | ||
225 | 33 | signal loaded() | ||
226 | 34 | |||
227 | 35 | property var baseModel: HistoryEventModel { | ||
228 | 36 | id: historyEventModel | ||
229 | 37 | |||
230 | 38 | type: HistoryThreadModel.EventTypeVoice | ||
231 | 39 | sort: HistorySort { | ||
232 | 40 | sortField: "timestamp" | ||
233 | 41 | sortOrder: HistorySort.DescendingOrder | ||
234 | 42 | } | ||
235 | 43 | filter: HistoryFilter { | ||
236 | 44 | filterProperty: "senderId" | ||
237 | 45 | filterValue: "self" | ||
238 | 46 | matchFlags: HistoryFilter.MatchCaseSensitive | ||
239 | 47 | } | ||
240 | 48 | onCanFetchMoreChanged: { | ||
241 | 49 | if (count === 0) { | ||
242 | 50 | mostCalledModel.update() | ||
243 | 51 | } | ||
244 | 52 | } | ||
245 | 53 | } | ||
246 | 54 | |||
247 | 55 | model: ContactUI.MostCalledContactsModel { | ||
248 | 56 | id: mostCalledModel | ||
249 | 57 | |||
250 | 58 | startInterval: new Date((new Date().getTime() - 2592000000)) // one month ago | ||
251 | 59 | maxCount: 5 | ||
252 | 60 | onLoaded: root.loaded() | ||
253 | 61 | sourceModel: historyEventModel | ||
254 | 62 | } | ||
255 | 63 | |||
256 | 64 | delegate: ContactDelegate { | ||
257 | 65 | id: contactDelegate | ||
258 | 66 | |||
259 | 67 | readonly property alias contact: contactFetch.contact | ||
260 | 68 | property var contents | ||
261 | 69 | |||
262 | 70 | defaultAvatarUrl: "image://theme/contacts" | ||
263 | 71 | width: parent ? parent.width : 0 | ||
264 | 72 | isCurrentItem: root.currentIndex === index | ||
265 | 73 | locked: true | ||
266 | 74 | |||
267 | 75 | // collapse the item before remove it, to avoid crash | ||
268 | 76 | ListView.onRemove: SequentialAnimation { | ||
269 | 77 | ScriptAction { | ||
270 | 78 | script: { | ||
271 | 79 | if (contactDelegate.state !== "") { | ||
272 | 80 | historyModel.currentIndex = -1 | ||
273 | 81 | } | ||
274 | 82 | } | ||
275 | 83 | } | ||
276 | 84 | } | ||
277 | 85 | |||
278 | 86 | onClicked: { | ||
279 | 87 | if (contact) { | ||
280 | 88 | root.contactClicked(index, contact) | ||
281 | 89 | } else { | ||
282 | 90 | root.addContactClicked(name.text) | ||
283 | 91 | } | ||
284 | 92 | } | ||
285 | 93 | |||
286 | 94 | // delegate does not support more than one child | ||
287 | 95 | contents: ContactFetch { | ||
288 | 96 | id: contactFetch | ||
289 | 97 | model: contactsModel | ||
290 | 98 | } | ||
291 | 99 | |||
292 | 100 | Component.onCompleted: contactFetch.fetchContact(contactId) | ||
293 | 101 | } | ||
294 | 102 | } | ||
295 | 103 | 0 | ||
296 | === removed file 'src/imports/Ubuntu/Contacts/mostcalledproxymodel.cpp' | |||
297 | --- src/imports/Ubuntu/Contacts/mostcalledproxymodel.cpp 2016-05-05 15:56:00 +0000 | |||
298 | +++ src/imports/Ubuntu/Contacts/mostcalledproxymodel.cpp 1970-01-01 00:00:00 +0000 | |||
299 | @@ -1,374 +0,0 @@ | |||
300 | 1 | /* | ||
301 | 2 | * Copyright (C) 2012-2015 Canonical, Ltd. | ||
302 | 3 | * | ||
303 | 4 | * This program is free software; you can redistribute it and/or modify | ||
304 | 5 | * it under the terms of the GNU General Public License as published by | ||
305 | 6 | * the Free Software Foundation; version 3. | ||
306 | 7 | * | ||
307 | 8 | * This program is distributed in the hope that it will be useful, | ||
308 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
309 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
310 | 11 | * GNU General Public License for more details. | ||
311 | 12 | * | ||
312 | 13 | * You should have received a copy of the GNU General Public License | ||
313 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
314 | 15 | */ | ||
315 | 16 | |||
316 | 17 | #include "mostcalledproxymodel.h" | ||
317 | 18 | |||
318 | 19 | #include <QtContacts/QContactManager> | ||
319 | 20 | #include <QtContacts/QContactFilter> | ||
320 | 21 | #include <QtContacts/QContactPhoneNumber> | ||
321 | 22 | #include <QtContacts/QContactFetchRequest> | ||
322 | 23 | |||
323 | 24 | #include <QDebug> | ||
324 | 25 | |||
325 | 26 | using namespace QtContacts; | ||
326 | 27 | |||
327 | 28 | bool mostCalledContactsModelDataGreaterThan(const MostCalledContactsModelData &d1, const MostCalledContactsModelData &d2) | ||
328 | 29 | { | ||
329 | 30 | return d1.callCount > d2.callCount; | ||
330 | 31 | } | ||
331 | 32 | |||
332 | 33 | MostCalledContactsModel::MostCalledContactsModel(QObject *parent) | ||
333 | 34 | : QAbstractListModel(parent), | ||
334 | 35 | m_sourceModel(0), | ||
335 | 36 | m_currentFetch(0), | ||
336 | 37 | m_manager(new QContactManager("galera")), | ||
337 | 38 | m_maxCount(20), | ||
338 | 39 | m_average(0), | ||
339 | 40 | m_outdated(true), | ||
340 | 41 | m_reloadingModel(false), | ||
341 | 42 | m_aboutToQuit(false) | ||
342 | 43 | { | ||
343 | 44 | connect(this, SIGNAL(sourceModelChanged(QAbstractItemModel*)), SLOT(markAsOutdated())); | ||
344 | 45 | connect(this, SIGNAL(maxCountChanged(uint)), SLOT(markAsOutdated())); | ||
345 | 46 | connect(this, SIGNAL(startIntervalChanged(QDateTime)), SLOT(markAsOutdated())); | ||
346 | 47 | } | ||
347 | 48 | |||
348 | 49 | MostCalledContactsModel::~MostCalledContactsModel() | ||
349 | 50 | { | ||
350 | 51 | m_aboutToQuit = true; | ||
351 | 52 | m_phones.clear(); | ||
352 | 53 | |||
353 | 54 | if (m_currentFetch) { | ||
354 | 55 | m_currentFetch->cancel(); | ||
355 | 56 | } | ||
356 | 57 | } | ||
357 | 58 | |||
358 | 59 | QVariant MostCalledContactsModel::data(const QModelIndex &index, int role) const | ||
359 | 60 | { | ||
360 | 61 | if (!index.isValid()) { | ||
361 | 62 | return QVariant(); | ||
362 | 63 | } | ||
363 | 64 | |||
364 | 65 | int row = index.row(); | ||
365 | 66 | if ((row >= 0) && (row < m_data.size())) { | ||
366 | 67 | switch (role) | ||
367 | 68 | { | ||
368 | 69 | case MostCalledContactsModel::ContactIdRole: | ||
369 | 70 | return m_data[row].contactId; | ||
370 | 71 | case MostCalledContactsModel::PhoneNumberRole: | ||
371 | 72 | return m_data[row].phoneNumber; | ||
372 | 73 | case MostCalledContactsModel::CallCountRole: | ||
373 | 74 | return m_data[row].callCount; | ||
374 | 75 | default: | ||
375 | 76 | return QVariant(); | ||
376 | 77 | } | ||
377 | 78 | } | ||
378 | 79 | return QVariant(); | ||
379 | 80 | } | ||
380 | 81 | |||
381 | 82 | QHash<int, QByteArray> MostCalledContactsModel::roleNames() const | ||
382 | 83 | { | ||
383 | 84 | static QHash<int, QByteArray> roles; | ||
384 | 85 | if (roles.isEmpty()) { | ||
385 | 86 | roles.insert(MostCalledContactsModel::ContactIdRole, "contactId"); | ||
386 | 87 | roles.insert(MostCalledContactsModel::PhoneNumberRole, "phoneNumber"); | ||
387 | 88 | roles.insert(MostCalledContactsModel::CallCountRole, "callCount"); | ||
388 | 89 | } | ||
389 | 90 | return roles; | ||
390 | 91 | } | ||
391 | 92 | |||
392 | 93 | int MostCalledContactsModel::rowCount(const QModelIndex &) const | ||
393 | 94 | { | ||
394 | 95 | return m_data.size(); | ||
395 | 96 | } | ||
396 | 97 | |||
397 | 98 | QAbstractItemModel *MostCalledContactsModel::sourceModel() const | ||
398 | 99 | { | ||
399 | 100 | return m_sourceModel; | ||
400 | 101 | } | ||
401 | 102 | |||
402 | 103 | void MostCalledContactsModel::setSourceModel(QAbstractItemModel *model) | ||
403 | 104 | { | ||
404 | 105 | if (m_sourceModel != model) { | ||
405 | 106 | if (m_sourceModel) { | ||
406 | 107 | disconnect(m_sourceModel); | ||
407 | 108 | } | ||
408 | 109 | |||
409 | 110 | m_sourceModel = model; | ||
410 | 111 | connect(m_sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(markAsOutdated())); | ||
411 | 112 | connect(m_sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(markAsOutdated())); | ||
412 | 113 | connect(m_sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(markAsOutdated())); | ||
413 | 114 | connect(m_sourceModel, SIGNAL(modelReset()), SLOT(markAsOutdated())); | ||
414 | 115 | |||
415 | 116 | Q_EMIT sourceModelChanged(m_sourceModel); | ||
416 | 117 | } | ||
417 | 118 | } | ||
418 | 119 | |||
419 | 120 | |||
420 | 121 | uint MostCalledContactsModel::maxCount() const | ||
421 | 122 | { | ||
422 | 123 | return m_maxCount; | ||
423 | 124 | } | ||
424 | 125 | |||
425 | 126 | void MostCalledContactsModel::setMaxCount(uint value) | ||
426 | 127 | { | ||
427 | 128 | if (m_maxCount != value) { | ||
428 | 129 | m_maxCount = value; | ||
429 | 130 | Q_EMIT maxCountChanged(m_maxCount); | ||
430 | 131 | } | ||
431 | 132 | } | ||
432 | 133 | |||
433 | 134 | int MostCalledContactsModel::callAverage() const | ||
434 | 135 | { | ||
435 | 136 | return m_average; | ||
436 | 137 | } | ||
437 | 138 | |||
438 | 139 | QDateTime MostCalledContactsModel::startInterval() const | ||
439 | 140 | { | ||
440 | 141 | return m_startInterval; | ||
441 | 142 | } | ||
442 | 143 | |||
443 | 144 | void MostCalledContactsModel::setStartInterval(const QDateTime &value) | ||
444 | 145 | { | ||
445 | 146 | if (m_startInterval != value) { | ||
446 | 147 | m_startInterval = value; | ||
447 | 148 | Q_EMIT startIntervalChanged(m_startInterval); | ||
448 | 149 | } | ||
449 | 150 | } | ||
450 | 151 | |||
451 | 152 | QVariant MostCalledContactsModel::getSourceData(int row, int role) | ||
452 | 153 | { | ||
453 | 154 | QAbstractItemModel *source = sourceModel(); | ||
454 | 155 | if (!source) { | ||
455 | 156 | return QVariant(); | ||
456 | 157 | } | ||
457 | 158 | |||
458 | 159 | while ((source->rowCount() <= row) && (source->canFetchMore(QModelIndex()))) { | ||
459 | 160 | source->fetchMore(QModelIndex()); | ||
460 | 161 | } | ||
461 | 162 | |||
462 | 163 | if (source->rowCount() < row) { | ||
463 | 164 | return QVariant(); | ||
464 | 165 | } | ||
465 | 166 | |||
466 | 167 | QModelIndex sourceIndex = source->index(row, 0); | ||
467 | 168 | return source->data(sourceIndex, role); | ||
468 | 169 | } | ||
469 | 170 | |||
470 | 171 | void MostCalledContactsModel::update() | ||
471 | 172 | { | ||
472 | 173 | // skip update if not necessary | ||
473 | 174 | if (!m_outdated || m_reloadingModel) { | ||
474 | 175 | return; | ||
475 | 176 | } | ||
476 | 177 | |||
477 | 178 | if (m_maxCount <= 0) { | ||
478 | 179 | qWarning() << "update model requested with invalid maxCount"; | ||
479 | 180 | m_outdated = false; | ||
480 | 181 | return; | ||
481 | 182 | } | ||
482 | 183 | |||
483 | 184 | if (!m_startInterval.isValid()) { | ||
484 | 185 | qWarning() << "Update model requested with invalid startInterval"; | ||
485 | 186 | m_outdated = false; | ||
486 | 187 | return; | ||
487 | 188 | } | ||
488 | 189 | |||
489 | 190 | QAbstractItemModel *source = sourceModel(); | ||
490 | 191 | if (!source) { | ||
491 | 192 | qWarning() << "Update model requested with null source model"; | ||
492 | 193 | m_outdated = false; | ||
493 | 194 | return; | ||
494 | 195 | } | ||
495 | 196 | |||
496 | 197 | m_totalCalls = 0; | ||
497 | 198 | m_phones.clear(); | ||
498 | 199 | m_phoneToContactCache.clear(); | ||
499 | 200 | m_contactsData.clear(); | ||
500 | 201 | queryContacts(); | ||
501 | 202 | } | ||
502 | 203 | |||
503 | 204 | void MostCalledContactsModel::queryContacts() | ||
504 | 205 | { | ||
505 | 206 | // get all phone in the date inteval | ||
506 | 207 | QHash<int, QByteArray> roles = sourceModel()->roleNames(); | ||
507 | 208 | int participantsRole = roles.key("participants", -1); | ||
508 | 209 | int timestampRole = roles.key("timestamp", -1); | ||
509 | 210 | int row = 0; | ||
510 | 211 | |||
511 | 212 | Q_ASSERT(participantsRole != -1); | ||
512 | 213 | Q_ASSERT(timestampRole != -1); | ||
513 | 214 | |||
514 | 215 | while(true) { | ||
515 | 216 | QVariant date = getSourceData(row, timestampRole); | ||
516 | 217 | |||
517 | 218 | // end of source model | ||
518 | 219 | if (date.isNull()) { | ||
519 | 220 | break; | ||
520 | 221 | } | ||
521 | 222 | |||
522 | 223 | // exit if date is out of interval | ||
523 | 224 | if (date.toDateTime() < m_startInterval) { | ||
524 | 225 | break; | ||
525 | 226 | } | ||
526 | 227 | |||
527 | 228 | QVariant data = getSourceData(row, participantsRole); | ||
528 | 229 | if (data.isValid()) { | ||
529 | 230 | const QVariantList participants = data.toList(); | ||
530 | 231 | Q_FOREACH(const QVariant &map, participants) { | ||
531 | 232 | const QString phone = map.toMap().value("identifier").toString(); | ||
532 | 233 | if (!phone.isEmpty()) | ||
533 | 234 | m_phones << phone; | ||
534 | 235 | } | ||
535 | 236 | } | ||
536 | 237 | |||
537 | 238 | // next row | ||
538 | 239 | row++; | ||
539 | 240 | } | ||
540 | 241 | |||
541 | 242 | // query for all phones | ||
542 | 243 | nextContact(); | ||
543 | 244 | } | ||
544 | 245 | |||
545 | 246 | void MostCalledContactsModel::nextContact() | ||
546 | 247 | { | ||
547 | 248 | if (m_phones.isEmpty()) { | ||
548 | 249 | parseResult(); | ||
549 | 250 | return; | ||
550 | 251 | } | ||
551 | 252 | |||
552 | 253 | QString nextPhone = m_phones.takeFirst(); | ||
553 | 254 | |||
554 | 255 | if (m_phoneToContactCache.contains(nextPhone)) { | ||
555 | 256 | registerCall(nextPhone, m_phoneToContactCache.value(nextPhone)); | ||
556 | 257 | nextContact(); | ||
557 | 258 | return; | ||
558 | 259 | } else { | ||
559 | 260 | QContactFilter filter(QContactPhoneNumber::match(nextPhone)); | ||
560 | 261 | QContactFetchHint hint; | ||
561 | 262 | hint.setDetailTypesHint(QList<QContactDetail::DetailType>() << QContactDetail::TypeGuid); | ||
562 | 263 | |||
563 | 264 | m_currentFetch = new QContactFetchRequest; | ||
564 | 265 | m_currentFetch->setProperty("PHONE", nextPhone); | ||
565 | 266 | m_currentFetch->setFilter(filter); | ||
566 | 267 | m_currentFetch->setFetchHint(hint); | ||
567 | 268 | m_currentFetch->setManager(m_manager.data()); | ||
568 | 269 | |||
569 | 270 | connect(m_currentFetch, | ||
570 | 271 | SIGNAL(stateChanged(QContactAbstractRequest::State)), | ||
571 | 272 | SLOT(fetchContactIdDone())); | ||
572 | 273 | |||
573 | 274 | m_currentFetch->start(); | ||
574 | 275 | } | ||
575 | 276 | } | ||
576 | 277 | |||
577 | 278 | void MostCalledContactsModel::fetchContactIdDone() | ||
578 | 279 | { | ||
579 | 280 | Q_ASSERT(m_currentFetch); | ||
580 | 281 | |||
581 | 282 | if (m_aboutToQuit) { | ||
582 | 283 | m_currentFetch->deleteLater(); | ||
583 | 284 | m_currentFetch = 0; | ||
584 | 285 | return; | ||
585 | 286 | } | ||
586 | 287 | |||
587 | 288 | if (m_currentFetch->state() == QContactAbstractRequest::ActiveState) { | ||
588 | 289 | return; | ||
589 | 290 | } | ||
590 | 291 | |||
591 | 292 | if (!m_currentFetch->contacts().isEmpty()) { | ||
592 | 293 | QString id = m_currentFetch->contacts().at(0).id().toString(); | ||
593 | 294 | registerCall(m_currentFetch->property("PHONE").toString(), id); | ||
594 | 295 | } | ||
595 | 296 | m_currentFetch->deleteLater(); | ||
596 | 297 | m_currentFetch = 0; | ||
597 | 298 | nextContact(); | ||
598 | 299 | } | ||
599 | 300 | |||
600 | 301 | void MostCalledContactsModel::registerCall(const QString &phone, const QString &contactId) | ||
601 | 302 | { | ||
602 | 303 | // update cache | ||
603 | 304 | m_phoneToContactCache.insert(phone, contactId); | ||
604 | 305 | |||
605 | 306 | if (m_contactsData.contains(contactId)) { | ||
606 | 307 | MostCalledContactsModelData &data = m_contactsData[contactId]; | ||
607 | 308 | data.callCount++; | ||
608 | 309 | } else { | ||
609 | 310 | MostCalledContactsModelData data; | ||
610 | 311 | data.contactId = contactId; | ||
611 | 312 | data.phoneNumber = phone; | ||
612 | 313 | data.callCount = 1; | ||
613 | 314 | m_contactsData.insert(contactId, data); | ||
614 | 315 | } | ||
615 | 316 | m_totalCalls++; | ||
616 | 317 | } | ||
617 | 318 | |||
618 | 319 | void MostCalledContactsModel::parseResult() | ||
619 | 320 | { | ||
620 | 321 | if (m_aboutToQuit) { | ||
621 | 322 | return; | ||
622 | 323 | } | ||
623 | 324 | |||
624 | 325 | Q_EMIT beginResetModel(); | ||
625 | 326 | |||
626 | 327 | m_reloadingModel = true; | ||
627 | 328 | m_outdated = false; | ||
628 | 329 | m_data.clear(); | ||
629 | 330 | m_average = 0; | ||
630 | 331 | |||
631 | 332 | if (!m_contactsData.isEmpty()) { | ||
632 | 333 | // sort by callCount | ||
633 | 334 | QList<MostCalledContactsModelData> data = m_contactsData.values(); | ||
634 | 335 | qSort(data.begin(), data.end(), mostCalledContactsModelDataGreaterThan); | ||
635 | 336 | |||
636 | 337 | // average | ||
637 | 338 | m_average = qRound(((qreal) (m_totalCalls)) / m_contactsData.size()); | ||
638 | 339 | Q_FOREACH(const MostCalledContactsModelData &d, data) { | ||
639 | 340 | if (d.callCount >= m_average) { | ||
640 | 341 | m_data << d; | ||
641 | 342 | } | ||
642 | 343 | if ((uint) m_data.size() >= m_maxCount) { | ||
643 | 344 | break; | ||
644 | 345 | } | ||
645 | 346 | } | ||
646 | 347 | } | ||
647 | 348 | |||
648 | 349 | m_totalCalls = 0; | ||
649 | 350 | m_phones.clear(); | ||
650 | 351 | m_phoneToContactCache.clear(); | ||
651 | 352 | m_contactsData.clear(); | ||
652 | 353 | |||
653 | 354 | Q_EMIT endResetModel(); | ||
654 | 355 | m_reloadingModel = false; | ||
655 | 356 | Q_EMIT callAverageChanged(m_average); | ||
656 | 357 | Q_EMIT loaded(); | ||
657 | 358 | } | ||
658 | 359 | |||
659 | 360 | |||
660 | 361 | void MostCalledContactsModel::markAsOutdated() | ||
661 | 362 | { | ||
662 | 363 | // skip if model is being reloaded | ||
663 | 364 | if (m_reloadingModel) { | ||
664 | 365 | return; | ||
665 | 366 | } | ||
666 | 367 | |||
667 | 368 | if (!m_outdated) { | ||
668 | 369 | m_outdated = true; | ||
669 | 370 | Q_EMIT outdatedChange(m_outdated); | ||
670 | 371 | } | ||
671 | 372 | } | ||
672 | 373 | |||
673 | 374 | |||
674 | 375 | 0 | ||
675 | === removed file 'src/imports/Ubuntu/Contacts/mostcalledproxymodel.h' | |||
676 | --- src/imports/Ubuntu/Contacts/mostcalledproxymodel.h 2015-05-07 17:27:16 +0000 | |||
677 | +++ src/imports/Ubuntu/Contacts/mostcalledproxymodel.h 1970-01-01 00:00:00 +0000 | |||
678 | @@ -1,112 +0,0 @@ | |||
679 | 1 | /* | ||
680 | 2 | * Copyright (C) 2012-2015 Canonical, Ltd. | ||
681 | 3 | * | ||
682 | 4 | * This program is free software; you can redistribute it and/or modify | ||
683 | 5 | * it under the terms of the GNU General Public License as published by | ||
684 | 6 | * the Free Software Foundation; version 3. | ||
685 | 7 | * | ||
686 | 8 | * This program is distributed in the hope that it will be useful, | ||
687 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
688 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
689 | 11 | * GNU General Public License for more details. | ||
690 | 12 | * | ||
691 | 13 | * You should have received a copy of the GNU General Public License | ||
692 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
693 | 15 | */ | ||
694 | 16 | |||
695 | 17 | #ifndef __MOSTCALLEDCONTACTSMODEL_H__ | ||
696 | 18 | #define __MOSTCALLEDCONTACTSMODEL_H__ | ||
697 | 19 | |||
698 | 20 | |||
699 | 21 | #include <QtCore/QAbstractListModel> | ||
700 | 22 | #include <QtCore/QScopedPointer> | ||
701 | 23 | #include <QtCore/QDateTime> | ||
702 | 24 | #include <QtCore/QMap> | ||
703 | 25 | |||
704 | 26 | #include <QtContacts/QContactManager> | ||
705 | 27 | #include <QtContacts/QContactFetchRequest> | ||
706 | 28 | |||
707 | 29 | struct MostCalledContactsModelData | ||
708 | 30 | { | ||
709 | 31 | QString contactId; | ||
710 | 32 | QString phoneNumber; | ||
711 | 33 | int callCount; | ||
712 | 34 | }; | ||
713 | 35 | |||
714 | 36 | class MostCalledContactsModel : public QAbstractListModel | ||
715 | 37 | { | ||
716 | 38 | Q_OBJECT | ||
717 | 39 | Q_PROPERTY(QAbstractItemModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) | ||
718 | 40 | Q_PROPERTY(uint maxCount READ maxCount WRITE setMaxCount NOTIFY maxCountChanged) | ||
719 | 41 | Q_PROPERTY(int callAverage READ callAverage NOTIFY callAverageChanged) | ||
720 | 42 | Q_PROPERTY(QDateTime startInterval READ startInterval WRITE setStartInterval NOTIFY startIntervalChanged) | ||
721 | 43 | Q_PROPERTY(bool outdated READ outdated NOTIFY outdatedChange) | ||
722 | 44 | |||
723 | 45 | public: | ||
724 | 46 | enum Role { | ||
725 | 47 | ContactIdRole = 0, | ||
726 | 48 | PhoneNumberRole, | ||
727 | 49 | CallCountRole | ||
728 | 50 | }; | ||
729 | 51 | |||
730 | 52 | MostCalledContactsModel(QObject *parent=0); | ||
731 | 53 | ~MostCalledContactsModel(); | ||
732 | 54 | |||
733 | 55 | QVariant data(const QModelIndex &index, int role) const; | ||
734 | 56 | QHash<int, QByteArray> roleNames() const; | ||
735 | 57 | int rowCount(const QModelIndex&) const; | ||
736 | 58 | |||
737 | 59 | QAbstractItemModel *sourceModel() const; | ||
738 | 60 | void setSourceModel(QAbstractItemModel *model); | ||
739 | 61 | |||
740 | 62 | uint maxCount() const; | ||
741 | 63 | void setMaxCount(uint value); | ||
742 | 64 | |||
743 | 65 | int callAverage() const; | ||
744 | 66 | bool outdated() const; | ||
745 | 67 | |||
746 | 68 | QDateTime startInterval() const; | ||
747 | 69 | void setStartInterval(const QDateTime &value); | ||
748 | 70 | |||
749 | 71 | Q_INVOKABLE void update(); | ||
750 | 72 | |||
751 | 73 | Q_SIGNALS: | ||
752 | 74 | void maxCountChanged(uint value); | ||
753 | 75 | void callAverageChanged(int value); | ||
754 | 76 | void startIntervalChanged(const QDateTime &value); | ||
755 | 77 | void sourceModelChanged(QAbstractItemModel *value); | ||
756 | 78 | void outdatedChange(bool value); | ||
757 | 79 | void loaded(); | ||
758 | 80 | |||
759 | 81 | private Q_SLOTS: | ||
760 | 82 | void markAsOutdated(); | ||
761 | 83 | void fetchContactIdDone(); | ||
762 | 84 | |||
763 | 85 | private: | ||
764 | 86 | QAbstractItemModel *m_sourceModel; | ||
765 | 87 | QtContacts::QContactFetchRequest *m_currentFetch; | ||
766 | 88 | |||
767 | 89 | QScopedPointer<QtContacts::QContactManager> m_manager; | ||
768 | 90 | QList<MostCalledContactsModelData> m_data; | ||
769 | 91 | uint m_maxCount; | ||
770 | 92 | int m_average; | ||
771 | 93 | QDateTime m_startInterval; | ||
772 | 94 | bool m_outdated; | ||
773 | 95 | bool m_reloadingModel; | ||
774 | 96 | bool m_aboutToQuit; | ||
775 | 97 | |||
776 | 98 | QStringList m_phones; | ||
777 | 99 | QMap<QString, QString> m_phoneToContactCache; | ||
778 | 100 | QMap<QString, MostCalledContactsModelData > m_contactsData; | ||
779 | 101 | int m_totalCalls; | ||
780 | 102 | |||
781 | 103 | void fetchContactId(const QString &phoneNumber); | ||
782 | 104 | QVariant getSourceData(int row, int role); | ||
783 | 105 | void queryContacts(); | ||
784 | 106 | void nextContact(); | ||
785 | 107 | void registerCall(const QString &phone, const QString &contactId); | ||
786 | 108 | void parseResult(); | ||
787 | 109 | }; | ||
788 | 110 | |||
789 | 111 | |||
790 | 112 | #endif | ||
791 | 113 | 0 | ||
792 | === modified file 'src/imports/Ubuntu/Contacts/plugin.cpp' | |||
793 | --- src/imports/Ubuntu/Contacts/plugin.cpp 2015-05-07 17:27:16 +0000 | |||
794 | +++ src/imports/Ubuntu/Contacts/plugin.cpp 2016-12-14 13:04:55 +0000 | |||
795 | @@ -15,7 +15,6 @@ | |||
796 | 15 | */ | 15 | */ |
797 | 16 | 16 | ||
798 | 17 | #include "plugin.h" | 17 | #include "plugin.h" |
799 | 18 | #include "mostcalledproxymodel.h" | ||
800 | 19 | #include "contacts.h" | 18 | #include "contacts.h" |
801 | 20 | #include "simcardcontacts.h" | 19 | #include "simcardcontacts.h" |
802 | 21 | 20 | ||
803 | @@ -39,6 +38,5 @@ | |||
804 | 39 | { | 38 | { |
805 | 40 | // @uri Ubuntu.Contacts | 39 | // @uri Ubuntu.Contacts |
806 | 41 | qmlRegisterSingletonType<UbuntuContacts>(uri, 0, 1, "Contacts", contactsProvider); | 40 | qmlRegisterSingletonType<UbuntuContacts>(uri, 0, 1, "Contacts", contactsProvider); |
807 | 42 | qmlRegisterType<MostCalledContactsModel>(uri, 0, 1, "MostCalledContactsModel"); | ||
808 | 43 | qmlRegisterType<SimCardContacts>(uri, 0, 1, "SimCardContacts"); | 41 | qmlRegisterType<SimCardContacts>(uri, 0, 1, "SimCardContacts"); |
809 | 44 | } | 42 | } |
810 | 45 | 43 | ||
811 | === modified file 'src/imports/Ubuntu/Contacts/qmldir' | |||
812 | --- src/imports/Ubuntu/Contacts/qmldir 2015-10-23 11:03:31 +0000 | |||
813 | +++ src/imports/Ubuntu/Contacts/qmldir 2016-12-14 13:04:55 +0000 | |||
814 | @@ -28,8 +28,6 @@ | |||
815 | 28 | internal FastScrollJs FastScroll.js | 28 | internal FastScrollJs FastScroll.js |
816 | 29 | internal FastScroll FastScroll.qml | 29 | internal FastScroll FastScroll.qml |
817 | 30 | internal ListItemWithActionsCheckBox ListItemWithActionsCheckBox.qml | 30 | internal ListItemWithActionsCheckBox ListItemWithActionsCheckBox.qml |
818 | 31 | internal MostCalledList MostCalledList.qml | ||
819 | 32 | internal MostCalledModel MostCalledModel.qml | ||
820 | 33 | internal Ofono Ofono.qml | 31 | internal Ofono Ofono.qml |
821 | 34 | internal SectionDelegate SectionDelegate.qml | 32 | internal SectionDelegate SectionDelegate.qml |
822 | 35 | internal SubtitledWithColors SubtitledWithColors.qml | 33 | internal SubtitledWithColors SubtitledWithColors.qml |
PASSED: Continuous integration, rev:666 /jenkins. canonical. com/system- apps/job/ lp-address- book-app- ci/52/ /jenkins. canonical. com/system- apps/job/ build/2180 /jenkins. canonical. com/system- apps/job/ test-0- autopkgtest/ label=phone- armhf,release= vivid+overlay, testname= default/ 562 /jenkins. canonical. com/system- apps/job/ build-0- fetch/2183 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 2010/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2010/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= zesty/2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= zesty/2010/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 2010/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2010/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= zesty/2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= zesty/2010/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 2010/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2010/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= zesty/2010 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= zesty/2010/ artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/system- apps/job/ lp-address- book-app- ci/52/rebuild
https:/