Merge lp:~renatofilho/address-book-app/disable-bottomEdge-on-multiple-column-mode into lp:address-book-app
- disable-bottomEdge-on-multiple-column-mode
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Bill Filler | ||||
Approved revision: | 568 | ||||
Merged at revision: | 537 | ||||
Proposed branch: | lp:~renatofilho/address-book-app/disable-bottomEdge-on-multiple-column-mode | ||||
Merge into: | lp:address-book-app | ||||
Prerequisite: | lp:~renatofilho/address-book-app/visuals-update | ||||
Diff against target: |
886 lines (+304/-125) 19 files modified
data/address-book-app.desktop.in.in (+0/-1) src/app/addressbookapp.cpp (+1/-1) src/imports/ABAdaptivePageLayout.qml (+50/-0) src/imports/ABContactListPage.qml (+124/-59) src/imports/ABContactViewPage.qml (+26/-23) src/imports/ABMultiColumnEmptyState.qml (+30/-2) src/imports/ABNewContactBottomEdge.qml (+2/-1) src/imports/CMakeLists.txt (+1/-0) src/imports/MainWindow.qml (+2/-3) src/imports/Settings/SettingsDefaultSyncTarget.qml (+2/-7) src/imports/Settings/SettingsPage.qml (+27/-9) src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml (+1/-1) src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml (+1/-7) src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml (+1/-1) src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml (+18/-0) src/imports/Ubuntu/Contacts/ContactDelegate.qml (+1/-1) src/imports/Ubuntu/Contacts/ContactListView.qml (+12/-6) src/imports/Ubuntu/Contacts/ContactSimpleListView.qml (+0/-2) src/imports/Ubuntu/Contacts/ListItemWithActions.qml (+5/-1) |
||||
To merge this branch: | bzr merge lp:~renatofilho/address-book-app/disable-bottomEdge-on-multiple-column-mode | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+284913@code.launchpad.net |
Commit message
Add "add new" bottom in the header and disable bottom edge hint on second column, if the app is running on multiple columns mode.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 538. By Renato Araujo Oliveira Filho
-
Use 'Contacts' as application title.
- 539. By Renato Araujo Oliveira Filho
-
clean up empty state text, leave right hand column blank.
- 540. By Renato Araujo Oliveira Filho
-
Hide contact list import options after bottom edge commit.
- 541. By Renato Araujo Oliveira Filho
-
Use 'Add field' as label for Add field button.
- 542. By Renato Araujo Oliveira Filho
-
Reduce the font size used by contact name field.
- 543. By Renato Araujo Oliveira Filho
-
Change selected visual for ListItemWithAct
ions. - 544. By Renato Araujo Oliveira Filho
-
Fixed default account component aligned
- 545. By Renato Araujo Oliveira Filho
-
Use themed colors for contact delegate text.
- 546. By Renato Araujo Oliveira Filho
-
Parent merged.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:546
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 547. By Renato Araujo Oliveira Filho
-
Update visuals for selected items.
- 548. By Renato Araujo Oliveira Filho
-
Remove icons from contact sync targe option selection.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:548
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 549. By Renato Araujo Oliveira Filho
-
Remove shortcut "ctrl+n" from "New contact" button, leave it on bottom edge action.
- 550. By Renato Araujo Oliveira Filho
-
Disable add new buttom when the bottom edge is already open.
Collapse bottom edge if the contact list receives focus.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:550
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 551. By Renato Araujo Oliveira Filho
-
reorder 'new-contact' button to make it always visible.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:551
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 552. By Renato Araujo Oliveira Filho
-
Remove side stage hint from desktop file.
- 553. By Renato Araujo Oliveira Filho
-
Update selected color for list items.
- 554. By Renato Araujo Oliveira Filho
-
Make sure that "new contact" item is visible when bottom edge is open.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:554
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 555. By Renato Araujo Oliveira Filho
-
Does not select 'new contact' button if keyboard is not present.
- 556. By Renato Araujo Oliveira Filho
-
Cancel edit before push a new view page, to avoid problems with adaptive layout.
Check bug #1544745
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:556
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 557. By Renato Araujo Oliveira Filho
-
Does not collapse bottom edge whe contact list receives focus.
- 558. By Renato Araujo Oliveira Filho
-
Does not scroll the contact list to the top when hiding the "new contact" button.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:558
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 559. By Renato Araujo Oliveira Filho
-
Does not select a contact on app startup.
Use sync functions to push Contact view and Empty state. - 560. By Renato Araujo Oliveira Filho
-
Collapse bottom edge when start searching on settings page is pushed.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:559
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:560
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 561. By Renato Araujo Oliveira Filho
-
Move 'ctrl+n' shortcut to header button.
Make sure that pageStack.bottomEdge is null after destroy pages. - 562. By Renato Araujo Oliveira Filho
-
Select first contact while searching
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:561
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 563. By Renato Araujo Oliveira Filho
-
Avoid push empty page twice.
Remove empty page title.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:562
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 564. By Renato Araujo Oliveira Filho
-
Sett bottom edge as null while settings page is opened.
- 565. By Renato Araujo Oliveira Filho
-
Fix bottom edge shortcut on single column mode.
Avoid re-create event page view.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:563
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 566. By Renato Araujo Oliveira Filho
-
Use 'incubator.
forceCompletion ()' to make adaptive layout syncronous. - 567. By Renato Araujo Oliveira Filho
-
Remove unecessary functions from ABAdaptivePageL
ayout.
Push edit page sync over contact view. - 568. By Renato Araujo Oliveira Filho
-
Remove debugs.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:565
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:568
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'data/address-book-app.desktop.in.in' |
2 | --- data/address-book-app.desktop.in.in 2015-06-10 18:52:25 +0000 |
3 | +++ data/address-book-app.desktop.in.in 2016-02-13 02:36:44 +0000 |
4 | @@ -11,7 +11,6 @@ |
5 | Icon=@ADDRESS_BOOK_ARTWORK_PATH@/@ADDRESS_BOOK_APP_ICON@ |
6 | X-Ubuntu-SymbolicIcon=@ADDRESS_BOOK_ARTWORK_PATH@/@ADDRESS_BOOK_APP_SYMBOLIC_ICON@ |
7 | X-Ubuntu-Touch=true |
8 | -X-Ubuntu-StageHint=SideStage |
9 | X-Ubuntu-Single-Instance=true |
10 | X-Ubuntu-Splash-Show-Header=true |
11 | X-Ubuntu-Supported-Orientations=portrait |
12 | |
13 | === modified file 'src/app/addressbookapp.cpp' |
14 | --- src/app/addressbookapp.cpp 2016-01-06 20:47:58 +0000 |
15 | +++ src/app/addressbookapp.cpp 2016-02-13 02:36:44 +0000 |
16 | @@ -194,7 +194,7 @@ |
17 | m_view->setMinimumWidth(300); |
18 | m_view->setMinimumHeight(500); |
19 | m_view->setResizeMode(QQuickView::SizeRootObjectToView); |
20 | - m_view->setTitle("AddressBook"); |
21 | + m_view->setTitle("Contacts"); |
22 | qDebug() << "New import path:" << QCoreApplication::applicationDirPath() + "/" + importPath(""); |
23 | m_view->engine()->addImportPath(QCoreApplication::applicationDirPath() + "/" + importPath("")); |
24 | m_view->engine()->addImportPath(UNITY8_QML_PATH); |
25 | |
26 | === added file 'src/imports/ABAdaptivePageLayout.qml' |
27 | --- src/imports/ABAdaptivePageLayout.qml 1970-01-01 00:00:00 +0000 |
28 | +++ src/imports/ABAdaptivePageLayout.qml 2016-02-13 02:36:44 +0000 |
29 | @@ -0,0 +1,50 @@ |
30 | +/* |
31 | + * Copyright (C) 2012-2015 Canonical, Ltd. |
32 | + * |
33 | + * This program is free software; you can redistribute it and/or modify |
34 | + * it under the terms of the GNU General Public License as published by |
35 | + * the Free Software Foundation; version 3. |
36 | + * |
37 | + * This program is distributed in the hope that it will be useful, |
38 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
39 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
40 | + * GNU General Public License for more details. |
41 | + * |
42 | + * You should have received a copy of the GNU General Public License |
43 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
44 | + */ |
45 | + |
46 | +import QtQuick 2.0 |
47 | +import Ubuntu.Components 1.3 |
48 | + |
49 | +AdaptivePageLayout { |
50 | + id: layout |
51 | + |
52 | + function addFileToNextColumnSync(parentObject, resolvedUrl, properties) { |
53 | + return addComponentToNextColumnSync(parentObject, Qt.createComponent(resolvedUrl), properties) |
54 | + } |
55 | + |
56 | + function addFileToCurrentColumnSync(parentObject, resolvedUrl, properties) { |
57 | + return addComponentToCurrentColumnSync(parentObject, Qt.createComponent(resolvedUrl), properties) |
58 | + } |
59 | + |
60 | + function addComponentToNextColumnSync(parentObject, component, properties) { |
61 | + if (typeof(properties) === 'undefined') { |
62 | + properties = {} |
63 | + } |
64 | + |
65 | + var incubator = layout.addPageToNextColumn(parentObject, component, properties) |
66 | + incubator.forceCompletion() |
67 | + return incubator.object |
68 | + } |
69 | + |
70 | + function addComponentToCurrentColumnSync(parentObject, component, properties) { |
71 | + if (typeof(properties) === 'undefined') { |
72 | + properties = {} |
73 | + } |
74 | + |
75 | + var incubator = layout.addPageToCurrentColumn(parentObject, component, properties) |
76 | + incubator.forceCompletion() |
77 | + return incubator.object |
78 | + } |
79 | +} |
80 | |
81 | === modified file 'src/imports/ABContactListPage.qml' |
82 | --- src/imports/ABContactListPage.qml 2016-01-06 18:54:25 +0000 |
83 | +++ src/imports/ABContactListPage.qml 2016-02-13 02:36:44 +0000 |
84 | @@ -32,6 +32,7 @@ |
85 | objectName: "contactListPage" |
86 | |
87 | property var viewPage: null |
88 | + property var emptyPage: null |
89 | property bool pickMode: false |
90 | property alias contentHubTransfer: contactExporter.activeTransfer |
91 | property bool pickMultipleContacts: false |
92 | @@ -73,19 +74,26 @@ |
93 | } |
94 | } |
95 | |
96 | - function openViewPage(viewPageProperties) { |
97 | - var component = Qt.createComponent(Qt.resolvedUrl("ABContactViewPage.qml")) |
98 | - var incubator = pageStack.addPageToNextColumn(mainPage, component, viewPageProperties) |
99 | - if (incubator && (incubator.status === Component.Loading)) { |
100 | - incubator.onStatusChanged = function(status) { |
101 | - if (status === Component.Ready) |
102 | - mainPage.viewPage = incubator.object |
103 | - } |
104 | - } else if (incubator && incubator.status ===- Component.Ready) { |
105 | - mainPage.viewPage = incubator.object |
106 | - } else { |
107 | - mainPage.viewPage = null |
108 | - } |
109 | + function clearViewPage() |
110 | + { |
111 | + viewPage = null |
112 | + } |
113 | + |
114 | + function openViewPage(viewPageProperties) |
115 | + { |
116 | + if (currentViewContactId === viewPageProperties.contact.contactId) { |
117 | + return |
118 | + } |
119 | + |
120 | + if (viewPage) { |
121 | + viewPage.Component.onDestruction.disconnect(clearViewPage) |
122 | + } |
123 | + |
124 | + pageStack.removePages(mainPage) |
125 | + viewPage = null |
126 | + |
127 | + viewPage = pageStack.addFileToNextColumnSync(mainPage, Qt.resolvedUrl("ABContactViewPage.qml"), viewPageProperties) |
128 | + viewPage.Component.onDestruction.connect(clearViewPage) |
129 | } |
130 | |
131 | function showContact(contact) |
132 | @@ -105,6 +113,51 @@ |
133 | contact: contact}); |
134 | } |
135 | |
136 | + function showEmptyPage(openBottomEdge) |
137 | + { |
138 | + if (pageStack.columns === 1) |
139 | + return |
140 | + |
141 | + if (!emptyPage) { |
142 | + contactList.currentIndex = -1 |
143 | + pageStack.removePages(mainPage) |
144 | + |
145 | + if (pageStack.columns > 1) { |
146 | + emptyPage = pageStack.addFileToNextColumnSync(pageStack.primaryPage, |
147 | + Qt.resolvedUrl("ABMultiColumnEmptyState.qml"), |
148 | + { 'headerTitle': "", |
149 | + 'pageStack': mainPage.pageStack }) |
150 | + emptyPage.Component.onDestruction.connect(function() { |
151 | + mainPage.emptyPage = null |
152 | + }) |
153 | + |
154 | + } |
155 | + } |
156 | + if (openBottomEdge) { |
157 | + mainPage.emptyPage.commitBottomEdge() |
158 | + } |
159 | + |
160 | + } |
161 | + |
162 | + function showSettingsPage() |
163 | + { |
164 | + pageStack.removePages(mainPage) |
165 | + |
166 | + var incubator = pageStack.addPageToNextColumn(mainPage, |
167 | + Qt.resolvedUrl("./Settings/SettingsPage.qml"), |
168 | + {"contactListModel": contactList.listModel}) |
169 | + incubator.onStatusChanged = function(status) { |
170 | + if (status === Component.Ready) { |
171 | + incubator.object.onActiveChanged.connect(function(active) { |
172 | + if (!incubator.object.active) { |
173 | + mainPage.delayFetchContact() |
174 | + contactList.forceActiveFocus() |
175 | + } |
176 | + }) |
177 | + } |
178 | + } |
179 | + } |
180 | + |
181 | function showContactWithId(contactId) |
182 | { |
183 | openViewPage({model: contactList.listModel, |
184 | @@ -169,18 +222,19 @@ |
185 | |
186 | function fetchContact() |
187 | { |
188 | - if ((contactList.currentIndex >= 0) && (pageStack.columns > 1)) { |
189 | - var currentContact = contactList.listModel.contacts[contactList.currentIndex] |
190 | + if (pageStack.columns > 1 && !contactList.showNewContact) { |
191 | + var currentContact = null |
192 | + if (contactList.currentIndex >= 0) |
193 | + currentContact = contactList.listModel.contacts[contactList.currentIndex] |
194 | + |
195 | if (!currentContact) { |
196 | - var component = Qt.createComponent(Qt.resolvedUrl("ABMultiColumnEmptyState.qml")) |
197 | - var searching = contactList.filterTerm !== "" |
198 | - pageStack.addPageToNextColumn(mainPage, component, |
199 | - { headerTitle: searching ? i18n.tr("No contact found") : i18n.tr("No contacts") }) |
200 | + showEmptyPage() |
201 | + return |
202 | + } else if (currentContact && (mainPage.currentViewContactId === currentContact.contactId)) { |
203 | return |
204 | } |
205 | - if (currentContact && (mainPage.currentViewContactId === currentContact.contactId)) |
206 | - return |
207 | |
208 | + console.debug("Will fetch new contact") |
209 | contactList.view._fetchContact(contactList.currentIndex, currentContact) |
210 | } |
211 | } |
212 | @@ -242,7 +296,7 @@ |
213 | focus: true |
214 | showImportOptions: !mainPage.pickMode && |
215 | pageStack.bottomEdge && |
216 | - (pageStack.bottomEdge.status === BottomEdge.Hidden) |
217 | + (pageStack.bottomEdge.status !== BottomEdge.Committed) |
218 | anchors { |
219 | top: parent.top |
220 | topMargin: pageHeader.height |
221 | @@ -255,7 +309,7 @@ |
222 | multiSelectionEnabled: true |
223 | multipleSelection: (mainPage.pickMode && mainPage.pickMultipleContacts) || !mainPage.pickMode |
224 | showNewContact: (pageStack.columns > 1) && pageStack.bottomEdge && (pageStack.bottomEdge.status === BottomEdge.Committed) |
225 | - highlightSelected: pageStack.hasKeyboard && !mainPage._creatingContact |
226 | + highlightSelected: !showNewContact && pageStack.hasKeyboard && !mainPage._creatingContact |
227 | onAddContactClicked: mainPage.createContactWithPhoneNumber(label) |
228 | onContactClicked: mainPage.showContact(contact) |
229 | onIsInSelectionModeChanged: mainPage.state = isInSelectionMode ? "selection" : "default" |
230 | @@ -272,18 +326,9 @@ |
231 | } |
232 | |
233 | onError: pageStack.contactModelError(error) |
234 | - onActiveFocusChanged: { |
235 | - if (activeFocus && (contactList.currentIndex === -1)) { |
236 | - contactList.currentIndex = 0 |
237 | - } |
238 | - } |
239 | - |
240 | onCountChanged: { |
241 | - if (mainPage.active && |
242 | - (pageStack.columns > 1) && |
243 | - (contactList.currentIndex === -1) && |
244 | - (pageStack.bottomEdge.status === BottomEdge.Hidden)) { |
245 | - contactList.currentIndex = 0 |
246 | + if (mainPage.state === "searching") { |
247 | + currentIndex = 0 |
248 | } |
249 | mainPage.delayFetchContact() |
250 | } |
251 | @@ -370,7 +415,7 @@ |
252 | } |
253 | ] |
254 | |
255 | - property list<QtObject> trailingActions: [ |
256 | + property list<QtObject> trailingActions: [ |
257 | Action { |
258 | text: i18n.tr("Search") |
259 | iconName: "search" |
260 | @@ -378,12 +423,34 @@ |
261 | enabled: visible && (mainPage.state === "default") |
262 | shortcut: "Ctrl+F" |
263 | onTriggered: { |
264 | + if (viewPage) { |
265 | + viewPage.cancelEdit() |
266 | + } |
267 | + |
268 | mainPage.state = "searching" |
269 | contactList.showAllContacts() |
270 | + if (pageStack.bottomEdge) { |
271 | + pageStack.bottomEdge.collapse() |
272 | + } else { |
273 | + showEmptyPage(false) |
274 | + } |
275 | searchField.forceActiveFocus() |
276 | } |
277 | }, |
278 | Action { |
279 | + iconName: "contact-new" |
280 | + enabled: visible && (!pageStack.bottomEdge || (pageStack.bottomEdge.enabled && (pageStack.bottomEdge.status === BottomEdge.Hidden))) |
281 | + visible: (pageStack.columns > 1) |
282 | + shortcut: "Ctrl+N" |
283 | + onTriggered: { |
284 | + if (pageStack.bottomEdge) { |
285 | + pageStack.bottomEdge.commit() |
286 | + } else { |
287 | + showEmptyPage(true) |
288 | + } |
289 | + } |
290 | + }, |
291 | + Action { |
292 | visible: (application.isOnline && (contactList.syncEnabled || application.serverSafeMode)) |
293 | text: contactList.syncing ? i18n.tr("Syncing") : i18n.tr("Sync") |
294 | iconName: application.serverSafeMode ? "reset" : "reload" |
295 | @@ -399,21 +466,7 @@ |
296 | Action { |
297 | text: i18n.tr("Settings") |
298 | iconName: "settings" |
299 | - onTriggered:{ |
300 | - var incubator = pageStack.addPageToNextColumn(mainPage, |
301 | - Qt.resolvedUrl("./Settings/SettingsPage.qml"), |
302 | - {"contactListModel": contactList.listModel}) |
303 | - incubator.onStatusChanged = function(status) { |
304 | - if (status === Component.Ready) { |
305 | - incubator.object.onActiveChanged.connect(function(active) { |
306 | - if (!incubator.object.active) { |
307 | - mainPage.delayFetchContact() |
308 | - contactList.forceActiveFocus() |
309 | - } |
310 | - }) |
311 | - } |
312 | - } |
313 | - } |
314 | + onTriggered: mainPage.showSettingsPage() |
315 | } |
316 | ] |
317 | |
318 | @@ -442,12 +495,7 @@ |
319 | Action { |
320 | iconName: "back" |
321 | text: i18n.tr("Cancel") |
322 | - enabled: (mainPage.state === "searching") && |
323 | - mainPage.active && |
324 | - (!pageStack.bottomEdge || |
325 | - (pageStack.bottomEdge && (pageStack.bottomEdge.status === BottomEdge.Hidden))) && |
326 | - ((pageStack.columns === 1) || |
327 | - (mainPage.viewPage && mainPage.viewPage.active)) |
328 | + enabled: (mainPage.state === "searching") && mainPage.active |
329 | shortcut:"Esc" |
330 | onTriggered: { |
331 | mainPage.head.sections.selectedIndex = 0 |
332 | @@ -494,7 +542,7 @@ |
333 | ] |
334 | |
335 | property list<QtObject> trailingActions: [ |
336 | - Action { |
337 | + Action { |
338 | text: (contactList.selectedItems.count === contactList.count) ? i18n.tr("Unselect All") : i18n.tr("Select All") |
339 | iconName: "select" |
340 | onTriggered: { |
341 | @@ -735,6 +783,7 @@ |
342 | |
343 | if (pageStack) { |
344 | pageStack.contactListPage = mainPage |
345 | + mainPage.delayFetchContact() |
346 | } |
347 | } |
348 | |
349 | @@ -745,6 +794,7 @@ |
350 | active: (pageStack.columns === 1) && bottomEdgeLoader.enabled |
351 | asynchronous: true |
352 | sourceComponent: ABNewContactBottomEdge { |
353 | + id: bottomEdge |
354 | parent: mainPage |
355 | modelToEdit: mainPage.contactModel |
356 | hint.flickable: contactList.view |
357 | @@ -753,6 +803,18 @@ |
358 | } |
359 | } |
360 | |
361 | + Action { |
362 | + iconName: "contact-new" |
363 | + enabled: mainPage.active && |
364 | + (bottomEdgeLoader.status === Loader.Ready) && |
365 | + (bottomEdgeLoader.item.status === BottomEdge.Hidden) |
366 | + shortcut: "Ctrl+N" |
367 | + onTriggered: { |
368 | + bottomEdgeLoader.item.commit() |
369 | + } |
370 | + } |
371 | + |
372 | + |
373 | Binding { |
374 | target: pageStack |
375 | property: 'bottomEdge' |
376 | @@ -769,7 +831,7 @@ |
377 | mainPage.contactIndex = null |
378 | // at this point the operation has finished already |
379 | mainPage._creatingContact = false |
380 | - fetchNewContactTimer.restart() |
381 | + mainPage.delayFetchContact() |
382 | } |
383 | } |
384 | onImportCompleted: { |
385 | @@ -812,7 +874,10 @@ |
386 | contactList.currentIndex = 0 |
387 | mainPage.delayFetchContact() |
388 | } |
389 | - contactList.forceActiveFocus() |
390 | + |
391 | + if (mainPage.status === "default") { |
392 | + contactList.forceActiveFocus() |
393 | + } |
394 | } |
395 | } |
396 | } |
397 | |
398 | === modified file 'src/imports/ABContactViewPage.qml' |
399 | --- src/imports/ABContactViewPage.qml 2016-01-04 21:52:26 +0000 |
400 | +++ src/imports/ABContactViewPage.qml 2016-02-13 02:36:44 +0000 |
401 | @@ -27,32 +27,31 @@ |
402 | id: root |
403 | objectName: "contactViewPage" |
404 | |
405 | - property bool editing: false |
406 | // used by autopilot test |
407 | readonly property string headerTitle: header.title |
408 | + readonly property bool editing: _editPage != null |
409 | + |
410 | + // FIXME: bug #1544745 |
411 | + // Adaptive layout is not destroying all pages correct, we do it manually for now |
412 | + property var _editPage: null |
413 | + function cancelEdit() |
414 | + { |
415 | + if (_editPage) { |
416 | + pageStack.removePages(_editPage) |
417 | + _editPage = null |
418 | + } |
419 | + if (pageStack.bottomEdge) { |
420 | + pageStack.bottomEdge.collapse() |
421 | + } |
422 | + } |
423 | |
424 | function editContact(contact) |
425 | { |
426 | - if (editing) |
427 | - return |
428 | - editing = true |
429 | - var component = Qt.createComponent(Qt.resolvedUrl("ABContactEditorPage.qml")) |
430 | - var incubator = pageStack.addPageToCurrentColumn(root, |
431 | - component, |
432 | - { model: root.model, |
433 | - contact: contact, |
434 | - backIconName: 'back'}) |
435 | - if (incubator && (incubator.status === Component.Loading)) { |
436 | - incubator.onStatusChanged = function(status) { |
437 | - if (status === Component.Ready) { |
438 | - incubator.object.Component.destruction.connect(function() { |
439 | - root.editing = false; |
440 | - }); |
441 | - } |
442 | - } |
443 | - } else { |
444 | - editing = false |
445 | - } |
446 | + root._editPage = pageStack.addComponentToCurrentColumnSync(root, Qt.resolvedUrl("ABContactEditorPage.qml"), |
447 | + { model: root.model, contact: contact, backIconName: 'back'}) |
448 | + root._editPage.Component.onDestruction(function() { |
449 | + root._editPage = null |
450 | + }) |
451 | } |
452 | |
453 | // Shortcut in case of single column |
454 | @@ -62,7 +61,9 @@ |
455 | name: "cancel" |
456 | enabled: root.active && root.enabled && (pageStack.columns === 1) |
457 | shortcut: "Esc" |
458 | - onTriggered: pageStack.removePages(root) |
459 | + onTriggered: { |
460 | + pageStack.removePages(root) |
461 | + } |
462 | } |
463 | |
464 | |
465 | @@ -86,7 +87,7 @@ |
466 | |
467 | text: i18n.tr("Edit") |
468 | iconName: "edit" |
469 | - enabled: root.active && !editing |
470 | + enabled: root.active && !root.editing |
471 | shortcut: "Ctrl+e" |
472 | onTriggered: root.editContact(root.contact) |
473 | } |
474 | @@ -132,6 +133,8 @@ |
475 | modelToEdit: root.model |
476 | hint.flickable: root.flickable |
477 | pageStack: root.pageStack |
478 | + hintVisible: false |
479 | + enabled: !root.editing |
480 | } |
481 | } |
482 | |
483 | |
484 | === modified file 'src/imports/ABMultiColumnEmptyState.qml' |
485 | --- src/imports/ABMultiColumnEmptyState.qml 2016-01-04 21:39:15 +0000 |
486 | +++ src/imports/ABMultiColumnEmptyState.qml 2016-02-13 02:36:44 +0000 |
487 | @@ -23,10 +23,29 @@ |
488 | |
489 | property string headerTitle: i18n.tr("No contacts") |
490 | |
491 | + property bool openBottomEdgeWhenReady: false |
492 | + |
493 | header: PageHeader { |
494 | title: root.headerTitle |
495 | } |
496 | |
497 | + function commitBottomEdge() |
498 | + { |
499 | + if (bottomEdgeLoader.status !== Loader.Ready) { |
500 | + openBottomEdgeWhenReady = true |
501 | + } else { |
502 | + bottomEdgeLoader.item.commit() |
503 | + } |
504 | + } |
505 | + |
506 | + function close() |
507 | + { |
508 | + if (bottomEdge.item) { |
509 | + bottomEdge.item.collapse() |
510 | + } |
511 | + } |
512 | + |
513 | + |
514 | ABEmptyState { |
515 | id: emptyStateScreen |
516 | |
517 | @@ -38,7 +57,7 @@ |
518 | rightMargin: units.gu(6) |
519 | } |
520 | height: childrenRect.height |
521 | - text: i18n.tr("Create a new contact by swiping up from the bottom of the screen.") |
522 | + text: "" |
523 | } |
524 | |
525 | Loader { |
526 | @@ -49,12 +68,21 @@ |
527 | sourceComponent: ABNewContactBottomEdge { |
528 | id: bottomEdge |
529 | |
530 | + hintVisible: false |
531 | parent: root |
532 | height: root.height |
533 | modelToEdit: root.pageStack.contactListPage.contactModel |
534 | hint.flickable: root.flickable |
535 | pageStack: root.pageStack |
536 | - } |
537 | + onCommitCompleted: { root.openBottomEdgeWhenReady = false } |
538 | + } |
539 | + |
540 | + onStatusChanged: { |
541 | + if ((status === Loader.Ready) && root.openBottomEdgeWhenReady) { |
542 | + bottomEdgeLoader.item.commit() |
543 | + } |
544 | + } |
545 | + |
546 | } |
547 | |
548 | Binding { |
549 | |
550 | === modified file 'src/imports/ABNewContactBottomEdge.qml' |
551 | --- src/imports/ABNewContactBottomEdge.qml 2016-01-04 20:03:58 +0000 |
552 | +++ src/imports/ABNewContactBottomEdge.qml 2016-02-13 02:36:44 +0000 |
553 | @@ -24,6 +24,7 @@ |
554 | |
555 | property var modelToEdit: null |
556 | property var pageStack: null |
557 | + property alias hintVisible: bottomEdgeHint.visible |
558 | property var _contactToEdit: null |
559 | // WORKAROUND: BottomEdge component loads the page async while draging it |
560 | // this cause a very bad visual. |
561 | @@ -38,9 +39,9 @@ |
562 | } |
563 | |
564 | hint { |
565 | + id: bottomEdgeHint |
566 | action: Action { |
567 | iconName: "contact-new" |
568 | - shortcut: "ctrl+n" |
569 | enabled: bottomEdge.enabled |
570 | |
571 | onTriggered: bottomEdge.commit() |
572 | |
573 | === modified file 'src/imports/CMakeLists.txt' |
574 | --- src/imports/CMakeLists.txt 2015-12-15 20:00:44 +0000 |
575 | +++ src/imports/CMakeLists.txt 2016-02-13 02:36:44 +0000 |
576 | @@ -1,6 +1,7 @@ |
577 | project(imports) |
578 | |
579 | set(ADDRESS_BOOK_APP_QMLS |
580 | + ABAdaptivePageLayout.qml |
581 | ABContactListPage.qml |
582 | ABContactEditorPage.qml |
583 | ABContactViewPage.qml |
584 | |
585 | === modified file 'src/imports/MainWindow.qml' |
586 | --- src/imports/MainWindow.qml 2016-01-07 13:18:43 +0000 |
587 | +++ src/imports/MainWindow.qml 2016-02-13 02:36:44 +0000 |
588 | @@ -99,8 +99,7 @@ |
589 | deviceFilter: InputInfo.Keyboard |
590 | } |
591 | |
592 | - |
593 | - AdaptivePageLayout { |
594 | + ABAdaptivePageLayout { |
595 | id: mainStack |
596 | objectName: "mainStack" |
597 | |
598 | @@ -169,7 +168,7 @@ |
599 | onColumnsChanged: { |
600 | if (mainStack.columns > 1) { |
601 | if (mainStack.contactListPage) |
602 | - mainStack.contactListPage.fetchContact() |
603 | + mainStack.contactListPage.delayFetchContact() |
604 | else |
605 | mainStack.addPageToNextColumn(contactPage, Qt.resolvedUrl("./ABMultiColumnEmptyState.qml")) |
606 | } |
607 | |
608 | === modified file 'src/imports/Settings/SettingsDefaultSyncTarget.qml' |
609 | --- src/imports/Settings/SettingsDefaultSyncTarget.qml 2015-12-11 16:43:39 +0000 |
610 | +++ src/imports/Settings/SettingsDefaultSyncTarget.qml 2016-02-13 02:36:44 +0000 |
611 | @@ -171,7 +171,7 @@ |
612 | Label { |
613 | id: label |
614 | |
615 | - text: i18n.tr("Default Addressbook") |
616 | + text: i18n.tr("Default address book") |
617 | anchors { |
618 | left: parent.left |
619 | top: parent.top |
620 | @@ -198,17 +198,12 @@ |
621 | |
622 | delegate: OptionSelectorDelegate { |
623 | text: { |
624 | - if ((sourceId != "system-address-book") && |
625 | - (iconSource == "image://theme/address-book-app-symbolic")) { |
626 | + if ((sourceId != "system-address-book") && (accountProvider == "")) { |
627 | return i18n.dtr("address-book-app", "Personal - %1").arg(sourceName) |
628 | } else { |
629 | return sourceName |
630 | } |
631 | } |
632 | - constrainImage: true |
633 | - iconSource: accountProvider == "" ? |
634 | - "image://theme/address-book-app-symbolic" : |
635 | - "image://theme/online-accounts-%1".arg(accountProvider) |
636 | height: units.gu(4) |
637 | } |
638 | |
639 | |
640 | === modified file 'src/imports/Settings/SettingsPage.qml' |
641 | --- src/imports/Settings/SettingsPage.qml 2016-02-13 02:36:44 +0000 |
642 | +++ src/imports/Settings/SettingsPage.qml 2016-02-13 02:36:44 +0000 |
643 | @@ -66,6 +66,8 @@ |
644 | ListItem.Standard { |
645 | id: addGoogleAccountItem |
646 | |
647 | + property bool selected: (activeFocus && pageStack.hasKeyboard) |
648 | + |
649 | function activate() |
650 | { |
651 | onlineAccountsHelper.setupExec() |
652 | @@ -82,23 +84,29 @@ |
653 | } |
654 | } |
655 | |
656 | - // Selection visual feedback |
657 | + // selection visual feedback |
658 | // |
659 | // FIXME: Using a private property here. This uses the old list item and the only way to change the text |
660 | // color is with this property. |
661 | // We should remove it when update the app to the new ListItem. |
662 | - __foregroundColor: (activeFocus && pageStack.hasKeyboard) ? Theme.palette.normal.foregroundText : |
663 | - Theme.palette.normal.foreground |
664 | + __foregroundColor: selected ? UbuntuColors.blue : Theme.palette.normal.foreground |
665 | + |
666 | Rectangle { |
667 | - color: UbuntuColors.orange |
668 | + border { |
669 | + color: UbuntuColors.orange |
670 | + width: units.dp(1) |
671 | + } |
672 | + color: "#E6E6E6" |
673 | anchors.fill: parent |
674 | - visible: addGoogleAccountItem.activeFocus && pageStack.hasKeyboard |
675 | + visible: addGoogleAccountItem.selected |
676 | z: -1 |
677 | } |
678 | } |
679 | ListItem.Standard { |
680 | id: importFromSimItem |
681 | |
682 | + property bool selected: (activeFocus && pageStack.hasKeyboard) |
683 | + |
684 | function activate() |
685 | { |
686 | pageStack.addPageToCurrentColumn(root, simCardImportPageComponent) |
687 | @@ -116,12 +124,16 @@ |
688 | // FIXME: Using a private property here. This uses the old list item and the only way to change the text |
689 | // color is with this property. |
690 | // We should remove it when update the app to the new ListItem. |
691 | - __foregroundColor: (activeFocus && pageStack.hasKeyboard) ? Theme.palette.normal.foregroundText : |
692 | - Theme.palette.normal.foreground |
693 | + __foregroundColor: selected ? UbuntuColors.blue : Theme.palette.normal.foreground |
694 | + |
695 | Rectangle { |
696 | - color: UbuntuColors.orange |
697 | + border { |
698 | + color: UbuntuColors.orange |
699 | + width: units.dp(1) |
700 | + } |
701 | + color: "#E6E6E6" |
702 | anchors.fill: parent |
703 | - visible: importFromSimItem.activeFocus && pageStack.hasKeyboard |
704 | + visible: importFromSimItem.selected |
705 | z: -1 |
706 | } |
707 | } |
708 | @@ -135,6 +147,12 @@ |
709 | id: onlineAccountsHelper |
710 | } |
711 | |
712 | + Binding { |
713 | + target: pageStack |
714 | + property: 'bottomEdge' |
715 | + value: null |
716 | + } |
717 | + |
718 | Component { |
719 | id: simCardImportPageComponent |
720 | |
721 | |
722 | === modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml' |
723 | --- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml 2015-11-11 20:01:43 +0000 |
724 | +++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailNameEditor.qml 2016-02-13 02:36:44 +0000 |
725 | @@ -89,6 +89,6 @@ |
726 | onFieldChanged: checkIsEmpty() |
727 | |
728 | //style |
729 | - font.pixelSize: FontUtils.sizeToPixels("x-large") |
730 | + font.pixelSize: FontUtils.sizeToPixels("large") |
731 | } |
732 | } |
733 | |
734 | === modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml' |
735 | --- src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml 2015-12-18 13:41:29 +0000 |
736 | +++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactDetailSyncTargetEditor.qml 2016-02-13 02:36:44 +0000 |
737 | @@ -214,18 +214,12 @@ |
738 | |
739 | delegate: OptionSelectorDelegate { |
740 | text: { |
741 | - if ((sourceId != "system-address-book") && |
742 | - (iconSource == "image://theme/address-book-app-symbolic")) { |
743 | - //TRANSLATORS: %1 is the display name of the source (address-book) |
744 | + if ((sourceId != "system-address-book") && (accountProvider == "")) { |
745 | return i18n.dtr("address-book-app", "Personal - %1").arg(sourceName) |
746 | } else { |
747 | return sourceName |
748 | } |
749 | } |
750 | - constrainImage: true |
751 | - iconSource: accountProvider == "" ? |
752 | - "image://theme/address-book-app-symbolic" : |
753 | - "image://theme/online-accounts-%1".arg(accountProvider) |
754 | height: units.gu(4) |
755 | } |
756 | |
757 | |
758 | === modified file 'src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml' |
759 | --- src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml 2016-02-13 02:36:44 +0000 |
760 | +++ src/imports/Ubuntu/AddressBook/ContactEditor/ContactEditorPage.qml 2016-02-13 02:36:44 +0000 |
761 | @@ -374,7 +374,7 @@ |
762 | objectName: "addNewFieldButton" |
763 | |
764 | contact: contactEditor.contact |
765 | - text: i18n.dtr("address-book-app", "Add Field") |
766 | + text: i18n.dtr("address-book-app", "Add field") |
767 | anchors { |
768 | left: parent.left |
769 | right: parent.right |
770 | |
771 | === modified file 'src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml' |
772 | --- src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml 2016-01-04 21:52:16 +0000 |
773 | +++ src/imports/Ubuntu/AddressBook/ContactView/ContactViewPage.qml 2016-02-13 02:36:44 +0000 |
774 | @@ -50,6 +50,24 @@ |
775 | trailingActionBar { |
776 | id: trailingBar |
777 | } |
778 | + leadingActionBar { |
779 | + id: leadingBar |
780 | + actions: Action { |
781 | + id: backAction |
782 | + |
783 | + iconName: "back" |
784 | + name: "cancel" |
785 | + enabled: visible && root.active && root.enabled |
786 | + visible: (pageStack.columns === 1) |
787 | + onTriggered: { |
788 | + if (pageStack.removePages) |
789 | + pageStack.removePages(root) |
790 | + else |
791 | + pageStack.pop() |
792 | + } |
793 | + } |
794 | + |
795 | + } |
796 | } |
797 | |
798 | Connections { |
799 | |
800 | === modified file 'src/imports/Ubuntu/Contacts/ContactDelegate.qml' |
801 | --- src/imports/Ubuntu/Contacts/ContactDelegate.qml 2016-02-13 02:36:44 +0000 |
802 | +++ src/imports/Ubuntu/Contacts/ContactDelegate.qml 2016-02-13 02:36:44 +0000 |
803 | @@ -76,7 +76,7 @@ |
804 | verticalCenter: parent.verticalCenter |
805 | right: parent.right |
806 | } |
807 | - color: UbuntuColors.darkGrey |
808 | + color: selected ? UbuntuColors.blue : UbuntuColors.darkGrey |
809 | text: root.displayLabel != "" ? root.displayLabel : i18n.dtr("address-book-app", "No name") |
810 | elide: Text.ElideRight |
811 | } |
812 | |
813 | === modified file 'src/imports/Ubuntu/Contacts/ContactListView.qml' |
814 | --- src/imports/Ubuntu/Contacts/ContactListView.qml 2015-12-04 15:08:46 +0000 |
815 | +++ src/imports/Ubuntu/Contacts/ContactListView.qml 2016-02-13 02:36:44 +0000 |
816 | @@ -419,11 +419,13 @@ |
817 | right: parent.right |
818 | } |
819 | |
820 | - Binding { |
821 | - target: view |
822 | - property: 'contentY' |
823 | - value: -view.headerItem.height |
824 | - when: root.showNewContact |
825 | + // top margin |
826 | + Item { |
827 | + anchors { |
828 | + left: parent.left |
829 | + right: parent.right |
830 | + } |
831 | + height: units.gu(0.5) |
832 | } |
833 | |
834 | Binding { |
835 | @@ -458,9 +460,13 @@ |
836 | imageUrl: "image://theme/contact" |
837 | } |
838 | } |
839 | - selected: true |
840 | + selected: pageStack.hasKeyboard |
841 | visible: root.showNewContact |
842 | height: root.showNewContact ? defaultHeight : 0 |
843 | + onHeightChanged: { |
844 | + if (visible) |
845 | + view.positionViewAtBeginning() |
846 | + } |
847 | Behavior on height {UbuntuNumberAnimation {}} |
848 | } |
849 | |
850 | |
851 | === modified file 'src/imports/Ubuntu/Contacts/ContactSimpleListView.qml' |
852 | --- src/imports/Ubuntu/Contacts/ContactSimpleListView.qml 2016-01-06 13:13:12 +0000 |
853 | +++ src/imports/Ubuntu/Contacts/ContactSimpleListView.qml 2016-02-13 02:36:44 +0000 |
854 | @@ -271,8 +271,6 @@ |
855 | width: parent.width |
856 | selected: (contactListView.multiSelectionEnabled && contactListView.isSelected(contactDelegate)) |
857 | || (!contactListView.isInSelectionMode && contactListView.highlightSelected && (contactListView.currentIndex == index)) |
858 | - selectedColor: contactListView.parent.activeFocus && !contactListView.isInSelectionMode && contactListView.highlightSelected ? |
859 | - UbuntuColors.orange : Theme.palette.selected.background |
860 | selectionMode: contactListView.isInSelectionMode |
861 | defaultAvatarUrl: contactListView.defaultAvatarImageUrl |
862 | isCurrentItem: ListView.isCurrentItem |
863 | |
864 | === modified file 'src/imports/Ubuntu/Contacts/ListItemWithActions.qml' |
865 | --- src/imports/Ubuntu/Contacts/ListItemWithActions.qml 2016-02-13 02:36:44 +0000 |
866 | +++ src/imports/Ubuntu/Contacts/ListItemWithActions.qml 2016-02-13 02:36:44 +0000 |
867 | @@ -28,7 +28,7 @@ |
868 | property var activeItem: null |
869 | property bool triggerActionOnMouseRelease: false |
870 | property color color: Theme.palette.normal.background |
871 | - property color selectedColor: "#E6E6E6" |
872 | + property color selectedColor: "#F7F7F7" |
873 | property bool selected: false |
874 | property bool selectionMode: false |
875 | property alias internalAnchors: mainContents.anchors |
876 | @@ -264,6 +264,10 @@ |
877 | } |
878 | |
879 | width: parent.width |
880 | + border { |
881 | + color: UbuntuColors.orange |
882 | + width: root.selected ? units.dp(1) : 0 |
883 | + } |
884 | color: root.selected ? root.selectedColor : root.color |
885 | |
886 | Loader { |
FAILED: Continuous integration, rev:537 jenkins. qa.ubuntu. com/job/ address- book-app- ci/1100/ jenkins. qa.ubuntu. com/job/ address- book-app- vivid-i386- ci/403 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 6316 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-touch/ 4853 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 6327 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 6327/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 27276
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/address- book-app- ci/1100/ rebuild
http://