Merge lp:~canonical-platform-qa/gallery-app/gallery-app-new_header-autopilot2 into lp:gallery-app
- gallery-app-new_header-autopilot2
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~canonical-platform-qa/gallery-app/gallery-app-new_header-autopilot2 |
Merge into: | lp:gallery-app |
Diff against target: |
2678 lines (+641/-1105) 31 files modified
rc/qml/AlbumEditor/AlbumEditor.qml (+9/-12) rc/qml/AlbumViewer/AlbumViewer.qml (+37/-34) rc/qml/AlbumsOverview.qml (+5/-6) rc/qml/Components/MediaSelector.qml (+12/-17) rc/qml/EventsOverview.qml (+1/-1) rc/qml/GalleryApplication.qml (+2/-3) rc/qml/MainScreen.qml (+2/-0) rc/qml/MediaViewer/GalleryPhotoComponent.qml (+2/-4) rc/qml/MediaViewer/MediaViewer.qml (+103/-149) rc/qml/MediaViewer/PhotoViewerDelegate.qml (+0/-129) rc/qml/MediaViewer/PopupPhotoViewer.qml (+16/-14) rc/qml/MediaViewer/SingleMediaViewer.qml (+246/-0) rc/qml/MediaViewer/VideoViewerDelegate.qml (+0/-125) rc/qml/MediaViewer/ZoomablePhotoComponent.qml (+0/-409) rc/qml/OrganicView/OrganicView.qml (+1/-1) rc/qml/PhotosOverview.qml (+1/-1) rc/qml/PickerScreen.qml (+15/-20) rc/qml/Utility/PhotosToolbarActions.qml (+19/-13) rc/qml/Utility/SelectionToolbarAction.qml (+32/-22) tests/autopilot/gallery_app/emulators/album_view.py (+4/-6) tests/autopilot/gallery_app/emulators/gallery_utils.py (+3/-3) tests/autopilot/gallery_app/emulators/main_screen.py (+27/-12) tests/autopilot/gallery_app/emulators/photo_viewer.py (+4/-5) tests/autopilot/gallery_app/emulators/picker_screen.py (+3/-3) tests/autopilot/gallery_app/tests/__init__.py (+6/-5) tests/autopilot/gallery_app/tests/test_album_editor.py (+14/-18) tests/autopilot/gallery_app/tests/test_album_view.py (+17/-26) tests/autopilot/gallery_app/tests/test_albums_view.py (+16/-11) tests/autopilot/gallery_app/tests/test_events_view.py (+17/-14) tests/autopilot/gallery_app/tests/test_photo_viewer.py (+8/-23) tests/autopilot/gallery_app/tests/test_photos_view.py (+19/-19) |
To merge this branch: | bzr merge lp:~canonical-platform-qa/gallery-app/gallery-app-new_header-autopilot2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+233273@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-09-04.
Commit message
Not ready, just trying jenkins.
Description of the change
NOT READY.
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1077
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
Preview Diff
1 | === modified file 'rc/qml/AlbumEditor/AlbumEditor.qml' | |||
2 | --- rc/qml/AlbumEditor/AlbumEditor.qml 2014-06-10 00:13:50 +0000 | |||
3 | +++ rc/qml/AlbumEditor/AlbumEditor.qml 2014-09-03 23:54:36 +0000 | |||
4 | @@ -20,7 +20,7 @@ | |||
5 | 20 | 20 | ||
6 | 21 | import QtQuick 2.0 | 21 | import QtQuick 2.0 |
7 | 22 | import Gallery 1.0 | 22 | import Gallery 1.0 |
9 | 23 | import Ubuntu.Components 0.1 | 23 | import Ubuntu.Components 1.1 |
10 | 24 | import "../../js/GalleryUtility.js" as GalleryUtility | 24 | import "../../js/GalleryUtility.js" as GalleryUtility |
11 | 25 | import "../../js/GraphicsRoutines.js" as GraphicsRoutines | 25 | import "../../js/GraphicsRoutines.js" as GraphicsRoutines |
12 | 26 | import "../AlbumViewer" | 26 | import "../AlbumViewer" |
13 | @@ -33,17 +33,14 @@ | |||
14 | 33 | objectName: "mainAlbumEditor" | 33 | objectName: "mainAlbumEditor" |
15 | 34 | 34 | ||
16 | 35 | title: "Edit album" | 35 | title: "Edit album" |
28 | 36 | tools: ToolbarItems { | 36 | head.backAction: Action { |
29 | 37 | back: Button { | 37 | objectName: "cancelButton" |
30 | 38 | objectName: "cancelButton" | 38 | text: i18n.tr("Cancel") |
31 | 39 | anchors.verticalCenter: parent.verticalCenter | 39 | iconName: "back" |
32 | 40 | text: i18n.tr("Cancel") | 40 | onTriggered: { |
33 | 41 | width: units.gu(10) | 41 | if(album.newAlbum) |
34 | 42 | onClicked: { | 42 | albumModel.destroyAlbum(album); |
35 | 43 | if(album.newAlbum) | 43 | albumEditor.closeRequested(albumEditor.album, false); |
25 | 44 | albumModel.destroyAlbum(album); | ||
26 | 45 | albumEditor.closeRequested(albumEditor.album, false); | ||
27 | 46 | } | ||
36 | 47 | } | 44 | } |
37 | 48 | } | 45 | } |
38 | 49 | 46 | ||
39 | 50 | 47 | ||
40 | === modified file 'rc/qml/AlbumViewer/AlbumViewer.qml' | |||
41 | --- rc/qml/AlbumViewer/AlbumViewer.qml 2014-06-18 17:43:41 +0000 | |||
42 | +++ rc/qml/AlbumViewer/AlbumViewer.qml 2014-09-03 23:54:36 +0000 | |||
43 | @@ -19,7 +19,7 @@ | |||
44 | 19 | */ | 19 | */ |
45 | 20 | 20 | ||
46 | 21 | import QtQuick 2.0 | 21 | import QtQuick 2.0 |
48 | 22 | import Ubuntu.Components 0.1 | 22 | import Ubuntu.Components 1.1 |
49 | 23 | import Gallery 1.0 | 23 | import Gallery 1.0 |
50 | 24 | import "../../js/Gallery.js" as Gallery | 24 | import "../../js/Gallery.js" as Gallery |
51 | 25 | import "../../js/GalleryUtility.js" as GalleryUtility | 25 | import "../../js/GalleryUtility.js" as GalleryUtility |
52 | @@ -74,10 +74,6 @@ | |||
53 | 74 | 74 | ||
54 | 75 | onVisibleChanged: { | 75 | onVisibleChanged: { |
55 | 76 | if (visible) reopenPicture(); | 76 | if (visible) reopenPicture(); |
56 | 77 | |||
57 | 78 | if (albumViewer.header) { | ||
58 | 79 | albumViewer.header.visible = !visible; | ||
59 | 80 | } | ||
60 | 81 | } | 77 | } |
61 | 82 | 78 | ||
62 | 83 | onCloseRequested: { | 79 | onCloseRequested: { |
63 | @@ -135,6 +131,11 @@ | |||
64 | 135 | overview.pushPage(component_mediaSelector); | 131 | overview.pushPage(component_mediaSelector); |
65 | 136 | } | 132 | } |
66 | 137 | 133 | ||
67 | 134 | function toggleHeaderVisibility() | ||
68 | 135 | { | ||
69 | 136 | header.visible = !header.visible; | ||
70 | 137 | } | ||
71 | 138 | |||
72 | 138 | AlbumSpreadViewer { | 139 | AlbumSpreadViewer { |
73 | 139 | id: albumSpreadViewer | 140 | id: albumSpreadViewer |
74 | 140 | objectName: "spreadViewer" | 141 | objectName: "spreadViewer" |
75 | @@ -188,8 +189,10 @@ | |||
76 | 188 | if (hit.objectName === "addButton") | 189 | if (hit.objectName === "addButton") |
77 | 189 | showMediaSelector(); | 190 | showMediaSelector(); |
78 | 190 | 191 | ||
80 | 191 | if (!hit.mediaSource) | 192 | if (!hit.mediaSource) { |
81 | 193 | albumViewer.toggleHeaderVisibility(); | ||
82 | 192 | return; | 194 | return; |
83 | 195 | } | ||
84 | 193 | 196 | ||
85 | 194 | albumViewer.mediaCurrentlyInView = hit.mediaSource.path; | 197 | albumViewer.mediaCurrentlyInView = hit.mediaSource.path; |
86 | 195 | photoViewerLoader.fadeOpen(hit.mediaSource); | 198 | photoViewerLoader.fadeOpen(hit.mediaSource); |
87 | @@ -302,6 +305,7 @@ | |||
88 | 302 | 305 | ||
89 | 303 | onOpened: { | 306 | onOpened: { |
90 | 304 | overview.pushPage(target); | 307 | overview.pushPage(target); |
91 | 308 | header.visible = false; | ||
92 | 305 | } | 309 | } |
93 | 306 | onCloseRequested: { | 310 | onCloseRequested: { |
94 | 307 | albumViewer.mediaCurrentlyInView = ""; | 311 | albumViewer.mediaCurrentlyInView = ""; |
95 | @@ -353,36 +357,35 @@ | |||
96 | 353 | } | 357 | } |
97 | 354 | 358 | ||
98 | 355 | /// Contains the actions for the toolbar in the album view | 359 | /// Contains the actions for the toolbar in the album view |
101 | 356 | tools: ToolbarItems { | 360 | head.actions: [ |
102 | 357 | ToolbarButton { | 361 | Action { |
103 | 358 | objectName: "addButton" | 362 | objectName: "addButton" |
115 | 359 | action: Action { | 363 | text: i18n.tr("Add to album") // text in HUD |
116 | 360 | text: i18n.tr("Add to album") // text in HUD | 364 | iconName: "add" |
117 | 361 | iconSource: Qt.resolvedUrl("../../img/add.png") | 365 | onTriggered: showMediaSelector(); |
118 | 362 | onTriggered: { | 366 | }, |
119 | 363 | showMediaSelector(); | 367 | Action { |
109 | 364 | } | ||
110 | 365 | } | ||
111 | 366 | text: i18n.tr("Add") // text in toolbar | ||
112 | 367 | } | ||
113 | 368 | ToolbarButton { | ||
114 | 369 | id: deleteButton | ||
120 | 370 | objectName: "deleteButton" | 368 | objectName: "deleteButton" |
121 | 371 | text: i18n.tr("Delete") | 369 | text: i18n.tr("Delete") |
137 | 372 | iconSource: Qt.resolvedUrl("../../img/delete.png") | 370 | iconName: "delete" |
138 | 373 | onTriggered: { | 371 | onTriggered: { |
139 | 374 | albumTrashDialog.album = album | 372 | albumTrashDialog.album = album; |
140 | 375 | albumTrashDialog.caller = deleteButton | 373 | albumTrashDialog.show(); |
141 | 376 | albumTrashDialog.show() | 374 | } |
142 | 377 | } | 375 | } |
143 | 378 | } | 376 | ] |
144 | 379 | back: ToolbarButton { | 377 | |
145 | 380 | text: i18n.tr("Back") | 378 | head.backAction: Action { |
146 | 381 | objectName: "backButton" | 379 | iconName: "back" |
147 | 382 | iconSource: Qt.resolvedUrl("../../img/back.png") | 380 | onTriggered: __close(); |
148 | 383 | onTriggered: { | 381 | } |
149 | 384 | __close() | 382 | |
150 | 385 | } | 383 | Rectangle { |
151 | 386 | } | 384 | id: headerBackground |
152 | 385 | |||
153 | 386 | width: parent.width | ||
154 | 387 | height: header.height | ||
155 | 388 | |||
156 | 389 | visible: header.visible | ||
157 | 387 | } | 390 | } |
158 | 388 | } | 391 | } |
159 | 389 | 392 | ||
160 | === modified file 'rc/qml/AlbumsOverview.qml' | |||
161 | --- rc/qml/AlbumsOverview.qml 2014-06-10 16:56:56 +0000 | |||
162 | +++ rc/qml/AlbumsOverview.qml 2014-09-03 23:54:36 +0000 | |||
163 | @@ -169,10 +169,9 @@ | |||
164 | 169 | root.visible = false; | 169 | root.visible = false; |
165 | 170 | 170 | ||
166 | 171 | if (albumViewer.origin) { | 171 | if (albumViewer.origin) { |
167 | 172 | if (header.visible) | ||
168 | 173 | header.visible = false; | ||
169 | 174 | albumViewer.visible = true; | 172 | albumViewer.visible = true; |
170 | 175 | overview.pushPage(albumViewer); | 173 | overview.pushPage(albumViewer); |
171 | 174 | header.visible = false; | ||
172 | 176 | } | 175 | } |
173 | 177 | else | 176 | else |
174 | 178 | albumViewer.visible = true | 177 | albumViewer.visible = true |
175 | @@ -221,10 +220,10 @@ | |||
176 | 221 | tools: ToolbarItems { | 220 | tools: ToolbarItems { |
177 | 222 | id: albumOverviewTools | 221 | id: albumOverviewTools |
178 | 223 | ToolbarButton { | 222 | ToolbarButton { |
179 | 224 | objectName: "addButton" | ||
180 | 225 | action: Action { | 223 | action: Action { |
181 | 224 | objectName: "addButton" | ||
182 | 226 | text: i18n.tr("Add new album") // Text in HUD | 225 | text: i18n.tr("Add new album") // Text in HUD |
184 | 227 | iconSource: Qt.resolvedUrl("../img/add.png") | 226 | iconName: "add" |
185 | 228 | onTriggered: { | 227 | onTriggered: { |
186 | 229 | var album = albumCollectionModel.createOrphan(); | 228 | var album = albumCollectionModel.createOrphan(); |
187 | 230 | albumCollectionModel.addOrphan(album); | 229 | albumCollectionModel.addOrphan(album); |
188 | @@ -238,10 +237,10 @@ | |||
189 | 238 | text: "Add" // text in toolbar | 237 | text: "Add" // text in toolbar |
190 | 239 | } | 238 | } |
191 | 240 | ToolbarButton { | 239 | ToolbarButton { |
192 | 241 | objectName: "cameraButton" | ||
193 | 242 | visible: !APP.desktopMode | ||
194 | 243 | action: Action { | 240 | action: Action { |
195 | 241 | objectName: "cameraButton" | ||
196 | 244 | text: i18n.tr("Camera") | 242 | text: i18n.tr("Camera") |
197 | 243 | visible: !APP.desktopMode | ||
198 | 245 | iconSource: Qt.resolvedUrl("../img/camera.png") | 244 | iconSource: Qt.resolvedUrl("../img/camera.png") |
199 | 246 | onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version") | 245 | onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version") |
200 | 247 | } | 246 | } |
201 | 248 | 247 | ||
202 | === modified file 'rc/qml/Components/MediaSelector.qml' | |||
203 | --- rc/qml/Components/MediaSelector.qml 2014-05-23 08:24:38 +0000 | |||
204 | +++ rc/qml/Components/MediaSelector.qml 2014-09-03 23:54:36 +0000 | |||
205 | @@ -16,7 +16,7 @@ | |||
206 | 16 | 16 | ||
207 | 17 | import QtQuick 2.0 | 17 | import QtQuick 2.0 |
208 | 18 | import Gallery 1.0 | 18 | import Gallery 1.0 |
210 | 19 | import Ubuntu.Components 0.1 | 19 | import Ubuntu.Components 1.1 |
211 | 20 | import "../../js/Gallery.js" as Gallery | 20 | import "../../js/Gallery.js" as Gallery |
212 | 21 | import "../OrganicView" | 21 | import "../OrganicView" |
213 | 22 | import "../Utility" | 22 | import "../Utility" |
214 | @@ -74,31 +74,26 @@ | |||
215 | 74 | selection: mediaSelector.selection | 74 | selection: mediaSelector.selection |
216 | 75 | } | 75 | } |
217 | 76 | 76 | ||
221 | 77 | tools: ToolbarItems { | 77 | head.actions: [ |
222 | 78 | Button { | 78 | Action { |
223 | 79 | anchors.verticalCenter: parent.verticalCenter | 79 | objectName: "addButton" |
224 | 80 | text: i18n.tr("Add to Album") | 80 | text: i18n.tr("Add to Album") |
228 | 81 | objectName: "addButton" | 81 | iconName: "add" |
226 | 82 | color: Gallery.HIGHLIGHT_BUTTON_COLOR | ||
227 | 83 | width: units.gu(16) | ||
229 | 84 | enabled: mediaSelector.selection.selectedCount | 82 | enabled: mediaSelector.selection.selectedCount |
230 | 85 | onTriggered: { | 83 | onTriggered: { |
231 | 86 | mediaSelector.addClicked(); | 84 | mediaSelector.addClicked(); |
232 | 87 | mediaSelector.hide(); | 85 | mediaSelector.hide(); |
233 | 88 | } | 86 | } |
234 | 89 | } | 87 | } |
235 | 88 | ] | ||
236 | 90 | 89 | ||
245 | 91 | back: Button { | 90 | head.backAction: Action { |
246 | 92 | anchors.verticalCenter: parent.verticalCenter | 91 | objectName: "cancelButton" |
247 | 93 | text: i18n.tr("Cancel") | 92 | text: i18n.tr("Cancel") |
248 | 94 | objectName: "cancelButton" | 93 | iconName: "back" |
249 | 95 | width: units.gu(10) | 94 | onTriggered: { |
250 | 96 | onClicked: { | 95 | mediaSelector.hide(); |
243 | 97 | mediaSelector.hide(); | ||
244 | 98 | } | ||
251 | 99 | } | 96 | } |
252 | 100 | opened: true | ||
253 | 101 | locked: true | ||
254 | 102 | } | 97 | } |
255 | 103 | 98 | ||
256 | 104 | PropertyAnimation { | 99 | PropertyAnimation { |
257 | 105 | 100 | ||
258 | === modified file 'rc/qml/EventsOverview.qml' | |||
259 | --- rc/qml/EventsOverview.qml 2014-03-10 17:20:03 +0000 | |||
260 | +++ rc/qml/EventsOverview.qml 2014-09-03 23:54:36 +0000 | |||
261 | @@ -94,7 +94,7 @@ | |||
262 | 94 | } | 94 | } |
263 | 95 | onAddClicked: { | 95 | onAddClicked: { |
264 | 96 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("Components/PopupAlbumPicker.qml"), | 96 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("Components/PopupAlbumPicker.qml"), |
266 | 97 | caller, | 97 | null, |
267 | 98 | {contentHeight: organicEventView.__pickerContentHeight}); | 98 | {contentHeight: organicEventView.__pickerContentHeight}); |
268 | 99 | } | 99 | } |
269 | 100 | onDeleteClicked: { | 100 | onDeleteClicked: { |
270 | 101 | 101 | ||
271 | === modified file 'rc/qml/GalleryApplication.qml' | |||
272 | --- rc/qml/GalleryApplication.qml 2014-08-14 21:53:31 +0000 | |||
273 | +++ rc/qml/GalleryApplication.qml 2014-09-03 23:54:36 +0000 | |||
274 | @@ -190,6 +190,7 @@ | |||
275 | 190 | 190 | ||
276 | 191 | Loader { | 191 | Loader { |
277 | 192 | id: loadingScreen | 192 | id: loadingScreen |
278 | 193 | objectName: 'loadingScreen' | ||
279 | 193 | anchors.fill: parent | 194 | anchors.fill: parent |
280 | 194 | visible: mainScreenLoader.status !== Loader.Ready | 195 | visible: mainScreenLoader.status !== Loader.Ready |
281 | 195 | source: visible ? Qt.resolvedUrl("LoadingScreen.qml") : "" | 196 | source: visible ? Qt.resolvedUrl("LoadingScreen.qml") : "" |
282 | @@ -201,9 +202,7 @@ | |||
283 | 201 | source: allLoaded ? ((APP.pickModeEnabled) ? Qt.resolvedUrl("PickerScreen.qml") : | 202 | source: allLoaded ? ((APP.pickModeEnabled) ? Qt.resolvedUrl("PickerScreen.qml") : |
284 | 202 | Qt.resolvedUrl("MainScreen.qml")) : "" | 203 | Qt.resolvedUrl("MainScreen.qml")) : "" |
285 | 203 | visible: status === Loader.Ready | 204 | visible: status === Loader.Ready |
289 | 204 | // FIXME: this causes https://bugs.launchpad.net/bugs/1356841 | 205 | asynchronous: true |
287 | 205 | // even though it fixes the spinner loading animation, comment out for now | ||
288 | 206 | //asynchronous: true | ||
290 | 207 | } | 206 | } |
291 | 208 | 207 | ||
292 | 209 | Component.onCompleted: { | 208 | Component.onCompleted: { |
293 | 210 | 209 | ||
294 | === modified file 'rc/qml/MainScreen.qml' | |||
295 | --- rc/qml/MainScreen.qml 2014-06-10 18:54:21 +0000 | |||
296 | +++ rc/qml/MainScreen.qml 2014-09-03 23:54:36 +0000 | |||
297 | @@ -31,6 +31,8 @@ | |||
298 | 31 | id: overview | 31 | id: overview |
299 | 32 | objectName: "overview" | 32 | objectName: "overview" |
300 | 33 | 33 | ||
301 | 34 | useDeprecatedToolbar: false | ||
302 | 35 | |||
303 | 34 | anchors.fill: parent | 36 | anchors.fill: parent |
304 | 35 | applicationName: "gallery-app" | 37 | applicationName: "gallery-app" |
305 | 36 | automaticOrientation: application.automaticOrientation | 38 | automaticOrientation: application.automaticOrientation |
306 | 37 | 39 | ||
307 | === modified file 'rc/qml/MediaViewer/GalleryPhotoComponent.qml' | |||
308 | --- rc/qml/MediaViewer/GalleryPhotoComponent.qml 2014-08-11 20:34:23 +0000 | |||
309 | +++ rc/qml/MediaViewer/GalleryPhotoComponent.qml 2014-09-03 23:54:36 +0000 | |||
310 | @@ -108,10 +108,8 @@ | |||
311 | 108 | // prevent this segfault & crash from occurring. | 108 | // prevent this segfault & crash from occurring. |
312 | 109 | visible: isLoaded; | 109 | visible: isLoaded; |
313 | 110 | 110 | ||
318 | 111 | sourceSize: { | 111 | sourceSize.width: width |
319 | 112 | width: width | 112 | sourceSize.height: height |
316 | 113 | height: height | ||
317 | 114 | } | ||
320 | 115 | 113 | ||
321 | 116 | // use cache: !isAnimate setting for flicker-free animations and reflows | 114 | // use cache: !isAnimate setting for flicker-free animations and reflows |
322 | 117 | asynchronous: !isAnimate | 115 | asynchronous: !isAnimate |
323 | 118 | 116 | ||
324 | === modified file 'rc/qml/MediaViewer/MediaViewer.qml' | |||
325 | --- rc/qml/MediaViewer/MediaViewer.qml 2014-07-04 11:29:31 +0000 | |||
326 | +++ rc/qml/MediaViewer/MediaViewer.qml 2014-09-03 23:54:36 +0000 | |||
327 | @@ -20,7 +20,7 @@ | |||
328 | 20 | 20 | ||
329 | 21 | import QtQuick 2.0 | 21 | import QtQuick 2.0 |
330 | 22 | import Gallery 1.0 | 22 | import Gallery 1.0 |
332 | 23 | import Ubuntu.Components 0.1 | 23 | import Ubuntu.Components 1.1 |
333 | 24 | import Ubuntu.Components.Popups 0.1 | 24 | import Ubuntu.Components.Popups 0.1 |
334 | 25 | import Ubuntu.Components.ListItems 0.1 as ListItem | 25 | import Ubuntu.Components.ListItems 0.1 as ListItem |
335 | 26 | import Ubuntu.Content 0.1 | 26 | import Ubuntu.Content 0.1 |
336 | @@ -60,13 +60,14 @@ | |||
337 | 60 | // | 60 | // |
338 | 61 | // Since there is no current item if there are no more photo objects left in the model, | 61 | // Since there is no current item if there are no more photo objects left in the model, |
339 | 62 | // the check catches this before we can inadvertently follow a stale pointer. | 62 | // the check catches this before we can inadvertently follow a stale pointer. |
342 | 63 | property bool isReady: model != null && model.count > 0 && | 63 | property bool isReady: model != null && model.count > 0 && galleryPhotoViewer.currentItem |
341 | 64 | (galleryPhotoViewer.currentItem ? galleryPhotoViewer.currentItem.isLoaded : false) | ||
343 | 65 | 64 | ||
344 | 66 | // tooolbar actions for the full view | 65 | // tooolbar actions for the full view |
348 | 67 | property Item tools: (media && !sharePicker.visible) ? (media.type === MediaSource.Photo ? | 66 | property variant actions: (media && !sharePicker.visible) ? (media.type === MediaSource.Photo ? |
349 | 68 | d.photoToolbar : d.videoToolbar) | 67 | d.photoActions : d.videoActions) |
350 | 69 | : null | 68 | : [] |
351 | 69 | |||
352 | 70 | property variant backAction: d.backAction | ||
353 | 70 | 71 | ||
354 | 71 | /*! | 72 | /*! |
355 | 72 | */ | 73 | */ |
356 | @@ -113,6 +114,16 @@ | |||
357 | 113 | galleryPhotoViewer.currentItem.togglePlayPause(); | 114 | galleryPhotoViewer.currentItem.togglePlayPause(); |
358 | 114 | } | 115 | } |
359 | 115 | 116 | ||
360 | 117 | function setHeaderVisibility(visible) | ||
361 | 118 | { | ||
362 | 119 | header.visible = visible; | ||
363 | 120 | } | ||
364 | 121 | |||
365 | 122 | function toggleHeaderVisibility() | ||
366 | 123 | { | ||
367 | 124 | setHeaderVisibility(!header.visible); | ||
368 | 125 | } | ||
369 | 126 | |||
370 | 116 | Rectangle{ | 127 | Rectangle{ |
371 | 117 | color: "black" | 128 | color: "black" |
372 | 118 | anchors.fill: parent | 129 | anchors.fill: parent |
373 | @@ -152,37 +163,19 @@ | |||
374 | 152 | media = model.getAt(currentIndex); | 163 | media = model.getAt(currentIndex); |
375 | 153 | } | 164 | } |
376 | 154 | 165 | ||
404 | 155 | delegate: Item { | 166 | delegate: SingleMediaViewer { |
405 | 156 | /// Is true while the media content is loaded | 167 | id: media |
406 | 157 | property bool isLoaded: delegateView.item.isLoaded | 168 | objectName: "openedMedia" + index |
407 | 158 | /// Is true when the view is in a state, where the user possibly | 169 | mediaFileURL: model.mediaSource.path |
408 | 159 | /// interacts with the media (and not swipe to another media) | 170 | mediaFileType: model.mediaSource.type |
409 | 160 | property bool userInteracting: delegateView.item.state === "zoomed" | 171 | maxDimension: Math.max(galleryPhotoViewer.width, galleryPhotoViewer.height) |
383 | 161 | /// Needed as ListView.isCurrentItem can't be used directly | ||
384 | 162 | property bool isActive: ListView.isCurrentItem | ||
385 | 163 | /// True if a video is currently played | ||
386 | 164 | property bool isPlayingVideo: galleryPhotoViewer.currentItem ? | ||
387 | 165 | galleryPhotoViewer.currentItem.state === "playing" | ||
388 | 166 | : false | ||
389 | 167 | |||
390 | 168 | // set the view to it's original state | ||
391 | 169 | function reset() { | ||
392 | 170 | delegateView.item.reset(); | ||
393 | 171 | } | ||
394 | 172 | /// Toggles between play and pause - only usful when a video is shown | ||
395 | 173 | function togglePlayPause() { | ||
396 | 174 | if (model.mediaSource.type === MediaSource.Video) | ||
397 | 175 | delegateView.item.togglePlayPause(); | ||
398 | 176 | } | ||
399 | 177 | |||
400 | 178 | onIsActiveChanged: { | ||
401 | 179 | if (!isActive) | ||
402 | 180 | reset() | ||
403 | 181 | } | ||
410 | 182 | 172 | ||
411 | 183 | width: galleryPhotoViewer.width | 173 | width: galleryPhotoViewer.width |
412 | 184 | height: galleryPhotoViewer.height | 174 | height: galleryPhotoViewer.height |
414 | 185 | state: delegateView.item.state | 175 | |
415 | 176 | // Needed as ListView.isCurrentItem can't be used directly in a change handler | ||
416 | 177 | property bool isActive: ListView.isCurrentItem | ||
417 | 178 | onIsActiveChanged: if (!isActive) reset(); | ||
418 | 186 | 179 | ||
419 | 187 | opacity: { | 180 | opacity: { |
420 | 188 | if (!galleryPhotoViewer.moving || galleryPhotoViewer.contentX < 0 | 181 | if (!galleryPhotoViewer.moving || galleryPhotoViewer.contentX < 0 |
421 | @@ -192,26 +185,12 @@ | |||
422 | 192 | return 1.0 - Math.abs((galleryPhotoViewer.contentX - x) / width); | 185 | return 1.0 - Math.abs((galleryPhotoViewer.contentX - x) / width); |
423 | 193 | } | 186 | } |
424 | 194 | 187 | ||
444 | 195 | Component { | 188 | onClicked: viewerWrapper.toggleHeaderVisibility() |
426 | 196 | id: component_delegatePhotoView | ||
427 | 197 | PhotoViewerDelegate { | ||
428 | 198 | useInteractivePreview: false | ||
429 | 199 | mediaSource: model.mediaSource | ||
430 | 200 | } | ||
431 | 201 | } | ||
432 | 202 | Component { | ||
433 | 203 | id: component_delegateVideoView | ||
434 | 204 | VideoViewerDelegate { | ||
435 | 205 | mediaSource: model.mediaSource | ||
436 | 206 | } | ||
437 | 207 | } | ||
438 | 208 | Loader { | ||
439 | 209 | id: delegateView | ||
440 | 210 | anchors.fill: parent | ||
441 | 211 | sourceComponent: model.mediaSource.type === MediaSource.Photo ? | ||
442 | 212 | component_delegatePhotoView : component_delegateVideoView | ||
443 | 213 | } | ||
445 | 214 | 189 | ||
446 | 190 | Connections { | ||
447 | 191 | target: model.mediaSource | ||
448 | 192 | onDataChanged: media.reload() | ||
449 | 193 | } | ||
450 | 215 | } | 194 | } |
451 | 216 | 195 | ||
452 | 217 | // Don't allow flicking while the chrome is actively displaying a popup | 196 | // Don't allow flicking while the chrome is actively displaying a popup |
453 | @@ -233,6 +212,8 @@ | |||
454 | 233 | anchors.fill: parent | 212 | anchors.fill: parent |
455 | 234 | visible: false | 213 | visible: false |
456 | 235 | 214 | ||
457 | 215 | onVisibleChanged: viewerWrapper.setHeaderVisibility(!visible) | ||
458 | 216 | |||
459 | 236 | ContentPeerPicker { | 217 | ContentPeerPicker { |
460 | 237 | objectName: "sharePicker" | 218 | objectName: "sharePicker" |
461 | 238 | anchors.fill: parent | 219 | anchors.fill: parent |
462 | @@ -488,123 +469,96 @@ | |||
463 | 488 | Item { | 469 | Item { |
464 | 489 | id: d | 470 | id: d |
465 | 490 | 471 | ||
469 | 491 | property Item photoToolbar: ToolbarItems { | 472 | property list<Action> photoActions: [ |
470 | 492 | ToolbarButton { | 473 | Action { |
468 | 493 | id: photoEditButton | ||
471 | 494 | objectName: "editButton" | 474 | objectName: "editButton" |
482 | 495 | action: Action { | 475 | text: i18n.tr("Edit") |
483 | 496 | text: i18n.tr("Edit") | 476 | iconSource: "../../img/edit.png" |
484 | 497 | iconSource: "../../img/edit.png" | 477 | onTriggered: PopupUtils.open(editPopoverComponent, null); |
485 | 498 | onTriggered: { | 478 | }, |
486 | 499 | PopupUtils.open(editPopoverComponent, photoEditButton); | 479 | Action { |
477 | 500 | } | ||
478 | 501 | } | ||
479 | 502 | } | ||
480 | 503 | ToolbarButton { | ||
481 | 504 | id: photoAddButton | ||
487 | 505 | objectName: "addButton" | 480 | objectName: "addButton" |
496 | 506 | action: Action { | 481 | text: i18n.tr("Add to album") |
497 | 507 | text: i18n.tr("Add photo to album") | 482 | iconName: "add" |
498 | 508 | iconSource: "../../img/add.png" | 483 | onTriggered: { |
499 | 509 | onTriggered: { | 484 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"), |
500 | 510 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"), | 485 | null, |
501 | 511 | photoAddButton, | 486 | {contentHeight: viewerWrapper.__pickerContentHeight}); |
494 | 512 | {contentHeight: viewerWrapper.__pickerContentHeight}); | ||
495 | 513 | } | ||
502 | 514 | } | 487 | } |
506 | 515 | text: i18n.tr("Add") | 488 | }, |
507 | 516 | } | 489 | Action { |
505 | 517 | ToolbarButton { | ||
508 | 518 | objectName: "deleteButton" | 490 | objectName: "deleteButton" |
509 | 519 | action: Action { | ||
510 | 520 | text: i18n.tr("Delete") | ||
511 | 521 | iconSource: "../../img/delete.png" | ||
512 | 522 | onTriggered: { | ||
513 | 523 | if (album) | ||
514 | 524 | PopupUtils.open(removeFromAlbumDialog, null); | ||
515 | 525 | else | ||
516 | 526 | PopupUtils.open(deleteDialog, null); | ||
517 | 527 | } | ||
518 | 528 | } | ||
519 | 529 | text: i18n.tr("Delete") | 491 | text: i18n.tr("Delete") |
523 | 530 | } | 492 | iconName: "delete" |
524 | 531 | ToolbarButton { | 493 | onTriggered: { |
525 | 532 | id: photoShareButton | 494 | if (album) |
526 | 495 | PopupUtils.open(removeFromAlbumDialog, null); | ||
527 | 496 | else | ||
528 | 497 | PopupUtils.open(deleteDialog, null); | ||
529 | 498 | } | ||
530 | 499 | }, | ||
531 | 500 | Action { | ||
532 | 533 | objectName: "shareButton" | 501 | objectName: "shareButton" |
533 | 502 | text: i18n.tr("Share photo") | ||
534 | 503 | iconName: "share" | ||
535 | 534 | visible: !APP.desktopMode | 504 | visible: !APP.desktopMode |
555 | 535 | action: Action { | 505 | onTriggered: sharePicker.visible = true; |
556 | 536 | text: i18n.tr("Share photo") | 506 | } |
557 | 537 | iconSource: "../../img/share.png" | 507 | ] |
558 | 538 | onTriggered: { | 508 | |
540 | 539 | sharePicker.visible = true; | ||
541 | 540 | } | ||
542 | 541 | } | ||
543 | 542 | text: i18n.tr("Share") | ||
544 | 543 | } | ||
545 | 544 | back: ToolbarButton { | ||
546 | 545 | objectName: "backButton" | ||
547 | 546 | text: i18n.tr("Back") | ||
548 | 547 | iconSource: "../../img/back.png" | ||
549 | 548 | onTriggered: { | ||
550 | 549 | galleryPhotoViewer.currentItem.reset(); | ||
551 | 550 | closeRequested(); | ||
552 | 551 | } | ||
553 | 552 | } | ||
554 | 553 | } | ||
559 | 554 | 509 | ||
562 | 555 | property Item videoToolbar: ToolbarItems { | 510 | property list<Action> videoActions: [ |
563 | 556 | ToolbarButton { | 511 | Action { |
564 | 557 | text: galleryPhotoViewer.currentItem ? | 512 | text: galleryPhotoViewer.currentItem ? |
568 | 558 | (galleryPhotoViewer.currentItem.isPlayingVideo ? | 513 | (galleryPhotoViewer.currentItem.isPlayingVideo ? |
569 | 559 | i18n.tr("Pause") : i18n.tr("Play")) | 514 | i18n.tr("Pause") : i18n.tr("Play")) |
570 | 560 | : "" | 515 | : "" |
571 | 561 | iconSource: galleryPhotoViewer.currentItem ? | 516 | iconSource: galleryPhotoViewer.currentItem ? |
584 | 562 | (galleryPhotoViewer.currentItem.isPlayingVideo ? | 517 | (galleryPhotoViewer.currentItem.isPlayingVideo ? |
585 | 563 | "../../img/icon_pause.png" : "../../img/icon_play.png") | 518 | "../../img/icon_pause.png" : "../../img/icon_play.png") |
586 | 564 | : "" | 519 | : "" |
587 | 565 | onTriggered: { | 520 | onTriggered: galleryPhotoViewer.currentItem.togglePlayPause(); |
588 | 566 | galleryPhotoViewer.currentItem.togglePlayPause(); | 521 | }, |
589 | 567 | } | 522 | Action { |
590 | 568 | } | 523 | text: i18n.tr("Add to album") |
591 | 569 | ToolbarButton { | 524 | iconName: "add" |
580 | 570 | id: videoAddButton | ||
581 | 571 | objectName: "addButton" | ||
582 | 572 | text: i18n.tr("Add") | ||
583 | 573 | iconSource: "../../img/add.png" | ||
592 | 574 | onTriggered: { | 525 | onTriggered: { |
593 | 575 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"), | 526 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"), |
595 | 576 | videoAddButton, | 527 | null, |
596 | 577 | {contentHeight: viewerWrapper.__pickerContentHeight}); | 528 | {contentHeight: viewerWrapper.__pickerContentHeight}); |
597 | 578 | } | 529 | } |
601 | 579 | } | 530 | }, |
602 | 580 | ToolbarButton { | 531 | Action { |
600 | 581 | objectName: "deleteButton" | ||
603 | 582 | text: i18n.tr("Delete") | 532 | text: i18n.tr("Delete") |
605 | 583 | iconSource: "../../img/delete.png" | 533 | iconName: "delete" |
606 | 584 | onTriggered: { | 534 | onTriggered: { |
608 | 585 | PopupUtils.open(deleteDialog, null); | 535 | if (album) |
609 | 536 | PopupUtils.open(removeFromAlbumDialog, null); | ||
610 | 537 | else | ||
611 | 538 | PopupUtils.open(deleteDialog, null); | ||
612 | 586 | } | 539 | } |
617 | 587 | } | 540 | }, |
618 | 588 | ToolbarButton { | 541 | Action { |
619 | 589 | id: videoShareButton | 542 | text: i18n.tr("Share photo") |
620 | 590 | objectName: "shareButton" | 543 | iconName: "share" |
621 | 591 | visible: !APP.desktopMode | 544 | visible: !APP.desktopMode |
627 | 592 | text: i18n.tr("Share") | 545 | onTriggered: sharePicker.visible = true; |
623 | 593 | iconSource: "../../img/share.png" | ||
624 | 594 | onTriggered: { | ||
625 | 595 | sharePicker.visible = true; | ||
626 | 596 | } | ||
628 | 597 | } | 546 | } |
629 | 547 | ] | ||
630 | 598 | 548 | ||
639 | 599 | back: ToolbarButton { | 549 | property Action backAction: Action { |
640 | 600 | objectName: "backButton" | 550 | iconName: "back" |
641 | 601 | text: i18n.tr("Back") | 551 | onTriggered: { |
642 | 602 | iconSource: "../../img/back.png" | 552 | galleryPhotoViewer.currentItem.reset(); |
643 | 603 | onTriggered: { | 553 | closeRequested(); |
636 | 604 | galleryPhotoViewer.currentItem.reset(); | ||
637 | 605 | closeRequested(); | ||
638 | 606 | } | ||
644 | 607 | } | 554 | } |
645 | 608 | } | 555 | } |
646 | 609 | } | 556 | } |
647 | 557 | |||
648 | 558 | Rectangle{ | ||
649 | 559 | id: headerBackground | ||
650 | 560 | width: parent.width | ||
651 | 561 | height: header.height | ||
652 | 562 | visible: header.visible | ||
653 | 563 | } | ||
654 | 610 | } | 564 | } |
655 | 611 | 565 | ||
656 | === removed file 'rc/qml/MediaViewer/PhotoViewerDelegate.qml' | |||
657 | --- rc/qml/MediaViewer/PhotoViewerDelegate.qml 2014-03-19 20:01:31 +0000 | |||
658 | +++ rc/qml/MediaViewer/PhotoViewerDelegate.qml 1970-01-01 00:00:00 +0000 | |||
659 | @@ -1,129 +0,0 @@ | |||
660 | 1 | /* | ||
661 | 2 | * Copyright (C) 2011-2012 Canonical Ltd | ||
662 | 3 | * | ||
663 | 4 | * This program is free software: you can redistribute it and/or modify | ||
664 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
665 | 6 | * published by the Free Software Foundation. | ||
666 | 7 | * | ||
667 | 8 | * This program is distributed in the hope that it will be useful, | ||
668 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
669 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
670 | 11 | * GNU General Public License for more details. | ||
671 | 12 | * | ||
672 | 13 | * You should have received a copy of the GNU General Public License | ||
673 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
674 | 15 | * | ||
675 | 16 | * Authors: | ||
676 | 17 | * Lucas Beeler <lucas@yorba.org> | ||
677 | 18 | */ | ||
678 | 19 | |||
679 | 20 | import QtQuick 2.0 | ||
680 | 21 | import Gallery 1.0 | ||
681 | 22 | import Ubuntu.Components 0.1 | ||
682 | 23 | import Ubuntu.Components.Popups 0.1 | ||
683 | 24 | import Ubuntu.Components.ListItems 0.1 as ListItem | ||
684 | 25 | import "../../js/Gallery.js" as Gallery | ||
685 | 26 | |||
686 | 27 | /*! | ||
687 | 28 | */ | ||
688 | 29 | Item { | ||
689 | 30 | id: photoViewerDelegate | ||
690 | 31 | |||
691 | 32 | /// The photo to show | ||
692 | 33 | property MediaSource mediaSource | ||
693 | 34 | /*! | ||
694 | 35 | */ | ||
695 | 36 | property bool useInteractivePreview | ||
696 | 37 | /*! | ||
697 | 38 | */ | ||
698 | 39 | property alias isLoaded: fullPhotoComponentLoader.isLoaded | ||
699 | 40 | |||
700 | 41 | /*! | ||
701 | 42 | */ | ||
702 | 43 | signal clicked() | ||
703 | 44 | /*! | ||
704 | 45 | */ | ||
705 | 46 | signal zoomed() | ||
706 | 47 | /*! | ||
707 | 48 | */ | ||
708 | 49 | signal unzoomed() | ||
709 | 50 | |||
710 | 51 | /// Resets the view to it's initial state | ||
711 | 52 | function reset() { | ||
712 | 53 | if (!isLoaded) | ||
713 | 54 | return; | ||
714 | 55 | |||
715 | 56 | fullPhotoComponentLoader.item.unzoom(); | ||
716 | 57 | } | ||
717 | 58 | |||
718 | 59 | Connections { | ||
719 | 60 | target: mediaSource | ||
720 | 61 | onDataChanged: { | ||
721 | 62 | // Force the image to be reloaded, to pick up the new thumbnail | ||
722 | 63 | interactivePreviewImage.active = false; | ||
723 | 64 | interactivePreviewImage.active = true; | ||
724 | 65 | } | ||
725 | 66 | } | ||
726 | 67 | |||
727 | 68 | // Note that we haven't defined a state set in this component, even though | ||
728 | 69 | // we bind the "state" property here. This is intentional and is necessary | ||
729 | 70 | // to work around a binding issue on Qt 5.0 beta 1. Given a later version | ||
730 | 71 | // of Qt, this treatment might not be necessary. | ||
731 | 72 | state: (fullPhotoComponentLoader.item && | ||
732 | 73 | !fullPhotoComponentLoader.item.fullyUnzoomed) ? "zoomed" : | ||
733 | 74 | "unzoomed"; | ||
734 | 75 | Component { | ||
735 | 76 | id: interactivePreviewImageSource | ||
736 | 77 | Image { | ||
737 | 78 | fillMode: Image.PreserveAspectFit | ||
738 | 79 | |||
739 | 80 | source: mediaSource ? mediaSource.galleryPreviewPath : "" | ||
740 | 81 | sourceSize.width: 256 | ||
741 | 82 | cache: false | ||
742 | 83 | } | ||
743 | 84 | } | ||
744 | 85 | |||
745 | 86 | Loader { | ||
746 | 87 | id: interactivePreviewImage | ||
747 | 88 | z: 0 | ||
748 | 89 | anchors.fill: parent | ||
749 | 90 | |||
750 | 91 | visible: photoViewerDelegate.state == "unzoomed" | ||
751 | 92 | sourceComponent: interactivePreviewImageSource | ||
752 | 93 | } | ||
753 | 94 | |||
754 | 95 | Loader { | ||
755 | 96 | id: fullPhotoComponentLoader | ||
756 | 97 | |||
757 | 98 | property bool isLoaded: status == Loader.Ready | ||
758 | 99 | |||
759 | 100 | z: 1 | ||
760 | 101 | asynchronous: true | ||
761 | 102 | anchors.fill: parent | ||
762 | 103 | opacity: (isLoaded && !useInteractivePreview) ? 1.0 : 0.0 | ||
763 | 104 | |||
764 | 105 | sourceComponent: (!useInteractivePreview && !sourceComponent) ? | ||
765 | 106 | fullPhotoComponent : sourceComponent; | ||
766 | 107 | |||
767 | 108 | Component { | ||
768 | 109 | id: fullPhotoComponent | ||
769 | 110 | |||
770 | 111 | ZoomablePhotoComponent { | ||
771 | 112 | id: galleryPhotoComponent | ||
772 | 113 | objectName: "openedPhoto" + index | ||
773 | 114 | |||
774 | 115 | anchors.fill: parent | ||
775 | 116 | color: "transparent" | ||
776 | 117 | |||
777 | 118 | mediaSource: photoViewerDelegate.mediaSource | ||
778 | 119 | load: true; | ||
779 | 120 | |||
780 | 121 | ownerName: "photoViewerDelegate" | ||
781 | 122 | |||
782 | 123 | onZoomed: photoViewerDelegate.zoomed() | ||
783 | 124 | onUnzoomed: photoViewerDelegate.unzoomed() | ||
784 | 125 | onClicked: photoViewerDelegate.clicked() | ||
785 | 126 | } | ||
786 | 127 | } | ||
787 | 128 | } | ||
788 | 129 | } | ||
789 | 130 | 0 | ||
790 | === modified file 'rc/qml/MediaViewer/PopupPhotoViewer.qml' | |||
791 | --- rc/qml/MediaViewer/PopupPhotoViewer.qml 2014-06-10 15:26:17 +0000 | |||
792 | +++ rc/qml/MediaViewer/PopupPhotoViewer.qml 2014-09-03 23:54:36 +0000 | |||
793 | @@ -18,7 +18,7 @@ | |||
794 | 18 | */ | 18 | */ |
795 | 19 | 19 | ||
796 | 20 | import QtQuick 2.0 | 20 | import QtQuick 2.0 |
798 | 21 | import Ubuntu.Components 0.1 | 21 | import Ubuntu.Components 1.1 |
799 | 22 | import "../Utility" | 22 | import "../Utility" |
800 | 23 | 23 | ||
801 | 24 | // A PhotoViewer that is opened and closed with the PhotoViewerTransition. | 24 | // A PhotoViewer that is opened and closed with the PhotoViewerTransition. |
802 | @@ -40,18 +40,18 @@ | |||
803 | 40 | property bool isPoppedUp: popupPhotoViewer.visible && viewer.visible && !animationRunning | 40 | property bool isPoppedUp: popupPhotoViewer.visible && viewer.visible && !animationRunning |
804 | 41 | 41 | ||
805 | 42 | // updating active will automatically set the tools of the toolbar when activating. | 42 | // updating active will automatically set the tools of the toolbar when activating. |
818 | 43 | onActiveChanged: { | 43 | //onActiveChanged: { |
819 | 44 | if (active && popupPhotoViewer.header) { | 44 | // if (active && popupPhotoViewer.header) { |
820 | 45 | popupPhotoViewer.header.hide(); | 45 | // popupPhotoViewer.header.hide(); |
821 | 46 | // FIXME: The hide function of header is not hiding it sometimes. | 46 | // // FIXME: The hide function of header is not hiding it sometimes. |
822 | 47 | // The issue started after we changed the page title | 47 | // // The issue started after we changed the page title |
823 | 48 | popupPhotoViewer.header.visible = false; | 48 | // popupPhotoViewer.header.visible = false; |
824 | 49 | } | 49 | // } |
825 | 50 | 50 | // | |
826 | 51 | if (!active && popupPhotoViewer.header && popupPhotoViewer.header.visible == false) { | 51 | // if (!active && popupPhotoViewer.header && popupPhotoViewer.header.visible == false) { |
827 | 52 | popupPhotoViewer.header.visible = true; | 52 | // popupPhotoViewer.header.visible = true; |
828 | 53 | } | 53 | // } |
829 | 54 | } | 54 | //} |
830 | 55 | 55 | ||
831 | 56 | title: i18n.tr("Gallery") | 56 | title: i18n.tr("Gallery") |
832 | 57 | 57 | ||
833 | @@ -95,7 +95,8 @@ | |||
834 | 95 | closed(); | 95 | closed(); |
835 | 96 | } | 96 | } |
836 | 97 | 97 | ||
838 | 98 | tools: viewer.tools | 98 | head.actions: viewer.actions |
839 | 99 | head.backAction: viewer.backAction | ||
840 | 99 | 100 | ||
841 | 100 | MediaViewer { | 101 | MediaViewer { |
842 | 101 | id: viewer | 102 | id: viewer |
843 | @@ -133,6 +134,7 @@ | |||
844 | 133 | setCurrentPhoto(forMediaSource); | 134 | setCurrentPhoto(forMediaSource); |
845 | 134 | viewer.openCompleted = true; | 135 | viewer.openCompleted = true; |
846 | 135 | overview.pushPage(popupPhotoViewer); | 136 | overview.pushPage(popupPhotoViewer); |
847 | 137 | header.visible = false; | ||
848 | 136 | opened(); | 138 | opened(); |
849 | 137 | viewer.playVideo(); | 139 | viewer.playVideo(); |
850 | 138 | } | 140 | } |
851 | 139 | 141 | ||
852 | === added file 'rc/qml/MediaViewer/SingleMediaViewer.qml' | |||
853 | --- rc/qml/MediaViewer/SingleMediaViewer.qml 1970-01-01 00:00:00 +0000 | |||
854 | +++ rc/qml/MediaViewer/SingleMediaViewer.qml 2014-09-03 23:54:36 +0000 | |||
855 | @@ -0,0 +1,246 @@ | |||
856 | 1 | /* | ||
857 | 2 | * Copyright 2014 Canonical Ltd. | ||
858 | 3 | * | ||
859 | 4 | * This program is free software; you can redistribute it and/or modify | ||
860 | 5 | * it under the terms of the GNU General Public License as published by | ||
861 | 6 | * the Free Software Foundation; version 3. | ||
862 | 7 | * | ||
863 | 8 | * This program is distributed in the hope that it will be useful, | ||
864 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
865 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
866 | 11 | * GNU General Public License for more details. | ||
867 | 12 | * | ||
868 | 13 | * You should have received a copy of the GNU General Public License | ||
869 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
870 | 15 | */ | ||
871 | 16 | |||
872 | 17 | import QtQuick 2.2 | ||
873 | 18 | import QtMultimedia 5.0 | ||
874 | 19 | import Ubuntu.Components 1.0 | ||
875 | 20 | import Ubuntu.Components.ListItems 1.0 as ListItems | ||
876 | 21 | import Ubuntu.Components.Popups 1.0 | ||
877 | 22 | import Ubuntu.Content 0.1 | ||
878 | 23 | import Ubuntu.Thumbnailer 0.1 | ||
879 | 24 | import Gallery 1.0 | ||
880 | 25 | import "../Components" | ||
881 | 26 | |||
882 | 27 | Item { | ||
883 | 28 | id: viewer | ||
884 | 29 | property bool pinchInProgress: zoomPinchArea.active | ||
885 | 30 | property var mediaFileType | ||
886 | 31 | property string mediaFileURL | ||
887 | 32 | property real maxDimension | ||
888 | 33 | |||
889 | 34 | property bool isVideo: mediaFileType === MediaSource.Video | ||
890 | 35 | property bool isPlayingVideo: isVideo && video.isPlaying | ||
891 | 36 | property bool userInteracting: pinchInProgress || flickable.sizeScale != 1.0 | ||
892 | 37 | property bool fullyZoomed: flickable.sizeScale == zoomPinchArea.maximumZoom | ||
893 | 38 | property bool fullyUnzoomed: flickable.sizeScale == zoomPinchArea.minimumZoom | ||
894 | 39 | |||
895 | 40 | property alias paintedHeight: image.paintedHeight | ||
896 | 41 | property alias paintedWidth: image.paintedWidth | ||
897 | 42 | |||
898 | 43 | signal clicked() | ||
899 | 44 | |||
900 | 45 | function zoomIn(centerX, centerY, factor) { | ||
901 | 46 | flickable.scaleCenterX = centerX / (flickable.sizeScale * flickable.width); | ||
902 | 47 | flickable.scaleCenterY = centerY / (flickable.sizeScale * flickable.height); | ||
903 | 48 | flickable.sizeScale = factor; | ||
904 | 49 | } | ||
905 | 50 | |||
906 | 51 | function zoomOut() { | ||
907 | 52 | if (flickable.sizeScale != 1.0) { | ||
908 | 53 | flickable.scaleCenterX = flickable.contentX / flickable.width / (flickable.sizeScale - 1); | ||
909 | 54 | flickable.scaleCenterY = flickable.contentY / flickable.height / (flickable.sizeScale - 1); | ||
910 | 55 | flickable.sizeScale = 1.0; | ||
911 | 56 | } | ||
912 | 57 | } | ||
913 | 58 | |||
914 | 59 | function reload() { | ||
915 | 60 | if (!viewer.isVideo) { | ||
916 | 61 | var src = image.source | ||
917 | 62 | image.asynchronous = false | ||
918 | 63 | image.source = "" | ||
919 | 64 | image.asynchronous = true | ||
920 | 65 | image.source = src; | ||
921 | 66 | |||
922 | 67 | src = highResolutionImage.source | ||
923 | 68 | highResolutionImage.asynchronous = false | ||
924 | 69 | highResolutionImage.source = "" | ||
925 | 70 | highResolutionImage.asynchronous = true | ||
926 | 71 | highResolutionImage.source = src | ||
927 | 72 | } | ||
928 | 73 | } | ||
929 | 74 | |||
930 | 75 | function reset() { | ||
931 | 76 | if (viewer.isVideo) { | ||
932 | 77 | if (video.item) { | ||
933 | 78 | video.item.stop(); | ||
934 | 79 | video.sourceComponent = null; | ||
935 | 80 | } | ||
936 | 81 | } else zoomOut() | ||
937 | 82 | } | ||
938 | 83 | |||
939 | 84 | function togglePlayPause() { | ||
940 | 85 | if (video.isPlaying) video.pause(); | ||
941 | 86 | else video.play(); | ||
942 | 87 | } | ||
943 | 88 | |||
944 | 89 | ActivityIndicator { | ||
945 | 90 | anchors.centerIn: parent | ||
946 | 91 | visible: running | ||
947 | 92 | running: image.status != Image.Ready | ||
948 | 93 | } | ||
949 | 94 | |||
950 | 95 | PinchArea { | ||
951 | 96 | id: zoomPinchArea | ||
952 | 97 | anchors.fill: parent | ||
953 | 98 | |||
954 | 99 | property real initialZoom | ||
955 | 100 | property real maximumScale: 3.0 | ||
956 | 101 | property real minimumZoom: 1.0 | ||
957 | 102 | property real maximumZoom: 3.0 | ||
958 | 103 | property bool active: false | ||
959 | 104 | property var center | ||
960 | 105 | |||
961 | 106 | onPinchStarted: { | ||
962 | 107 | active = true; | ||
963 | 108 | initialZoom = flickable.sizeScale; | ||
964 | 109 | center = zoomPinchArea.mapToItem(media, pinch.startCenter.x, pinch.startCenter.y); | ||
965 | 110 | zoomIn(center.x, center.y, initialZoom); | ||
966 | 111 | } | ||
967 | 112 | onPinchUpdated: { | ||
968 | 113 | var zoomFactor = MathUtils.clamp(initialZoom * pinch.scale, minimumZoom, maximumZoom); | ||
969 | 114 | flickable.sizeScale = zoomFactor; | ||
970 | 115 | } | ||
971 | 116 | onPinchFinished: { | ||
972 | 117 | active = false; | ||
973 | 118 | } | ||
974 | 119 | |||
975 | 120 | Flickable { | ||
976 | 121 | id: flickable | ||
977 | 122 | anchors.fill: parent | ||
978 | 123 | contentWidth: media.width | ||
979 | 124 | contentHeight: media.height | ||
980 | 125 | contentX: (sizeScale - 1) * scaleCenterX * width | ||
981 | 126 | contentY: (sizeScale - 1) * scaleCenterY * height | ||
982 | 127 | interactive: !viewer.pinchInProgress | ||
983 | 128 | |||
984 | 129 | property real sizeScale: 1.0 | ||
985 | 130 | property real scaleCenterX: 0.0 | ||
986 | 131 | property real scaleCenterY: 0.0 | ||
987 | 132 | Behavior on sizeScale { | ||
988 | 133 | enabled: !viewer.pinchInProgress | ||
989 | 134 | UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} | ||
990 | 135 | } | ||
991 | 136 | Behavior on scaleCenterX { | ||
992 | 137 | UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} | ||
993 | 138 | } | ||
994 | 139 | Behavior on scaleCenterY { | ||
995 | 140 | UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} | ||
996 | 141 | } | ||
997 | 142 | |||
998 | 143 | Item { | ||
999 | 144 | id: media | ||
1000 | 145 | |||
1001 | 146 | width: flickable.width * flickable.sizeScale | ||
1002 | 147 | height: flickable.height * flickable.sizeScale | ||
1003 | 148 | |||
1004 | 149 | Image { | ||
1005 | 150 | id: image | ||
1006 | 151 | anchors.fill: parent | ||
1007 | 152 | asynchronous: true | ||
1008 | 153 | cache: false | ||
1009 | 154 | source: "image://thumbnailer/" + mediaFileURL.toString() | ||
1010 | 155 | sourceSize { | ||
1011 | 156 | width: viewer.maxDimension | ||
1012 | 157 | height: viewer.maxDimension | ||
1013 | 158 | } | ||
1014 | 159 | fillMode: Image.PreserveAspectFit | ||
1015 | 160 | opacity: status == Image.Ready ? 1.0 : 0.0 | ||
1016 | 161 | Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} } | ||
1017 | 162 | |||
1018 | 163 | } | ||
1019 | 164 | |||
1020 | 165 | Image { | ||
1021 | 166 | id: highResolutionImage | ||
1022 | 167 | anchors.fill: parent | ||
1023 | 168 | asynchronous: true | ||
1024 | 169 | cache: false | ||
1025 | 170 | source: flickable.sizeScale > 1.0 ? mediaFileURL : "" | ||
1026 | 171 | sourceSize { | ||
1027 | 172 | width: width | ||
1028 | 173 | height: height | ||
1029 | 174 | } | ||
1030 | 175 | fillMode: Image.PreserveAspectFit | ||
1031 | 176 | } | ||
1032 | 177 | } | ||
1033 | 178 | |||
1034 | 179 | Loader { | ||
1035 | 180 | id: video | ||
1036 | 181 | anchors.fill: parent | ||
1037 | 182 | visible: viewer.isVideo && video.status == Loader.Ready && | ||
1038 | 183 | video.item.playbackState !== MediaPlayer.StoppedState | ||
1039 | 184 | onLoaded: { | ||
1040 | 185 | item.source = mediaFileURL; | ||
1041 | 186 | item.play() | ||
1042 | 187 | } | ||
1043 | 188 | |||
1044 | 189 | property bool isPlaying: item && item.playbackState === MediaPlayer.PlayingState | ||
1045 | 190 | function play() { | ||
1046 | 191 | if (item) item.play(); | ||
1047 | 192 | else sourceComponent = component_video; | ||
1048 | 193 | } | ||
1049 | 194 | function pause() { | ||
1050 | 195 | if (item) item.pause(); | ||
1051 | 196 | } | ||
1052 | 197 | } | ||
1053 | 198 | |||
1054 | 199 | Icon { | ||
1055 | 200 | width: units.gu(5) | ||
1056 | 201 | height: units.gu(5) | ||
1057 | 202 | anchors.centerIn: parent | ||
1058 | 203 | name: "media-playback-start" | ||
1059 | 204 | color: "white" | ||
1060 | 205 | opacity: 0.8 | ||
1061 | 206 | visible: viewer.isVideo && | ||
1062 | 207 | (!video.item || item.playbackState === MediaPlayer.StoppedState) | ||
1063 | 208 | } | ||
1064 | 209 | |||
1065 | 210 | MouseArea { | ||
1066 | 211 | anchors.fill: parent | ||
1067 | 212 | onDoubleClicked: { | ||
1068 | 213 | clickTimer.stop(); | ||
1069 | 214 | if (viewer.isVideo) return; | ||
1070 | 215 | |||
1071 | 216 | if (flickable.sizeScale < zoomPinchArea.maximumZoom) { | ||
1072 | 217 | zoomIn(mouse.x, mouse.y, zoomPinchArea.maximumZoom); | ||
1073 | 218 | } else { | ||
1074 | 219 | zoomOut(); | ||
1075 | 220 | } | ||
1076 | 221 | } | ||
1077 | 222 | onClicked: clickTimer.start() | ||
1078 | 223 | |||
1079 | 224 | Timer { | ||
1080 | 225 | id: clickTimer | ||
1081 | 226 | interval: 20 | ||
1082 | 227 | onTriggered: viewer.clicked() | ||
1083 | 228 | } | ||
1084 | 229 | } | ||
1085 | 230 | |||
1086 | 231 | MouseArea { | ||
1087 | 232 | anchors.centerIn: parent | ||
1088 | 233 | width: units.gu(10) | ||
1089 | 234 | height: units.gu(10) | ||
1090 | 235 | enabled: viewer.isVideo | ||
1091 | 236 | onClicked: viewer.togglePlayPause() | ||
1092 | 237 | } | ||
1093 | 238 | } | ||
1094 | 239 | |||
1095 | 240 | Component { | ||
1096 | 241 | id: component_video | ||
1097 | 242 | Video { } | ||
1098 | 243 | } | ||
1099 | 244 | } | ||
1100 | 245 | } | ||
1101 | 246 | |||
1102 | 0 | 247 | ||
1103 | === removed file 'rc/qml/MediaViewer/VideoViewerDelegate.qml' | |||
1104 | --- rc/qml/MediaViewer/VideoViewerDelegate.qml 2014-03-21 22:11:44 +0000 | |||
1105 | +++ rc/qml/MediaViewer/VideoViewerDelegate.qml 1970-01-01 00:00:00 +0000 | |||
1106 | @@ -1,125 +0,0 @@ | |||
1107 | 1 | /* | ||
1108 | 2 | * Copyright (C) 2013 Canonical Ltd | ||
1109 | 3 | * | ||
1110 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1111 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
1112 | 6 | * published by the Free Software Foundation. | ||
1113 | 7 | * | ||
1114 | 8 | * This program is distributed in the hope that it will be useful, | ||
1115 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1116 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1117 | 11 | * GNU General Public License for more details. | ||
1118 | 12 | * | ||
1119 | 13 | * You should have received a copy of the GNU General Public License | ||
1120 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1121 | 15 | */ | ||
1122 | 16 | |||
1123 | 17 | import QtQuick 2.0 | ||
1124 | 18 | import QtMultimedia 5.0 | ||
1125 | 19 | import Gallery 1.0 | ||
1126 | 20 | |||
1127 | 21 | /*! | ||
1128 | 22 | VideoViewerDelegate is an item to show a vide thumbnail, and play the video | ||
1129 | 23 | if requrested | ||
1130 | 24 | */ | ||
1131 | 25 | Item { | ||
1132 | 26 | id: videoViewerDelegate | ||
1133 | 27 | |||
1134 | 28 | /// The video item that to be shown by this component | ||
1135 | 29 | property MediaSource mediaSource | ||
1136 | 30 | /// Is true, once this component is fully usable | ||
1137 | 31 | property bool isLoaded: thumbnail.status === Image.Ready | ||
1138 | 32 | |||
1139 | 33 | /// Stops the video playback if running | ||
1140 | 34 | function reset() { | ||
1141 | 35 | state = "stopped"; | ||
1142 | 36 | } | ||
1143 | 37 | |||
1144 | 38 | /// Starts playing the video | ||
1145 | 39 | function playVideo() { | ||
1146 | 40 | if (!loader_video.item) | ||
1147 | 41 | loader_video.sourceComponent = component_video; | ||
1148 | 42 | |||
1149 | 43 | if (loader_video.item.source !== mediaSource.path) | ||
1150 | 44 | loader_video.item.source = mediaSource.path; | ||
1151 | 45 | loader_video.item.play(); | ||
1152 | 46 | } | ||
1153 | 47 | |||
1154 | 48 | /// Toggles between playing and pausing the video playback | ||
1155 | 49 | function togglePlayPause() { | ||
1156 | 50 | if (!loader_video.item) | ||
1157 | 51 | loader_video.sourceComponent = component_video; | ||
1158 | 52 | |||
1159 | 53 | if (videoViewerDelegate.state === "playing") { | ||
1160 | 54 | loader_video.item.pause(); | ||
1161 | 55 | } else { | ||
1162 | 56 | videoViewerDelegate.playVideo(); | ||
1163 | 57 | } | ||
1164 | 58 | } | ||
1165 | 59 | |||
1166 | 60 | Image { | ||
1167 | 61 | id: thumbnail | ||
1168 | 62 | |||
1169 | 63 | anchors.fill: parent | ||
1170 | 64 | fillMode: Image.PreserveAspectFit | ||
1171 | 65 | source: mediaSource.galleryPreviewPath | ||
1172 | 66 | asynchronous: true | ||
1173 | 67 | } | ||
1174 | 68 | |||
1175 | 69 | Image { | ||
1176 | 70 | // Display a play icon if the media is a video | ||
1177 | 71 | source: "../../img/icon_play.png" | ||
1178 | 72 | anchors.centerIn: parent | ||
1179 | 73 | } | ||
1180 | 74 | |||
1181 | 75 | MouseArea { | ||
1182 | 76 | anchors.fill: parent | ||
1183 | 77 | onClicked: { | ||
1184 | 78 | videoViewerDelegate.togglePlayPause(); | ||
1185 | 79 | } | ||
1186 | 80 | } | ||
1187 | 81 | |||
1188 | 82 | Component { | ||
1189 | 83 | id: component_video | ||
1190 | 84 | Video { | ||
1191 | 85 | id: video | ||
1192 | 86 | onStopped: { | ||
1193 | 87 | videoViewerDelegate.state = "stopped"; | ||
1194 | 88 | } | ||
1195 | 89 | onPaused: { | ||
1196 | 90 | videoViewerDelegate.state = "paused" | ||
1197 | 91 | } | ||
1198 | 92 | onPlaying: { | ||
1199 | 93 | videoViewerDelegate.state = "playing" | ||
1200 | 94 | } | ||
1201 | 95 | } | ||
1202 | 96 | } | ||
1203 | 97 | Loader { | ||
1204 | 98 | id: loader_video | ||
1205 | 99 | anchors.fill: parent | ||
1206 | 100 | } | ||
1207 | 101 | |||
1208 | 102 | |||
1209 | 103 | state: "stopped" | ||
1210 | 104 | states: [ | ||
1211 | 105 | State { | ||
1212 | 106 | name: "playing" | ||
1213 | 107 | PropertyChanges { target: thumbnail; visible: false } | ||
1214 | 108 | }, | ||
1215 | 109 | State { | ||
1216 | 110 | name: "paused" | ||
1217 | 111 | PropertyChanges { target: thumbnail; visible: false } | ||
1218 | 112 | }, | ||
1219 | 113 | State { | ||
1220 | 114 | name: "stopped" | ||
1221 | 115 | PropertyChanges { target: thumbnail; visible: true } | ||
1222 | 116 | } | ||
1223 | 117 | ] | ||
1224 | 118 | onStateChanged: { | ||
1225 | 119 | if (state === "stopped") { | ||
1226 | 120 | if (loader_video.item) | ||
1227 | 121 | loader_video.item.stop() | ||
1228 | 122 | loader_video.sourceComponent = null | ||
1229 | 123 | } | ||
1230 | 124 | } | ||
1231 | 125 | } | ||
1232 | 126 | 0 | ||
1233 | === removed file 'rc/qml/MediaViewer/ZoomablePhotoComponent.qml' | |||
1234 | --- rc/qml/MediaViewer/ZoomablePhotoComponent.qml 2014-04-04 13:16:49 +0000 | |||
1235 | +++ rc/qml/MediaViewer/ZoomablePhotoComponent.qml 1970-01-01 00:00:00 +0000 | |||
1236 | @@ -1,409 +0,0 @@ | |||
1237 | 1 | /* | ||
1238 | 2 | * Copyright (C) 2012 Canonical Ltd | ||
1239 | 3 | * | ||
1240 | 4 | * This program is free software: you can redistribute it and/or modify | ||
1241 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
1242 | 6 | * published by the Free Software Foundation. | ||
1243 | 7 | * | ||
1244 | 8 | * This program is distributed in the hope that it will be useful, | ||
1245 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1246 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1247 | 11 | * GNU General Public License for more details. | ||
1248 | 12 | * | ||
1249 | 13 | * You should have received a copy of the GNU General Public License | ||
1250 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1251 | 15 | * | ||
1252 | 16 | * Authors: | ||
1253 | 17 | * Charles Lindsay <chaz@yorba.org> | ||
1254 | 18 | * Lucas Beeler <lucas@yorba.org> | ||
1255 | 19 | */ | ||
1256 | 20 | |||
1257 | 21 | import QtQuick 2.0 | ||
1258 | 22 | import "../../js/Gallery.js" as Gallery | ||
1259 | 23 | import "../../js/GalleryUtility.js" as GalleryUtility | ||
1260 | 24 | import "../../js/GraphicsRoutines.js" as GraphicsRoutines | ||
1261 | 25 | import "../Components" | ||
1262 | 26 | |||
1263 | 27 | // PhotoComponent that allows you to zoom in on the photo. | ||
1264 | 28 | Rectangle { | ||
1265 | 29 | id: zoomablePhotoComponent | ||
1266 | 30 | |||
1267 | 31 | /*! | ||
1268 | 32 | */ | ||
1269 | 33 | signal loaded() | ||
1270 | 34 | /*! | ||
1271 | 35 | */ | ||
1272 | 36 | signal clicked() | ||
1273 | 37 | /*! | ||
1274 | 38 | */ | ||
1275 | 39 | signal zoomed() | ||
1276 | 40 | /*! | ||
1277 | 41 | */ | ||
1278 | 42 | signal unzoomed() | ||
1279 | 43 | |||
1280 | 44 | /*! | ||
1281 | 45 | */ | ||
1282 | 46 | property var mediaSource | ||
1283 | 47 | /*! | ||
1284 | 48 | */ | ||
1285 | 49 | property bool load: false | ||
1286 | 50 | /*! | ||
1287 | 51 | */ | ||
1288 | 52 | property bool isPreview | ||
1289 | 53 | /*! | ||
1290 | 54 | */ | ||
1291 | 55 | property string ownerName | ||
1292 | 56 | |||
1293 | 57 | // read-only | ||
1294 | 58 | /*! | ||
1295 | 59 | */ | ||
1296 | 60 | property alias paintedWidth: unzoomedPhoto.paintedWidth | ||
1297 | 61 | /*! | ||
1298 | 62 | */ | ||
1299 | 63 | property alias paintedHeight: unzoomedPhoto.paintedHeight | ||
1300 | 64 | /*! | ||
1301 | 65 | */ | ||
1302 | 66 | property alias isLoaded: unzoomedPhoto.isLoaded | ||
1303 | 67 | /*! | ||
1304 | 68 | */ | ||
1305 | 69 | property int zoomFocusX: 0 // Relative to zoomablePhotoComponent. | ||
1306 | 70 | /*! | ||
1307 | 71 | */ | ||
1308 | 72 | property int zoomFocusY: 0 | ||
1309 | 73 | /*! | ||
1310 | 74 | */ | ||
1311 | 75 | property real zoomFactor: 1 | ||
1312 | 76 | /*! | ||
1313 | 77 | */ | ||
1314 | 78 | property bool fullyUnzoomed: (state === "unzoomed" && zoomFactor === 1) | ||
1315 | 79 | /*! | ||
1316 | 80 | */ | ||
1317 | 81 | property bool fullyZoomed: (state === "full_zoom" && zoomFactor === maxZoomFactor) | ||
1318 | 82 | |||
1319 | 83 | // Though little documented, Qt has a dedicated background thread, separate | ||
1320 | 84 | // from the main GUI thread, in which it renders on-screen objects (see | ||
1321 | 85 | // http://blog.qt.digia.com/blog/2012/08/20/render-thread-animations-in-qt-quick-2-0/ | ||
1322 | 86 | // for a discussion of this topic). Unfortunately, animation ticks are timed | ||
1323 | 87 | // by the main GUI thread, but actual drawing in response to these ticks | ||
1324 | 88 | // is done in the separate rendering thread. Because of this, you can get | ||
1325 | 89 | // into a situation in which an animation reports that it has completed but | ||
1326 | 90 | // the separate rendering thread still has a frame to draw. In all of my | ||
1327 | 91 | // testing, I've never seen this timing mismatch exceed 1/30th of a second, | ||
1328 | 92 | // which makes sense because the QML animation clock ticks every 1/60th of a | ||
1329 | 93 | // second, according to the docs (see http://qt-project.org/doc/qt-5.0/qtqml/qml-qtquick2-timer.html), | ||
1330 | 94 | // though implementations appear to be free to drop to half this rate | ||
1331 | 95 | // (see https://bugreports.qt-project.org/browse/QTBUG-28487). So we define | ||
1332 | 96 | // an animation frame as 1/30th of a second and wait this long before doing | ||
1333 | 97 | // more drawing in response to the completion of an animation to prevent | ||
1334 | 98 | // stuttering. | ||
1335 | 99 | property int oneFrame: Math.ceil(1000 / 30); | ||
1336 | 100 | |||
1337 | 101 | // internal | ||
1338 | 102 | /*! | ||
1339 | 103 | */ | ||
1340 | 104 | property real maxZoomFactor: 2.5 | ||
1341 | 105 | /*! | ||
1342 | 106 | */ | ||
1343 | 107 | property real photoFocusX: zoomFocusX - unzoomedPhoto.leftEdge | ||
1344 | 108 | /*! | ||
1345 | 109 | */ | ||
1346 | 110 | property real photoFocusY: zoomFocusY - unzoomedPhoto.topEdge | ||
1347 | 111 | /*! | ||
1348 | 112 | */ | ||
1349 | 113 | property bool isZoomAnimationInProgress: false | ||
1350 | 114 | |||
1351 | 115 | clip: true | ||
1352 | 116 | |||
1353 | 117 | /*! | ||
1354 | 118 | */ | ||
1355 | 119 | function zoom(x, y) { | ||
1356 | 120 | zoomFocusX = x; | ||
1357 | 121 | zoomFocusY = y; | ||
1358 | 122 | state = "full_zoom"; | ||
1359 | 123 | } | ||
1360 | 124 | |||
1361 | 125 | /*! | ||
1362 | 126 | */ | ||
1363 | 127 | function unzoom() { | ||
1364 | 128 | state = "unzoomed"; | ||
1365 | 129 | } | ||
1366 | 130 | |||
1367 | 131 | /*! | ||
1368 | 132 | */ | ||
1369 | 133 | function toggleZoom(x, y) { | ||
1370 | 134 | if (state === "unzoomed") | ||
1371 | 135 | zoom(x, y); | ||
1372 | 136 | else | ||
1373 | 137 | unzoom(); | ||
1374 | 138 | } | ||
1375 | 139 | |||
1376 | 140 | states: [ | ||
1377 | 141 | State { name: "unzoomed"; | ||
1378 | 142 | PropertyChanges { target: zoomablePhotoComponent; zoomFactor: 1; } | ||
1379 | 143 | }, | ||
1380 | 144 | State { name: "full_zoom"; | ||
1381 | 145 | PropertyChanges { target: zoomablePhotoComponent; zoomFactor: maxZoomFactor; } | ||
1382 | 146 | }, | ||
1383 | 147 | State { name: "pinching"; | ||
1384 | 148 | // Setting the zoom factor to itself seems odd, but it's necessary to | ||
1385 | 149 | // prevent zoomFactor from jumping when you start pinching. | ||
1386 | 150 | PropertyChanges { target: zoomablePhotoComponent; zoomFactor: zoomFactor; | ||
1387 | 151 | explicit: true; } | ||
1388 | 152 | } | ||
1389 | 153 | ] | ||
1390 | 154 | |||
1391 | 155 | transitions: [ | ||
1392 | 156 | // Double-click transitions. | ||
1393 | 157 | Transition { from: "full_zoom"; to: "unzoomed"; | ||
1394 | 158 | SequentialAnimation { | ||
1395 | 159 | ScriptAction { script: isZoomAnimationInProgress = true; } | ||
1396 | 160 | NumberAnimation { properties: "zoomFactor"; easing.type: Easing.InQuad; | ||
1397 | 161 | duration: Gallery.FAST_DURATION; } | ||
1398 | 162 | PauseAnimation { duration: oneFrame } | ||
1399 | 163 | ScriptAction { script: isZoomAnimationInProgress = false; } | ||
1400 | 164 | } | ||
1401 | 165 | }, | ||
1402 | 166 | |||
1403 | 167 | Transition { from: "unzoomed"; to: "full_zoom"; | ||
1404 | 168 | SequentialAnimation { | ||
1405 | 169 | ScriptAction { script: isZoomAnimationInProgress = true; } | ||
1406 | 170 | NumberAnimation { properties: "zoomFactor"; easing.type: Easing.InQuad; | ||
1407 | 171 | duration: Gallery.FAST_DURATION; } | ||
1408 | 172 | PauseAnimation { duration: oneFrame } | ||
1409 | 173 | ScriptAction { script: isZoomAnimationInProgress = false; } | ||
1410 | 174 | } | ||
1411 | 175 | }, | ||
1412 | 176 | |||
1413 | 177 | Transition { from: "pinching"; to: "unzoomed"; | ||
1414 | 178 | SequentialAnimation { | ||
1415 | 179 | ScriptAction { script: isZoomAnimationInProgress = true; } | ||
1416 | 180 | NumberAnimation { properties: "zoomFactor"; easing.type: Easing.Linear; | ||
1417 | 181 | duration: Gallery.SNAP_DURATION; } | ||
1418 | 182 | PauseAnimation { duration: oneFrame } | ||
1419 | 183 | ScriptAction { script: isZoomAnimationInProgress = false; } | ||
1420 | 184 | } | ||
1421 | 185 | }, | ||
1422 | 186 | |||
1423 | 187 | Transition { from: "pinching"; to: "full_zoom"; | ||
1424 | 188 | SequentialAnimation { | ||
1425 | 189 | ScriptAction { script: isZoomAnimationInProgress = true; } | ||
1426 | 190 | NumberAnimation { properties: "zoomFactor"; easing.type: Easing.Linear; | ||
1427 | 191 | duration: Gallery.SNAP_DURATION; } | ||
1428 | 192 | PauseAnimation { duration: oneFrame } | ||
1429 | 193 | ScriptAction { script: isZoomAnimationInProgress = false; } | ||
1430 | 194 | } | ||
1431 | 195 | } | ||
1432 | 196 | ] | ||
1433 | 197 | |||
1434 | 198 | state: "unzoomed" | ||
1435 | 199 | |||
1436 | 200 | onStateChanged: { | ||
1437 | 201 | if (state === "full_zoom") | ||
1438 | 202 | zoomed(); | ||
1439 | 203 | else if (state === "unzoomed") | ||
1440 | 204 | unzoomed(); | ||
1441 | 205 | } | ||
1442 | 206 | |||
1443 | 207 | GalleryPhotoComponent { | ||
1444 | 208 | id: unzoomedPhoto | ||
1445 | 209 | |||
1446 | 210 | property real leftEdge: (parent.width - paintedWidth) / 2 | ||
1447 | 211 | property real topEdge: (parent.height - paintedHeight) / 2 | ||
1448 | 212 | |||
1449 | 213 | function isInsidePhoto(x, y) { | ||
1450 | 214 | return (x >= leftEdge && x < leftEdge + paintedWidth && | ||
1451 | 215 | y >= topEdge && y < topEdge + paintedHeight); | ||
1452 | 216 | } | ||
1453 | 217 | |||
1454 | 218 | anchors.fill: parent | ||
1455 | 219 | visible: fullyUnzoomed | ||
1456 | 220 | color: zoomablePhotoComponent.color | ||
1457 | 221 | |||
1458 | 222 | mediaSource: zoomablePhotoComponent.mediaSource | ||
1459 | 223 | load: zoomablePhotoComponent.load && zoomablePhotoComponent.fullyUnzoomed | ||
1460 | 224 | isPreview: zoomablePhotoComponent.isPreview | ||
1461 | 225 | ownerName: zoomablePhotoComponent.ownerName + "unzoomedPhoto" | ||
1462 | 226 | } | ||
1463 | 227 | |||
1464 | 228 | PinchArea { | ||
1465 | 229 | id: pinchArea | ||
1466 | 230 | |||
1467 | 231 | property bool zoomingIn // Splaying to zoom in, vs. pinching to zoom out. | ||
1468 | 232 | property real initialZoomFactor | ||
1469 | 233 | |||
1470 | 234 | anchors.fill: parent | ||
1471 | 235 | |||
1472 | 236 | // QML seems to ignore these, so we have to manually keep scale in check | ||
1473 | 237 | // inside onPinchUpdated. The 0.9 and 1.1 are just fudge factors to give | ||
1474 | 238 | // us a little bounce when you go past the zoom limit. | ||
1475 | 239 | pinch.minimumScale: 1 / initialZoomFactor * 0.9 | ||
1476 | 240 | pinch.maximumScale: maxZoomFactor / initialZoomFactor * 1.1 | ||
1477 | 241 | |||
1478 | 242 | onPinchStarted: { | ||
1479 | 243 | zoomingIn = false; | ||
1480 | 244 | initialZoomFactor = zoomFactor; | ||
1481 | 245 | |||
1482 | 246 | if (fullyUnzoomed) { | ||
1483 | 247 | if (unzoomedPhoto.isInsidePhoto(pinch.center.x, pinch.center.y)) { | ||
1484 | 248 | zoomFocusX = pinch.center.x; | ||
1485 | 249 | zoomFocusY = pinch.center.y; | ||
1486 | 250 | } else { | ||
1487 | 251 | zoomFocusX = parent.width / 2; | ||
1488 | 252 | zoomFocusY = parent.height / 2; | ||
1489 | 253 | } | ||
1490 | 254 | } | ||
1491 | 255 | |||
1492 | 256 | zoomablePhotoComponent.state = "pinching"; | ||
1493 | 257 | } | ||
1494 | 258 | |||
1495 | 259 | onPinchUpdated: { | ||
1496 | 260 | // Determine if we're still zooming in or out. Allow for a small | ||
1497 | 261 | // variance to account for touch noise. | ||
1498 | 262 | if (Math.abs(pinch.scale - pinch.previousScale) > 0.001) | ||
1499 | 263 | zoomingIn = (pinch.scale > pinch.previousScale); | ||
1500 | 264 | |||
1501 | 265 | // For some reason, the PinchArea ignores these settings. | ||
1502 | 266 | var scale = GraphicsRoutines.clamp(pinch.scale, | ||
1503 | 267 | pinchArea.pinch.minimumScale, pinchArea.pinch.maximumScale); | ||
1504 | 268 | |||
1505 | 269 | zoomFactor = initialZoomFactor * scale; | ||
1506 | 270 | } | ||
1507 | 271 | |||
1508 | 272 | onPinchFinished: zoomablePhotoComponent.state = (zoomingIn ? "full_zoom" : "unzoomed") | ||
1509 | 273 | |||
1510 | 274 | MouseAreaWithMultipoint { | ||
1511 | 275 | desktop: APP.desktopMode | ||
1512 | 276 | anchors.fill: parent | ||
1513 | 277 | enabled: fullyUnzoomed | ||
1514 | 278 | |||
1515 | 279 | onClicked: zoomablePhotoComponent.clicked() | ||
1516 | 280 | onDoubleClicked: { | ||
1517 | 281 | if (unzoomedPhoto.isInsidePhoto(mouse.x, mouse.y)) | ||
1518 | 282 | zoom(mouse.x, mouse.y); | ||
1519 | 283 | else | ||
1520 | 284 | zoomablePhotoComponent.clicked(); | ||
1521 | 285 | } | ||
1522 | 286 | } | ||
1523 | 287 | } | ||
1524 | 288 | |||
1525 | 289 | Loader { | ||
1526 | 290 | id: zoomAssemblyLoader | ||
1527 | 291 | |||
1528 | 292 | anchors.fill: parent | ||
1529 | 293 | |||
1530 | 294 | sourceComponent: (fullyUnzoomed ? undefined : zoomAssemblyComponent) | ||
1531 | 295 | |||
1532 | 296 | Component { | ||
1533 | 297 | id: zoomAssemblyComponent | ||
1534 | 298 | |||
1535 | 299 | Item { | ||
1536 | 300 | anchors.fill: parent | ||
1537 | 301 | |||
1538 | 302 | Flickable { | ||
1539 | 303 | id: zoomArea | ||
1540 | 304 | |||
1541 | 305 | property real zoomAreaZoomFactor: maxZoomFactor | ||
1542 | 306 | property real minContentFocusX: (contentWidth < parent.width | ||
1543 | 307 | ? contentWidth : parent.width) / 2 | ||
1544 | 308 | property real maxContentFocusX: contentWidth - minContentFocusX | ||
1545 | 309 | property real minContentFocusY: (contentHeight < parent.height | ||
1546 | 310 | ? contentHeight : parent.height) / 2 | ||
1547 | 311 | property real maxContentFocusY: contentHeight - minContentFocusY | ||
1548 | 312 | property real contentFocusX: GraphicsRoutines.clamp( | ||
1549 | 313 | photoFocusX * zoomAreaZoomFactor, | ||
1550 | 314 | minContentFocusX, maxContentFocusX) | ||
1551 | 315 | property real contentFocusY: GraphicsRoutines.clamp( | ||
1552 | 316 | photoFocusY * zoomAreaZoomFactor, | ||
1553 | 317 | minContentFocusY, maxContentFocusY) | ||
1554 | 318 | // Translate between focus point and top/left point. Note: you might think | ||
1555 | 319 | // that this should take into account the left and top margins, but | ||
1556 | 320 | // apparently not. | ||
1557 | 321 | property real contentFocusLeft: contentFocusX - parent.width / 2 | ||
1558 | 322 | property real contentFocusTop: contentFocusY - parent.height / 2 | ||
1559 | 323 | |||
1560 | 324 | anchors.fill: parent | ||
1561 | 325 | visible: fullyZoomed && !isZoomAnimationInProgress | ||
1562 | 326 | |||
1563 | 327 | onVisibleChanged: { | ||
1564 | 328 | if (visible) { | ||
1565 | 329 | contentX = contentFocusLeft; | ||
1566 | 330 | contentY = contentFocusTop; | ||
1567 | 331 | } | ||
1568 | 332 | } | ||
1569 | 333 | |||
1570 | 334 | onContentXChanged: { | ||
1571 | 335 | var contentFocusX = contentX + width / 2; | ||
1572 | 336 | var photoFocusX = contentFocusX / zoomAreaZoomFactor; | ||
1573 | 337 | zoomFocusX = photoFocusX + unzoomedPhoto.leftEdge; | ||
1574 | 338 | } | ||
1575 | 339 | |||
1576 | 340 | onContentYChanged: { | ||
1577 | 341 | var contentFocusY = contentY + height / 2; | ||
1578 | 342 | var photoFocusY = contentFocusY / zoomAreaZoomFactor; | ||
1579 | 343 | zoomFocusY = photoFocusY + unzoomedPhoto.topEdge; | ||
1580 | 344 | } | ||
1581 | 345 | |||
1582 | 346 | flickableDirection: Flickable.HorizontalAndVerticalFlick | ||
1583 | 347 | contentWidth: unzoomedPhoto.paintedWidth * zoomAreaZoomFactor | ||
1584 | 348 | contentHeight: unzoomedPhoto.paintedHeight * zoomAreaZoomFactor | ||
1585 | 349 | |||
1586 | 350 | leftMargin: Math.max(0, (parent.width - contentWidth) / 2) | ||
1587 | 351 | rightMargin: leftMargin | ||
1588 | 352 | topMargin: Math.max(0, (parent.height - contentHeight) / 2) | ||
1589 | 353 | bottomMargin: topMargin | ||
1590 | 354 | |||
1591 | 355 | GalleryPhotoComponent { | ||
1592 | 356 | id: zoomedPhoto | ||
1593 | 357 | |||
1594 | 358 | anchors.fill: parent | ||
1595 | 359 | color: zoomablePhotoComponent.color | ||
1596 | 360 | |||
1597 | 361 | mediaSource: zoomablePhotoComponent.mediaSource | ||
1598 | 362 | load: zoomablePhotoComponent.load && fullyZoomed | ||
1599 | 363 | |||
1600 | 364 | isPreview: zoomablePhotoComponent.isPreview | ||
1601 | 365 | ownerName: zoomablePhotoComponent.ownerName + "zoomedPhoto" | ||
1602 | 366 | |||
1603 | 367 | MouseAreaWithMultipoint { | ||
1604 | 368 | desktop: APP.desktopMode | ||
1605 | 369 | anchors.fill: parent | ||
1606 | 370 | |||
1607 | 371 | onClicked: zoomablePhotoComponent.clicked() | ||
1608 | 372 | onDoubleClicked: unzoom() | ||
1609 | 373 | } | ||
1610 | 374 | } | ||
1611 | 375 | } | ||
1612 | 376 | |||
1613 | 377 | GalleryPhotoComponent { | ||
1614 | 378 | id: transitionPhoto | ||
1615 | 379 | |||
1616 | 380 | property real unzoomedX: unzoomedPhoto.leftEdge | ||
1617 | 381 | property real unzoomedY: unzoomedPhoto.topEdge | ||
1618 | 382 | property real zoomedX: -zoomArea.contentFocusLeft | ||
1619 | 383 | property real zoomedY: -zoomArea.contentFocusTop | ||
1620 | 384 | |||
1621 | 385 | property real zoomFraction: (zoomFactor - 1) / (maxZoomFactor - 1) | ||
1622 | 386 | |||
1623 | 387 | x: GalleryUtility.interpolate(unzoomedX, zoomedX, zoomFraction) | ||
1624 | 388 | y: GalleryUtility.interpolate(unzoomedY, zoomedY, zoomFraction) | ||
1625 | 389 | width: unzoomedPhoto.paintedWidth | ||
1626 | 390 | height: unzoomedPhoto.paintedHeight | ||
1627 | 391 | scale: zoomFactor | ||
1628 | 392 | transformOrigin: Item.TopLeft | ||
1629 | 393 | |||
1630 | 394 | visible: zoomablePhotoComponent.isZoomAnimationInProgress || | ||
1631 | 395 | zoomablePhotoComponent.state == "pinching" || | ||
1632 | 396 | !zoomedPhoto.isLoaded | ||
1633 | 397 | |||
1634 | 398 | color: zoomablePhotoComponent.color | ||
1635 | 399 | |||
1636 | 400 | mediaSource: zoomablePhotoComponent.mediaSource | ||
1637 | 401 | load: zoomablePhotoComponent.load | ||
1638 | 402 | isPreview: zoomablePhotoComponent.isPreview | ||
1639 | 403 | isAnimate: true | ||
1640 | 404 | ownerName: zoomablePhotoComponent.ownerName + "transitionPhoto" | ||
1641 | 405 | } | ||
1642 | 406 | } | ||
1643 | 407 | } | ||
1644 | 408 | } | ||
1645 | 409 | } | ||
1646 | 410 | 0 | ||
1647 | === modified file 'rc/qml/OrganicView/OrganicView.qml' | |||
1648 | --- rc/qml/OrganicView/OrganicView.qml 2014-03-10 17:20:03 +0000 | |||
1649 | +++ rc/qml/OrganicView/OrganicView.qml 2014-09-03 23:54:36 +0000 | |||
1650 | @@ -18,7 +18,7 @@ | |||
1651 | 18 | */ | 18 | */ |
1652 | 19 | 19 | ||
1653 | 20 | import QtQuick 2.0 | 20 | import QtQuick 2.0 |
1655 | 21 | import Ubuntu.Components 0.1 | 21 | import Ubuntu.Components 1.1 |
1656 | 22 | import "../Utility" | 22 | import "../Utility" |
1657 | 23 | import "../../js/Gallery.js" as Gallery | 23 | import "../../js/Gallery.js" as Gallery |
1658 | 24 | 24 | ||
1659 | 25 | 25 | ||
1660 | === modified file 'rc/qml/PhotosOverview.qml' | |||
1661 | --- rc/qml/PhotosOverview.qml 2013-09-30 17:01:38 +0000 | |||
1662 | +++ rc/qml/PhotosOverview.qml 2014-09-03 23:54:36 +0000 | |||
1663 | @@ -111,7 +111,7 @@ | |||
1664 | 111 | } | 111 | } |
1665 | 112 | onAddClicked: { | 112 | onAddClicked: { |
1666 | 113 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("Components/PopupAlbumPicker.qml"), | 113 | __albumPicker = PopupUtils.open(Qt.resolvedUrl("Components/PopupAlbumPicker.qml"), |
1668 | 114 | caller, | 114 | null, |
1669 | 115 | {contentHeight: photosOverview.__pickerContentHeight}); | 115 | {contentHeight: photosOverview.__pickerContentHeight}); |
1670 | 116 | } | 116 | } |
1671 | 117 | onDeleteClicked: { | 117 | onDeleteClicked: { |
1672 | 118 | 118 | ||
1673 | === modified file 'rc/qml/PickerScreen.qml' | |||
1674 | --- rc/qml/PickerScreen.qml 2014-08-14 10:59:38 +0000 | |||
1675 | +++ rc/qml/PickerScreen.qml 2014-09-03 23:54:36 +0000 | |||
1676 | @@ -15,7 +15,7 @@ | |||
1677 | 15 | */ | 15 | */ |
1678 | 16 | 16 | ||
1679 | 17 | import QtQuick 2.0 | 17 | import QtQuick 2.0 |
1681 | 18 | import Ubuntu.Components 0.1 | 18 | import Ubuntu.Components 1.1 |
1682 | 19 | import Gallery 1.0 | 19 | import Gallery 1.0 |
1683 | 20 | import "Components" | 20 | import "Components" |
1684 | 21 | import "OrganicView" | 21 | import "OrganicView" |
1685 | @@ -29,6 +29,8 @@ | |||
1686 | 29 | id: pickerMainView | 29 | id: pickerMainView |
1687 | 30 | objectName: "pickerMainView" | 30 | objectName: "pickerMainView" |
1688 | 31 | 31 | ||
1689 | 32 | useDeprecatedToolbar: false | ||
1690 | 33 | |||
1691 | 32 | /// Model of all media | 34 | /// Model of all media |
1692 | 33 | property MediaCollectionModel mediaLibrary: MediaCollectionModel { | 35 | property MediaCollectionModel mediaLibrary: MediaCollectionModel { |
1693 | 34 | monitored: true | 36 | monitored: true |
1694 | @@ -58,7 +60,8 @@ | |||
1695 | 58 | id: eventSelectView | 60 | id: eventSelectView |
1696 | 59 | objectName: "eventSelectView" | 61 | objectName: "eventSelectView" |
1697 | 60 | 62 | ||
1699 | 61 | tools: pickTools | 63 | head.actions: pickActions |
1700 | 64 | |||
1701 | 62 | selection: pickerMainView.selection | 65 | selection: pickerMainView.selection |
1702 | 63 | model: EventCollectionModel { | 66 | model: EventCollectionModel { |
1703 | 64 | mediaTypeFilter: APP.mediaTypeFilter | 67 | mediaTypeFilter: APP.mediaTypeFilter |
1704 | @@ -80,7 +83,7 @@ | |||
1705 | 80 | id: photosOverview | 83 | id: photosOverview |
1706 | 81 | objectName: "photosPage" | 84 | objectName: "photosPage" |
1707 | 82 | 85 | ||
1709 | 83 | tools: pickTools | 86 | head.actions: pickActions |
1710 | 84 | 87 | ||
1711 | 85 | Image { | 88 | Image { |
1712 | 86 | anchors.fill: parent | 89 | anchors.fill: parent |
1713 | @@ -97,32 +100,24 @@ | |||
1714 | 97 | } | 100 | } |
1715 | 98 | } | 101 | } |
1716 | 99 | 102 | ||
1720 | 100 | property ToolbarItems pickTools: ToolbarItems { | 103 | property list<Action> pickActions: [ |
1721 | 101 | Button { | 104 | Action { |
1719 | 102 | anchors.verticalCenter: parent.verticalCenter | ||
1722 | 103 | text: i18n.tr("Pick") | 105 | text: i18n.tr("Pick") |
1723 | 104 | objectName: "pickButton" | 106 | objectName: "pickButton" |
1724 | 105 | color: Gallery.HIGHLIGHT_BUTTON_COLOR | ||
1725 | 106 | width: units.gu(16) | ||
1726 | 107 | enabled: pickerMainView.selection.selectedCount > 0 | 107 | enabled: pickerMainView.selection.selectedCount > 0 |
1728 | 108 | onClicked: { | 108 | iconName: "ok" |
1729 | 109 | onTriggered: { | ||
1730 | 109 | if (!enabled) | 110 | if (!enabled) |
1731 | 110 | return; | 111 | return; |
1732 | 111 | 112 | ||
1733 | 112 | APP.returnPickedContent(mediaLibrary.selectedMedias); | 113 | APP.returnPickedContent(mediaLibrary.selectedMedias); |
1734 | 113 | } | 114 | } |
1739 | 114 | } | 115 | }, |
1740 | 115 | 116 | Action { | |
1737 | 116 | back: Button { | ||
1738 | 117 | anchors.verticalCenter: parent.verticalCenter | ||
1741 | 118 | text: i18n.tr("Cancel") | 117 | text: i18n.tr("Cancel") |
1742 | 119 | objectName: "cancelButton" | 118 | objectName: "cancelButton" |
1747 | 120 | width: units.gu(10) | 119 | iconName: "close" |
1748 | 121 | onClicked: { | 120 | onTriggered: APP.contentPickingCanceled() |
1745 | 122 | APP.contentPickingCanceled() | ||
1746 | 123 | } | ||
1749 | 124 | } | 121 | } |
1753 | 125 | opened: true | 122 | ] |
1751 | 126 | locked: true | ||
1752 | 127 | } | ||
1754 | 128 | } | 123 | } |
1755 | 129 | 124 | ||
1756 | === modified file 'rc/qml/Utility/PhotosToolbarActions.qml' | |||
1757 | --- rc/qml/Utility/PhotosToolbarActions.qml 2014-03-19 20:19:57 +0000 | |||
1758 | +++ rc/qml/Utility/PhotosToolbarActions.qml 2014-09-03 23:54:36 +0000 | |||
1759 | @@ -29,23 +29,29 @@ | |||
1760 | 29 | signal startCamera() | 29 | signal startCamera() |
1761 | 30 | 30 | ||
1762 | 31 | ToolbarButton { | 31 | ToolbarButton { |
1768 | 32 | objectName: "selectButton" | 32 | action: Action { |
1769 | 33 | text: i18n.tr("Select") | 33 | objectName: "selectButton" |
1770 | 34 | iconSource: Qt.resolvedUrl("../../img/select.png") | 34 | text: i18n.tr("Select") |
1771 | 35 | enabled: root.selection !== null | 35 | iconSource: Qt.resolvedUrl("../../img/select.png") |
1772 | 36 | onTriggered: root.selection.inSelectionMode = true; | 36 | enabled: root.selection !== null |
1773 | 37 | onTriggered: root.selection.inSelectionMode = true; | ||
1774 | 38 | } | ||
1775 | 37 | } | 39 | } |
1776 | 38 | ToolbarButton { | 40 | ToolbarButton { |
1777 | 39 | objectName: "importButton" | 41 | objectName: "importButton" |
1781 | 40 | text: i18n.tr("Import") | 42 | action: Action { |
1782 | 41 | iconSource: Qt.resolvedUrl("../../img/import-image.png") | 43 | text: i18n.tr("Import") |
1783 | 42 | enabled: false | 44 | iconSource: Qt.resolvedUrl("../../img/import-image.png") |
1784 | 45 | visible: false | ||
1785 | 46 | } | ||
1786 | 43 | } | 47 | } |
1787 | 44 | ToolbarButton { | 48 | ToolbarButton { |
1793 | 45 | objectName: "cameraButton" | 49 | action: Action { |
1794 | 46 | text: i18n.tr("Camera") | 50 | objectName: "cameraButton" |
1795 | 47 | visible: !APP.desktopMode | 51 | text: i18n.tr("Camera") |
1796 | 48 | iconSource: Qt.resolvedUrl("../../img/camera.png") | 52 | visible: !APP.desktopMode |
1797 | 49 | onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version") | 53 | iconSource: Qt.resolvedUrl("../../img/camera.png") |
1798 | 54 | onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version") | ||
1799 | 55 | } | ||
1800 | 50 | } | 56 | } |
1801 | 51 | } | 57 | } |
1802 | 52 | 58 | ||
1803 | === modified file 'rc/qml/Utility/SelectionToolbarAction.qml' | |||
1804 | --- rc/qml/Utility/SelectionToolbarAction.qml 2013-09-19 14:53:09 +0000 | |||
1805 | +++ rc/qml/Utility/SelectionToolbarAction.qml 2014-09-03 23:54:36 +0000 | |||
1806 | @@ -33,6 +33,8 @@ | |||
1807 | 33 | signal addClicked(var caller) | 33 | signal addClicked(var caller) |
1808 | 34 | ///Emitted when delete was clicked | 34 | ///Emitted when delete was clicked |
1809 | 35 | signal deleteClicked() | 35 | signal deleteClicked() |
1810 | 36 | ///Emitted when share was clicked | ||
1811 | 37 | signal shareClicked() | ||
1812 | 36 | 38 | ||
1813 | 37 | // in selection mode, never hide the toolbar: | 39 | // in selection mode, never hide the toolbar: |
1814 | 38 | opened: true | 40 | opened: true |
1815 | @@ -41,32 +43,40 @@ | |||
1816 | 41 | ToolbarButton { | 43 | ToolbarButton { |
1817 | 42 | id: addButton | 44 | id: addButton |
1818 | 43 | objectName: "addButton" | 45 | objectName: "addButton" |
1836 | 44 | text: i18n.tr("Add") | 46 | action: Action { |
1837 | 45 | iconSource: Qt.resolvedUrl("../../img/add.png") | 47 | text: i18n.tr("Add") |
1838 | 46 | enabled: root.selection.selectedCount > 0 | 48 | iconName: "add" |
1839 | 47 | onTriggered: root.addClicked(addButton); | 49 | enabled: root.selection.selectedCount > 0 |
1840 | 48 | } | 50 | onTriggered: root.addClicked(addButton); |
1841 | 49 | ToolbarButton { | 51 | } |
1842 | 50 | objectName: "deleteButton" | 52 | } |
1843 | 51 | text: i18n.tr("Delete") | 53 | ToolbarButton { |
1844 | 52 | iconSource: Qt.resolvedUrl("../../img/delete.png") | 54 | action: Action { |
1845 | 53 | enabled: root.selection.selectedCount > 0 | 55 | objectName: "deleteButton" |
1846 | 54 | onTriggered:root.deleteClicked(); | 56 | text: i18n.tr("Delete") |
1847 | 55 | } | 57 | iconName: "delete" |
1848 | 56 | ToolbarButton { | 58 | enabled: root.selection.selectedCount > 0 |
1849 | 57 | objectName: "shareButton" | 59 | onTriggered:root.deleteClicked(); |
1850 | 58 | text: i18n.tr("Share") | 60 | } |
1851 | 59 | iconSource: Qt.resolvedUrl("../../img/share.png") | 61 | } |
1852 | 60 | enabled: false | 62 | ToolbarButton { |
1853 | 63 | action: Action { | ||
1854 | 64 | objectName: "shareButton" | ||
1855 | 65 | text: i18n.tr("Share") | ||
1856 | 66 | iconName: "share" | ||
1857 | 67 | enabled: root.selection.selectedCount > 0 | ||
1858 | 68 | onTriggered: root.shareClicked(); | ||
1859 | 69 | } | ||
1860 | 61 | } | 70 | } |
1861 | 62 | 71 | ||
1862 | 63 | back: Button { | 72 | back: Button { |
1863 | 64 | objectName: "cancelButton" | 73 | objectName: "cancelButton" |
1869 | 65 | anchors.verticalCenter: parent.verticalCenter | 74 | action: Action { |
1870 | 66 | text: i18n.tr("Cancel") | 75 | text: i18n.tr("Cancel") |
1871 | 67 | width: units.gu(10) | 76 | iconName: "back" |
1872 | 68 | onClicked: { | 77 | onTriggered: { |
1873 | 69 | root.cancelClicked(); | 78 | root.cancelClicked(); |
1874 | 79 | } | ||
1875 | 70 | } | 80 | } |
1876 | 71 | } | 81 | } |
1877 | 72 | } | 82 | } |
1878 | 73 | 83 | ||
1879 | === modified file 'tests/autopilot/gallery_app/emulators/album_view.py' | |||
1880 | --- tests/autopilot/gallery_app/emulators/album_view.py 2014-06-12 16:42:04 +0000 | |||
1881 | +++ tests/autopilot/gallery_app/emulators/album_view.py 2014-09-03 23:54:36 +0000 | |||
1882 | @@ -38,10 +38,6 @@ | |||
1883 | 38 | return self.app.wait_select_single("AlbumViewer", | 38 | return self.app.wait_select_single("AlbumViewer", |
1884 | 39 | objectName="albumViewer") | 39 | objectName="albumViewer") |
1885 | 40 | 40 | ||
1886 | 41 | def get_toolbar_add_button(self): | ||
1887 | 42 | """Returns the add button of the tollbar in the events view.""" | ||
1888 | 43 | return self.get_toolbar_named_toolbarbutton("addButton") | ||
1889 | 44 | |||
1890 | 45 | def get_first_photo(self): | 41 | def get_first_photo(self): |
1891 | 46 | """Returns the first photo in a newly opened album""" | 42 | """Returns the first photo in a newly opened album""" |
1892 | 47 | return self.app.select_many( | 43 | return self.app.select_many( |
1893 | @@ -103,14 +99,16 @@ | |||
1894 | 103 | matcher = LessThan | 99 | matcher = LessThan |
1895 | 104 | self.pointing_device.drag( | 100 | self.pointing_device.drag( |
1896 | 105 | mid_x, mid_y, # Start | 101 | mid_x, mid_y, # Start |
1898 | 106 | x + w, mid_y # Finish | 102 | x + w, mid_y, # Finish |
1899 | 103 | rate=3 | ||
1900 | 107 | ) | 104 | ) |
1901 | 108 | 105 | ||
1902 | 109 | elif 'right' == direction: | 106 | elif 'right' == direction: |
1903 | 110 | matcher = GreaterThan | 107 | matcher = GreaterThan |
1904 | 111 | self.pointing_device.drag( | 108 | self.pointing_device.drag( |
1905 | 112 | mid_x, mid_y, # Start | 109 | mid_x, mid_y, # Start |
1907 | 113 | x, mid_y # Finish | 110 | x, mid_y, # Finish |
1908 | 111 | rate=3 | ||
1909 | 114 | ) | 112 | ) |
1910 | 115 | else: | 113 | else: |
1911 | 116 | raise GalleryAppException( | 114 | raise GalleryAppException( |
1912 | 117 | 115 | ||
1913 | === modified file 'tests/autopilot/gallery_app/emulators/gallery_utils.py' | |||
1914 | --- tests/autopilot/gallery_app/emulators/gallery_utils.py 2014-06-13 13:57:20 +0000 | |||
1915 | +++ tests/autopilot/gallery_app/emulators/gallery_utils.py 2014-09-03 23:54:36 +0000 | |||
1916 | @@ -85,14 +85,14 @@ | |||
1917 | 85 | 85 | ||
1918 | 86 | def get_first_album(self): | 86 | def get_first_album(self): |
1919 | 87 | """Returns the first album in the albums view.""" | 87 | """Returns the first album in the albums view.""" |
1923 | 88 | # For some reasons the albums are returned in inverse order, so | 88 | return self.get_album_at(0) |
1921 | 89 | # the first album is acutally the last in the array | ||
1922 | 90 | return self.get_album_at(-1) | ||
1924 | 91 | 89 | ||
1925 | 92 | def get_album_at(self, position): | 90 | def get_album_at(self, position): |
1926 | 93 | """Returns the albums at this position in the albums view""" | 91 | """Returns the albums at this position in the albums view""" |
1927 | 94 | albums = self.select_many_retry("CheckerboardDelegate", | 92 | albums = self.select_many_retry("CheckerboardDelegate", |
1928 | 95 | objectName="checkerboardDelegate") | 93 | objectName="checkerboardDelegate") |
1929 | 94 | albums = sorted( | ||
1930 | 95 | albums, key=lambda album: (album.globalRect.y, album.globalRect.x)) | ||
1931 | 96 | return albums[position] | 96 | return albums[position] |
1932 | 97 | 97 | ||
1933 | 98 | def get_edit_album_button(self): | 98 | def get_edit_album_button(self): |
1934 | 99 | 99 | ||
1935 | === modified file 'tests/autopilot/gallery_app/emulators/main_screen.py' | |||
1936 | --- tests/autopilot/gallery_app/emulators/main_screen.py 2014-04-01 19:18:50 +0000 | |||
1937 | +++ tests/autopilot/gallery_app/emulators/main_screen.py 2014-09-03 23:54:36 +0000 | |||
1938 | @@ -5,17 +5,32 @@ | |||
1939 | 5 | # under the terms of the GNU General Public License version 3, as published | 5 | # under the terms of the GNU General Public License version 3, as published |
1940 | 6 | # by the Free Software Foundation. | 6 | # by the Free Software Foundation. |
1941 | 7 | 7 | ||
1947 | 8 | from ubuntuuitoolkit import emulators as toolkit_emulators | 8 | import ubuntuuitoolkit |
1948 | 9 | from gallery_app.emulators import toolbar | 9 | |
1949 | 10 | 10 | ||
1950 | 11 | 11 | class MainScreen(ubuntuuitoolkit.MainView): | |
1946 | 12 | class MainScreen(toolkit_emulators.MainView): | ||
1951 | 13 | """An emulator class that makes it easy to interact with the gallery app""" | 12 | """An emulator class that makes it easy to interact with the gallery app""" |
1952 | 14 | 13 | ||
1960 | 15 | def get_toolbar(self): | 14 | def get_header(self): |
1961 | 16 | """Return the Toolbar emulator of the MainView. | 15 | """Return the Header emulator of the MainView.""" |
1962 | 17 | 16 | return self.select_single(AppHeader, objectName='MainView_Header') | |
1963 | 18 | Overriden because the gallery app has custom buttons. | 17 | |
1964 | 19 | 18 | ||
1965 | 20 | """ | 19 | class AppHeader(ubuntuuitoolkit.Header): |
1966 | 21 | return self.select_single(toolbar.Toolbar) | 20 | """Header Autopilot helper. |
1967 | 21 | |||
1968 | 22 | We override this helper because on the gallery the gesture to show the | ||
1969 | 23 | header when it's hidden it's not the default. | ||
1970 | 24 | |||
1971 | 25 | """ | ||
1972 | 26 | |||
1973 | 27 | # XXX We are overriding internal methods that may change on the toolkit. | ||
1974 | 28 | # The helper on the toolkit needs a public method that will be safe to | ||
1975 | 29 | # override. Reported as bug http://pad.lv/1363591 --elopio - 2014-31-08 | ||
1976 | 30 | |||
1977 | 31 | def _is_visible(self): | ||
1978 | 32 | return self.visible | ||
1979 | 33 | |||
1980 | 34 | def _show(self): | ||
1981 | 35 | self.pointing_device.click_object(self._get_top_container()) | ||
1982 | 36 | self.visible.wait_for(True) | ||
1983 | 22 | 37 | ||
1984 | === modified file 'tests/autopilot/gallery_app/emulators/photo_viewer.py' | |||
1985 | --- tests/autopilot/gallery_app/emulators/photo_viewer.py 2014-08-27 20:28:51 +0000 | |||
1986 | +++ tests/autopilot/gallery_app/emulators/photo_viewer.py 2014-09-03 23:54:36 +0000 | |||
1987 | @@ -48,9 +48,8 @@ | |||
1988 | 48 | # Was using a list index (lp:1247711). Still needs fixing, I'm not | 48 | # Was using a list index (lp:1247711). Still needs fixing, I'm not |
1989 | 49 | # convinced this is a suitable way to select the correct item. | 49 | # convinced this is a suitable way to select the correct item. |
1990 | 50 | return self.app.wait_select_single( | 50 | return self.app.wait_select_single( |
1994 | 51 | "ZoomablePhotoComponent", | 51 | "SingleMediaViewer", |
1995 | 52 | ownerName="photoViewerDelegate", | 52 | objectName="openedMedia0" |
1993 | 53 | objectName="openedPhoto0" | ||
1996 | 54 | ) | 53 | ) |
1997 | 55 | 54 | ||
1998 | 56 | def get_photos_list(self): | 55 | def get_photos_list(self): |
1999 | @@ -94,8 +93,8 @@ | |||
2000 | 94 | 93 | ||
2001 | 95 | def get_opened_photo(self): | 94 | def get_opened_photo(self): |
2002 | 96 | """Returns the first opened photo.""" | 95 | """Returns the first opened photo.""" |
2005 | 97 | return self.app.wait_select_single("ZoomablePhotoComponent", | 96 | return self.app.wait_select_single("SingleMediaViewer", |
2006 | 98 | objectName="openedPhoto0") | 97 | objectName="openedMedia0") |
2007 | 99 | 98 | ||
2008 | 100 | def get_crop_interactor(self): | 99 | def get_crop_interactor(self): |
2009 | 101 | """Returns the crop interactor.""" | 100 | """Returns the crop interactor.""" |
2010 | 102 | 101 | ||
2011 | === modified file 'tests/autopilot/gallery_app/emulators/picker_screen.py' | |||
2012 | --- tests/autopilot/gallery_app/emulators/picker_screen.py 2014-07-10 09:07:34 +0000 | |||
2013 | +++ tests/autopilot/gallery_app/emulators/picker_screen.py 2014-09-03 23:54:36 +0000 | |||
2014 | @@ -11,7 +11,7 @@ | |||
2015 | 11 | class PickerScreen(toolkit_emulators.MainView): | 11 | class PickerScreen(toolkit_emulators.MainView): |
2016 | 12 | 12 | ||
2017 | 13 | def pick_button(self): | 13 | def pick_button(self): |
2019 | 14 | return self.select_single("Button", objectName="pickButton") | 14 | return self.select_single(objectName="pickButton_header_button") |
2020 | 15 | 15 | ||
2021 | 16 | def get_photos_tab_button(self): | 16 | def get_photos_tab_button(self): |
2022 | 17 | """Returns the photos tab.""" | 17 | """Returns the photos tab.""" |
2023 | @@ -38,7 +38,7 @@ | |||
2024 | 38 | Return the Page object representing the photos | 38 | Return the Page object representing the photos |
2025 | 39 | """ | 39 | """ |
2026 | 40 | self.switch_to_tab('photosTab') | 40 | self.switch_to_tab('photosTab') |
2028 | 41 | return self.select_single(Page10, objectName='photosPage') | 41 | return self.select_single(Page11, objectName='photosPage') |
2029 | 42 | 42 | ||
2030 | 43 | def click_pick_button(self): | 43 | def click_pick_button(self): |
2031 | 44 | """Click on the pick button""" | 44 | """Click on the pick button""" |
2032 | @@ -51,7 +51,7 @@ | |||
2033 | 51 | self.click_pick_button() | 51 | self.click_pick_button() |
2034 | 52 | 52 | ||
2035 | 53 | 53 | ||
2037 | 54 | class Page10(PickerScreen): | 54 | class Page11(PickerScreen): |
2038 | 55 | """Class to represent photos page view from picker screen""" | 55 | """Class to represent photos page view from picker screen""" |
2039 | 56 | 56 | ||
2040 | 57 | def _get_named_photo_element(self, photo_name): | 57 | def _get_named_photo_element(self, photo_name): |
2041 | 58 | 58 | ||
2042 | === modified file 'tests/autopilot/gallery_app/tests/__init__.py' | |||
2043 | --- tests/autopilot/gallery_app/tests/__init__.py 2014-07-14 15:29:11 +0000 | |||
2044 | +++ tests/autopilot/gallery_app/tests/__init__.py 2014-09-03 23:54:36 +0000 | |||
2045 | @@ -162,8 +162,11 @@ | |||
2046 | 162 | 162 | ||
2047 | 163 | """ This is needed to wait for the application to start. | 163 | """ This is needed to wait for the application to start. |
2048 | 164 | In the testfarm, the application may take some time to show up.""" | 164 | In the testfarm, the application may take some time to show up.""" |
2051 | 165 | self.assertThat(self.gallery_utils.get_qml_view().visible, | 165 | qml_view = self.gallery_utils.get_qml_view() |
2052 | 166 | Eventually(Equals(True))) | 166 | self.assertThat(qml_view.visible, Eventually(Equals(True))) |
2053 | 167 | loading_screen = qml_view.select_single( | ||
2054 | 168 | 'QQuickLoader', objectName='loadingScreen') | ||
2055 | 169 | loading_screen.visible.wait_for(False) | ||
2056 | 167 | """FIXME somehow on the server gallery sometimes is not fully started | 170 | """FIXME somehow on the server gallery sometimes is not fully started |
2057 | 168 | for switching to the albums view. Therefore this hack of sleeping""" | 171 | for switching to the albums view. Therefore this hack of sleeping""" |
2058 | 169 | sleep(2) | 172 | sleep(2) |
2059 | @@ -262,13 +265,11 @@ | |||
2060 | 262 | 265 | ||
2061 | 263 | def open_album_at(self, position): | 266 | def open_album_at(self, position): |
2062 | 264 | album = self.album_view.get_album_at(position) | 267 | album = self.album_view.get_album_at(position) |
2063 | 265 | # workaround lp:1247698 | ||
2064 | 266 | self.main_view.close_toolbar() | ||
2065 | 267 | self.click_item(album) | 268 | self.click_item(album) |
2066 | 268 | self.ensure_view_is_fully_open() | 269 | self.ensure_view_is_fully_open() |
2067 | 269 | 270 | ||
2068 | 270 | def open_first_album(self): | 271 | def open_first_album(self): |
2070 | 271 | self.open_album_at(-1) | 272 | self.open_album_at(0) |
2071 | 272 | 273 | ||
2072 | 273 | def ensure_view_is_fully_open(self): | 274 | def ensure_view_is_fully_open(self): |
2073 | 274 | view = self.album_view.get_album_view() | 275 | view = self.album_view.get_album_view() |
2074 | 275 | 276 | ||
2075 | === modified file 'tests/autopilot/gallery_app/tests/test_album_editor.py' | |||
2076 | --- tests/autopilot/gallery_app/tests/test_album_editor.py 2014-06-10 19:00:23 +0000 | |||
2077 | +++ tests/autopilot/gallery_app/tests/test_album_editor.py 2014-09-03 23:54:36 +0000 | |||
2078 | @@ -33,13 +33,10 @@ | |||
2079 | 33 | self.ARGS = [] | 33 | self.ARGS = [] |
2080 | 34 | super(TestAlbumEditor, self).setUp() | 34 | super(TestAlbumEditor, self).setUp() |
2081 | 35 | self.switch_to_albums_tab() | 35 | self.switch_to_albums_tab() |
2082 | 36 | self.main_view.close_toolbar() | ||
2083 | 37 | self.edit_first_album() | 36 | self.edit_first_album() |
2084 | 38 | 37 | ||
2085 | 39 | def edit_first_album(self): | 38 | def edit_first_album(self): |
2086 | 40 | first_album = self.gallery_utils.get_first_album() | 39 | first_album = self.gallery_utils.get_first_album() |
2087 | 41 | # workaround lp:1247698 | ||
2088 | 42 | self.main_view.close_toolbar() | ||
2089 | 43 | self.tap_item(first_album) | 40 | self.tap_item(first_album) |
2090 | 44 | edit_button = self.gallery_utils.get_edit_album_button() | 41 | edit_button = self.gallery_utils.get_edit_album_button() |
2091 | 45 | self.click_item(edit_button) | 42 | self.click_item(edit_button) |
2092 | @@ -58,8 +55,7 @@ | |||
2093 | 58 | text = "Ubuntu" | 55 | text = "Ubuntu" |
2094 | 59 | self.assertThat(subtitle_field.text, Eventually(Equals(text))) | 56 | self.assertThat(subtitle_field.text, Eventually(Equals(text))) |
2095 | 60 | 57 | ||
2098 | 61 | # workaround lp:1247698 | 58 | sleep(5) |
2097 | 62 | self.main_view.close_toolbar() | ||
2099 | 63 | editor.click_title_field() | 59 | editor.click_title_field() |
2100 | 64 | self.assertThat(title_field.activeFocus, Eventually(Equals(True))) | 60 | self.assertThat(title_field.activeFocus, Eventually(Equals(True))) |
2101 | 65 | self.keyboard.press_and_release("Ctrl+a") | 61 | self.keyboard.press_and_release("Ctrl+a") |
2102 | @@ -81,38 +77,41 @@ | |||
2103 | 81 | """Tests adding a photo using the media selector""" | 77 | """Tests adding a photo using the media selector""" |
2104 | 82 | # first open, but cancel before adding a photo | 78 | # first open, but cancel before adding a photo |
2105 | 83 | editor = self.app.select_single(album_editor.AlbumEditor) | 79 | editor = self.app.select_single(album_editor.AlbumEditor) |
2106 | 84 | # workaround lp:1247698 | ||
2107 | 85 | self.main_view.close_toolbar() | ||
2108 | 86 | editor.add_photos() | 80 | editor.add_photos() |
2109 | 87 | self.media_selector.ensure_fully_open() | 81 | self.media_selector.ensure_fully_open() |
2110 | 88 | 82 | ||
2111 | 89 | sleep(5) | 83 | sleep(5) |
2113 | 90 | self.main_view.get_toolbar().click_custom_button("cancelButton") | 84 | self.main_view.get_header().click_custom_back_button() |
2114 | 85 | |||
2115 | 91 | editor.ensure_fully_closed() | 86 | editor.ensure_fully_closed() |
2116 | 92 | 87 | ||
2118 | 93 | self.main_view.close_toolbar() | 88 | sleep(5) |
2119 | 94 | self.open_first_album() | 89 | self.open_first_album() |
2120 | 95 | num_photos_start = self.album_view.number_of_photos() | 90 | num_photos_start = self.album_view.number_of_photos() |
2121 | 96 | self.assertThat(num_photos_start, Equals(1)) | 91 | self.assertThat(num_photos_start, Equals(1)) |
2123 | 97 | self.main_view.open_toolbar().click_button("backButton") | 92 | |
2124 | 93 | # should click away of any photo to toggle header | ||
2125 | 94 | photo = self.album_view.get_first_photo() | ||
2126 | 95 | x, y, w, h = photo.globalRect | ||
2127 | 96 | self.pointing_device.move(x + 40 , y + h + 40) | ||
2128 | 97 | self.pointing_device.click() | ||
2129 | 98 | |||
2130 | 99 | self.main_view.get_header().click_custom_back_button() | ||
2131 | 98 | self.album_view.ensure_album_view_fully_closed() | 100 | self.album_view.ensure_album_view_fully_closed() |
2132 | 99 | 101 | ||
2133 | 100 | # now open to add a photo | 102 | # now open to add a photo |
2134 | 101 | self.main_view.close_toolbar() | ||
2135 | 102 | self.edit_first_album() | 103 | self.edit_first_album() |
2136 | 103 | editor = self.app.select_single(album_editor.AlbumEditor) | 104 | editor = self.app.select_single(album_editor.AlbumEditor) |
2137 | 104 | # workaround lp:1247698 | ||
2138 | 105 | self.main_view.close_toolbar() | ||
2139 | 106 | editor.add_photos() | 105 | editor.add_photos() |
2140 | 107 | self.media_selector.ensure_fully_open() | 106 | self.media_selector.ensure_fully_open() |
2141 | 108 | 107 | ||
2142 | 109 | photo = self.media_selector.get_second_photo() | 108 | photo = self.media_selector.get_second_photo() |
2143 | 110 | self.click_item(photo) | 109 | self.click_item(photo) |
2145 | 111 | self.main_view.get_toolbar().click_custom_button("addButton") | 110 | self.main_view.get_header().click_action_button("addButton") |
2146 | 112 | editor = self.app.select_single(album_editor.AlbumEditor) | 111 | editor = self.app.select_single(album_editor.AlbumEditor) |
2147 | 113 | editor.ensure_fully_closed() | 112 | editor.ensure_fully_closed() |
2148 | 114 | 113 | ||
2150 | 115 | self.main_view.close_toolbar() | 114 | self.album_view.ensure_album_view_fully_closed() |
2151 | 116 | self.open_first_album() | 115 | self.open_first_album() |
2152 | 117 | num_photos = self.album_view.number_of_photos() | 116 | num_photos = self.album_view.number_of_photos() |
2153 | 118 | self.assertThat(num_photos, Equals(num_photos_start + 1)) | 117 | self.assertThat(num_photos, Equals(num_photos_start + 1)) |
2154 | @@ -124,11 +123,8 @@ | |||
2155 | 124 | self.assertThat( | 123 | self.assertThat( |
2156 | 125 | cover_image.source.endswith("album-cover-default-large.png"), | 124 | cover_image.source.endswith("album-cover-default-large.png"), |
2157 | 126 | Equals(True)) | 125 | Equals(True)) |
2158 | 127 | self.main_view.close_toolbar() | ||
2159 | 128 | 126 | ||
2160 | 129 | # click somewhere rather at the bottom of the cover | 127 | # click somewhere rather at the bottom of the cover |
2161 | 130 | # workaround lp:1247698 | ||
2162 | 131 | self.main_view.close_toolbar() | ||
2163 | 132 | x, y, w, h = cover_image.globalRect | 128 | x, y, w, h = cover_image.globalRect |
2164 | 133 | self.pointing_device.move(x + int(w / 2), y + h - int(h / 10)) | 129 | self.pointing_device.move(x + int(w / 2), y + h - int(h / 10)) |
2165 | 134 | self.pointing_device.click() | 130 | self.pointing_device.click() |
2166 | 135 | 131 | ||
2167 | === modified file 'tests/autopilot/gallery_app/tests/test_album_view.py' | |||
2168 | --- tests/autopilot/gallery_app/tests/test_album_view.py 2014-06-12 16:42:04 +0000 | |||
2169 | +++ tests/autopilot/gallery_app/tests/test_album_view.py 2014-09-03 23:54:36 +0000 | |||
2170 | @@ -48,24 +48,17 @@ | |||
2171 | 48 | self.switch_to_albums_tab() | 48 | self.switch_to_albums_tab() |
2172 | 49 | 49 | ||
2173 | 50 | def test_album_view_open_photo(self): | 50 | def test_album_view_open_photo(self): |
2174 | 51 | self.main_view.close_toolbar() | ||
2175 | 52 | self.open_first_album() | 51 | self.open_first_album() |
2176 | 53 | self.main_view.close_toolbar() | ||
2177 | 54 | photo = self.album_view.get_first_photo() | 52 | photo = self.album_view.get_first_photo() |
2178 | 55 | # workaround lp:1247698 | ||
2179 | 56 | self.main_view.close_toolbar() | ||
2180 | 57 | self.click_item(photo) | 53 | self.click_item(photo) |
2181 | 58 | sleep(5) | 54 | sleep(5) |
2182 | 59 | photo_view = self.main_view.wait_select_single("PopupPhotoViewer") | 55 | photo_view = self.main_view.wait_select_single("PopupPhotoViewer") |
2183 | 60 | self.assertThat(photo_view.visible, Eventually(Equals(True))) | 56 | self.assertThat(photo_view.visible, Eventually(Equals(True))) |
2184 | 61 | 57 | ||
2185 | 62 | def test_album_view_flipping(self): | 58 | def test_album_view_flipping(self): |
2186 | 63 | self.main_view.close_toolbar() | ||
2187 | 64 | |||
2188 | 65 | # For some reason here the album at position 0 in the autopilot list is | 59 | # For some reason here the album at position 0 in the autopilot list is |
2189 | 66 | # actually the second album, they seem to be returned in reverse order. | 60 | # actually the second album, they seem to be returned in reverse order. |
2192 | 67 | self.open_album_at(0) | 61 | self.open_album_at(1) |
2191 | 68 | self.main_view.close_toolbar() | ||
2193 | 69 | 62 | ||
2194 | 70 | spread = self.album_view.get_spread_view() | 63 | spread = self.album_view.get_spread_view() |
2195 | 71 | 64 | ||
2196 | @@ -84,35 +77,39 @@ | |||
2197 | 84 | self.assertThat(spread.viewingPage, Eventually(GreaterThan(1))) | 77 | self.assertThat(spread.viewingPage, Eventually(GreaterThan(1))) |
2198 | 85 | 78 | ||
2199 | 86 | def test_add_photo(self): | 79 | def test_add_photo(self): |
2200 | 87 | self.main_view.close_toolbar() | ||
2201 | 88 | self.open_first_album() | 80 | self.open_first_album() |
2202 | 89 | num_photos_start = self.album_view.number_of_photos() | 81 | num_photos_start = self.album_view.number_of_photos() |
2203 | 90 | self.assertThat(num_photos_start, Equals(1)) | 82 | self.assertThat(num_photos_start, Equals(1)) |
2204 | 91 | 83 | ||
2205 | 84 | # should click away of any photo to toggle header | ||
2206 | 85 | photo = self.album_view.get_first_photo() | ||
2207 | 86 | x, y, w, h = photo.globalRect | ||
2208 | 87 | self.pointing_device.move(x + 40 , y + h + 40) | ||
2209 | 88 | self.pointing_device.click() | ||
2210 | 89 | |||
2211 | 92 | # open media selector but cancel | 90 | # open media selector but cancel |
2213 | 93 | self.main_view.open_toolbar().click_button("addButton") | 91 | self.main_view.get_header().click_action_button("addButton") |
2214 | 94 | self.media_selector.ensure_fully_open() | 92 | self.media_selector.ensure_fully_open() |
2215 | 95 | 93 | ||
2217 | 96 | self.main_view.get_toolbar().click_custom_button("cancelButton") | 94 | self.main_view.get_header().click_custom_back_button() |
2218 | 97 | sleep(1) | 95 | sleep(1) |
2219 | 98 | 96 | ||
2220 | 99 | num_photos = self.album_view.number_of_photos() | 97 | num_photos = self.album_view.number_of_photos() |
2221 | 100 | self.assertThat(num_photos, Equals(num_photos_start)) | 98 | self.assertThat(num_photos, Equals(num_photos_start)) |
2222 | 101 | 99 | ||
2223 | 102 | # open media selector and add a photo | 100 | # open media selector and add a photo |
2225 | 103 | self.main_view.open_toolbar().click_button("addButton") | 101 | self.main_view.get_header().click_action_button("addButton") |
2226 | 104 | self.media_selector.ensure_fully_open() | 102 | self.media_selector.ensure_fully_open() |
2227 | 105 | 103 | ||
2228 | 106 | photo = self.media_selector.get_second_photo() | 104 | photo = self.media_selector.get_second_photo() |
2229 | 107 | self.click_item(photo) | 105 | self.click_item(photo) |
2231 | 108 | self.main_view.get_toolbar().click_custom_button("addButton") | 106 | self.main_view.get_header().click_action_button("addButton") |
2232 | 109 | 107 | ||
2233 | 110 | self.assertThat( | 108 | self.assertThat( |
2234 | 111 | lambda: self.album_view.number_of_photos(), | 109 | lambda: self.album_view.number_of_photos(), |
2235 | 112 | Eventually(Equals(num_photos_start + 1))) | 110 | Eventually(Equals(num_photos_start + 1))) |
2236 | 113 | 111 | ||
2237 | 114 | def test_remove_photo_from_album(self): | 112 | def test_remove_photo_from_album(self): |
2238 | 115 | self.main_view.close_toolbar() | ||
2239 | 116 | self.open_first_album() | 113 | self.open_first_album() |
2240 | 117 | num_photos_start = self.album_view.number_of_photos() | 114 | num_photos_start = self.album_view.number_of_photos() |
2241 | 118 | self.assertThat(num_photos_start, Equals(1)) | 115 | self.assertThat(num_photos_start, Equals(1)) |
2242 | @@ -125,7 +122,7 @@ | |||
2243 | 125 | photo_view = self.album_view.get_album_photo_view() | 122 | photo_view = self.album_view.get_album_photo_view() |
2244 | 126 | self.assertThat(photo_view.visible, Eventually(Equals(True))) | 123 | self.assertThat(photo_view.visible, Eventually(Equals(True))) |
2245 | 127 | 124 | ||
2247 | 128 | self.main_view.open_toolbar().click_button("deleteButton") | 125 | self.main_view.get_header().click_action_button("deleteButton") |
2248 | 129 | self.album_view.click_remove_from_album_remove_button() | 126 | self.album_view.click_remove_from_album_remove_button() |
2249 | 130 | 127 | ||
2250 | 131 | self.assertThat(lambda: self.album_view.number_of_photos(), | 128 | self.assertThat(lambda: self.album_view.number_of_photos(), |
2251 | @@ -135,7 +132,6 @@ | |||
2252 | 135 | Eventually(Equals(True))) | 132 | Eventually(Equals(True))) |
2253 | 136 | 133 | ||
2254 | 137 | def test_remove_photo_from_album_and_delete(self): | 134 | def test_remove_photo_from_album_and_delete(self): |
2255 | 138 | self.main_view.close_toolbar() | ||
2256 | 139 | self.open_first_album() | 135 | self.open_first_album() |
2257 | 140 | num_photos_start = self.album_view.number_of_photos() | 136 | num_photos_start = self.album_view.number_of_photos() |
2258 | 141 | self.assertThat(num_photos_start, Equals(1)) | 137 | self.assertThat(num_photos_start, Equals(1)) |
2259 | @@ -148,7 +144,7 @@ | |||
2260 | 148 | photo_view = self.album_view.get_album_photo_view() | 144 | photo_view = self.album_view.get_album_photo_view() |
2261 | 149 | self.assertThat(photo_view.visible, Eventually(Equals(True))) | 145 | self.assertThat(photo_view.visible, Eventually(Equals(True))) |
2262 | 150 | 146 | ||
2264 | 151 | self.main_view.open_toolbar().click_button("deleteButton") | 147 | self.main_view.get_header().click_action_button("deleteButton") |
2265 | 152 | self.album_view.click_remove_from_album_delete_button() | 148 | self.album_view.click_remove_from_album_delete_button() |
2266 | 153 | 149 | ||
2267 | 154 | self.assertThat(lambda: self.album_view.number_of_photos(), | 150 | self.assertThat(lambda: self.album_view.number_of_photos(), |
2268 | @@ -158,7 +154,6 @@ | |||
2269 | 158 | Eventually(Equals(False))) | 154 | Eventually(Equals(False))) |
2270 | 159 | 155 | ||
2271 | 160 | def test_cancel_remove_photo_from_album(self): | 156 | def test_cancel_remove_photo_from_album(self): |
2272 | 161 | self.main_view.close_toolbar() | ||
2273 | 162 | self.open_first_album() | 157 | self.open_first_album() |
2274 | 163 | num_photos_start = self.album_view.number_of_photos() | 158 | num_photos_start = self.album_view.number_of_photos() |
2275 | 164 | self.assertThat(num_photos_start, Equals(1)) | 159 | self.assertThat(num_photos_start, Equals(1)) |
2276 | @@ -171,10 +166,10 @@ | |||
2277 | 171 | photo_view = self.album_view.get_album_photo_view() | 166 | photo_view = self.album_view.get_album_photo_view() |
2278 | 172 | self.assertThat(photo_view.visible, Eventually(Equals(True))) | 167 | self.assertThat(photo_view.visible, Eventually(Equals(True))) |
2279 | 173 | 168 | ||
2281 | 174 | self.main_view.open_toolbar().click_button("deleteButton") | 169 | self.main_view.get_header().click_action_button("deleteButton") |
2282 | 175 | self.album_view.click_remove_from_album_cancel_button() | 170 | self.album_view.click_remove_from_album_cancel_button() |
2283 | 176 | 171 | ||
2285 | 177 | self.main_view.open_toolbar().click_button("backButton") | 172 | self.main_view.get_header().click_custom_back_button() |
2286 | 178 | 173 | ||
2287 | 179 | self.assertThat(lambda: self.album_view.number_of_photos(), | 174 | self.assertThat(lambda: self.album_view.number_of_photos(), |
2288 | 180 | Eventually(Equals(num_photos_start))) | 175 | Eventually(Equals(num_photos_start))) |
2289 | @@ -183,28 +178,24 @@ | |||
2290 | 183 | Eventually(Equals(True))) | 178 | Eventually(Equals(True))) |
2291 | 184 | 179 | ||
2292 | 185 | def test_add_photo_to_new_album(self): | 180 | def test_add_photo_to_new_album(self): |
2294 | 186 | self.main_view.open_toolbar().click_button("addButton") | 181 | self.main_view.get_header().click_action_button("addButton") |
2295 | 187 | self.ui_update() | 182 | self.ui_update() |
2296 | 188 | 183 | ||
2297 | 189 | editor = self.app.select_single(album_editor.AlbumEditor) | 184 | editor = self.app.select_single(album_editor.AlbumEditor) |
2298 | 190 | editor.ensure_fully_open() | 185 | editor.ensure_fully_open() |
2299 | 191 | self.main_view.close_toolbar() | ||
2300 | 192 | editor.close() | 186 | editor.close() |
2301 | 193 | 187 | ||
2302 | 194 | self.open_first_album() | 188 | self.open_first_album() |
2303 | 195 | self.main_view.close_toolbar() | ||
2304 | 196 | num_photos_start = self.album_view.number_of_photos() | 189 | num_photos_start = self.album_view.number_of_photos() |
2305 | 197 | self.assertThat(num_photos_start, Equals(0)) | 190 | self.assertThat(num_photos_start, Equals(0)) |
2306 | 198 | 191 | ||
2307 | 199 | plus = self.album_view.get_plus_icon_empty_album() | 192 | plus = self.album_view.get_plus_icon_empty_album() |
2308 | 200 | # workaround lp:1247698 | ||
2309 | 201 | self.main_view.close_toolbar() | ||
2310 | 202 | self.click_item(plus) | 193 | self.click_item(plus) |
2311 | 203 | self.media_selector.ensure_fully_open() | 194 | self.media_selector.ensure_fully_open() |
2312 | 204 | 195 | ||
2313 | 205 | photo = self.media_selector.get_second_photo() | 196 | photo = self.media_selector.get_second_photo() |
2314 | 206 | self.click_item(photo) | 197 | self.click_item(photo) |
2316 | 207 | self.main_view.get_toolbar().click_custom_button("addButton") | 198 | self.main_view.get_header().click_action_button("addButton") |
2317 | 208 | 199 | ||
2318 | 209 | self.assertThat( | 200 | self.assertThat( |
2319 | 210 | lambda: self.album_view.number_of_photos(), | 201 | lambda: self.album_view.number_of_photos(), |
2320 | 211 | 202 | ||
2321 | === modified file 'tests/autopilot/gallery_app/tests/test_albums_view.py' | |||
2322 | --- tests/autopilot/gallery_app/tests/test_albums_view.py 2014-05-20 15:19:35 +0000 | |||
2323 | +++ tests/autopilot/gallery_app/tests/test_albums_view.py 2014-09-03 23:54:36 +0000 | |||
2324 | @@ -11,6 +11,7 @@ | |||
2325 | 11 | from testtools.matchers import Equals | 11 | from testtools.matchers import Equals |
2326 | 12 | from autopilot.matchers import Eventually | 12 | from autopilot.matchers import Eventually |
2327 | 13 | from autopilot.platform import model | 13 | from autopilot.platform import model |
2328 | 14 | from autopilot.introspection.dbus import StateNotFoundError | ||
2329 | 14 | 15 | ||
2330 | 15 | from gallery_app.tests import GalleryTestCase | 16 | from gallery_app.tests import GalleryTestCase |
2331 | 16 | from gallery_app.emulators.albums_view import AlbumsView | 17 | from gallery_app.emulators.albums_view import AlbumsView |
2332 | @@ -47,10 +48,19 @@ | |||
2333 | 47 | 48 | ||
2334 | 48 | super(TestAlbumsView, self).tearDown() | 49 | super(TestAlbumsView, self).tearDown() |
2335 | 49 | 50 | ||
2336 | 51 | def check_header_button_exist(self, button): | ||
2337 | 52 | header = self.main_view.get_header() | ||
2338 | 53 | buttonName = button + "_header_button" | ||
2339 | 54 | try: | ||
2340 | 55 | header.select_single(objectName=buttonName) | ||
2341 | 56 | except StateNotFoundError: | ||
2342 | 57 | return False | ||
2343 | 58 | return True | ||
2344 | 59 | |||
2345 | 50 | def test_add_album(self): | 60 | def test_add_album(self): |
2346 | 51 | """Add one album, and checks if the number of albums went up by one""" | 61 | """Add one album, and checks if the number of albums went up by one""" |
2347 | 52 | albums = self.albums_view.number_of_albums_in_albums_view() | 62 | albums = self.albums_view.number_of_albums_in_albums_view() |
2349 | 53 | self.main_view.open_toolbar().click_button("addButton") | 63 | self.main_view.get_header().click_action_button("addButton") |
2350 | 54 | self.assertThat( | 64 | self.assertThat( |
2351 | 55 | lambda: self.albums_view.number_of_albums_in_albums_view(), | 65 | lambda: self.albums_view.number_of_albums_in_albums_view(), |
2352 | 56 | Eventually(Equals(albums+1)) | 66 | Eventually(Equals(albums+1)) |
2353 | @@ -61,10 +71,10 @@ | |||
2354 | 61 | not change | 71 | not change |
2355 | 62 | """ | 72 | """ |
2356 | 63 | albums = self.albums_view.number_of_albums_in_albums_view() | 73 | albums = self.albums_view.number_of_albums_in_albums_view() |
2358 | 64 | self.main_view.open_toolbar().click_button("addButton") | 74 | self.main_view.get_header().click_action_button("addButton") |
2359 | 65 | editor = self.app.select_single(album_editor.AlbumEditor) | 75 | editor = self.app.select_single(album_editor.AlbumEditor) |
2360 | 66 | editor.ensure_fully_open() | 76 | editor.ensure_fully_open() |
2362 | 67 | self.main_view.get_toolbar().click_custom_button("cancelButton") | 77 | self.main_view.get_header().click_custom_back_button() |
2363 | 68 | self.assertThat( | 78 | self.assertThat( |
2364 | 69 | lambda: self.albums_view.number_of_albums_in_albums_view(), | 79 | lambda: self.albums_view.number_of_albums_in_albums_view(), |
2365 | 70 | Eventually(Equals(albums)) | 80 | Eventually(Equals(albums)) |
2366 | @@ -72,13 +82,8 @@ | |||
2367 | 72 | 82 | ||
2368 | 73 | # Check if Camera Button is not visible at Desktop mode | 83 | # Check if Camera Button is not visible at Desktop mode |
2369 | 74 | def test_camera_button_visible(self): | 84 | def test_camera_button_visible(self): |
2376 | 75 | self.main_view.open_toolbar() | 85 | cameraButtonVisible = self.check_header_button_exist("cameraButton") |
2371 | 76 | toolbar = self.main_view.get_toolbar() | ||
2372 | 77 | cameraButton = toolbar.select_single( | ||
2373 | 78 | "ActionItem", | ||
2374 | 79 | objectName="cameraButton" | ||
2375 | 80 | ) | ||
2377 | 81 | if model() == "Desktop": | 86 | if model() == "Desktop": |
2379 | 82 | self.assertThat(cameraButton.visible, Equals(False)) | 87 | self.assertThat(cameraButtonVisible, Equals(False)) |
2380 | 83 | else: | 88 | else: |
2382 | 84 | self.assertThat(cameraButton.visible, Equals(True)) | 89 | self.assertThat(cameraButtonVisible, Equals(True)) |
2383 | 85 | 90 | ||
2384 | === modified file 'tests/autopilot/gallery_app/tests/test_events_view.py' | |||
2385 | --- tests/autopilot/gallery_app/tests/test_events_view.py 2014-06-16 13:46:21 +0000 | |||
2386 | +++ tests/autopilot/gallery_app/tests/test_events_view.py 2014-09-03 23:54:36 +0000 | |||
2387 | @@ -11,6 +11,7 @@ | |||
2388 | 11 | from testtools.matchers import Equals, NotEquals, Is, GreaterThan | 11 | from testtools.matchers import Equals, NotEquals, Is, GreaterThan |
2389 | 12 | from autopilot.matchers import Eventually | 12 | from autopilot.matchers import Eventually |
2390 | 13 | from autopilot.platform import model | 13 | from autopilot.platform import model |
2391 | 14 | from autopilot.introspection.dbus import StateNotFoundError | ||
2392 | 14 | 15 | ||
2393 | 15 | from gallery_app.tests import GalleryTestCase | 16 | from gallery_app.tests import GalleryTestCase |
2394 | 16 | from gallery_app.emulators.events_view import EventsView | 17 | from gallery_app.emulators.events_view import EventsView |
2395 | @@ -59,7 +60,16 @@ | |||
2396 | 59 | objectName="organicEventView") | 60 | objectName="organicEventView") |
2397 | 60 | 61 | ||
2398 | 61 | def enable_select_mode(self): | 62 | def enable_select_mode(self): |
2400 | 62 | self.main_view.open_toolbar().click_button("selectButton") | 63 | self.main_view.get_header().click_action_button("selectButton") |
2401 | 64 | |||
2402 | 65 | def check_header_button_exist(self, button): | ||
2403 | 66 | header = self.main_view.get_header() | ||
2404 | 67 | buttonName = button + "_header_button" | ||
2405 | 68 | try: | ||
2406 | 69 | header.select_single(objectName=buttonName) | ||
2407 | 70 | except StateNotFoundError: | ||
2408 | 71 | return False | ||
2409 | 72 | return True | ||
2410 | 63 | 73 | ||
2411 | 64 | def test_select_button_cancel(self): | 74 | def test_select_button_cancel(self): |
2412 | 65 | """Clicking the cancel button after clicking the select button must | 75 | """Clicking the cancel button after clicking the select button must |
2413 | @@ -70,10 +80,8 @@ | |||
2414 | 70 | self.enable_select_mode() | 80 | self.enable_select_mode() |
2415 | 71 | self.assertTrue(events_view.inSelectionMode) | 81 | self.assertTrue(events_view.inSelectionMode) |
2416 | 72 | 82 | ||
2418 | 73 | self.main_view.get_toolbar().click_custom_button("cancelButton") | 83 | self.main_view.get_header().click_custom_back_button() |
2419 | 74 | 84 | ||
2420 | 75 | toolbar = self.main_view.get_toolbar() | ||
2421 | 76 | self.assertThat(toolbar.opened, Eventually(Equals(False))) | ||
2422 | 77 | self.assertFalse(events_view.inSelectionMode) | 85 | self.assertFalse(events_view.inSelectionMode) |
2423 | 78 | 86 | ||
2424 | 79 | def test_delete_a_photo(self): | 87 | def test_delete_a_photo(self): |
2425 | @@ -83,7 +91,7 @@ | |||
2426 | 83 | 91 | ||
2427 | 84 | self.enable_select_mode() | 92 | self.enable_select_mode() |
2428 | 85 | self.events_view.click_photo(self.sample_file) | 93 | self.events_view.click_photo(self.sample_file) |
2430 | 86 | self.main_view.open_toolbar().click_button("deleteButton") | 94 | self.main_view.get_header().click_action_button("deleteButton") |
2431 | 87 | self.assertThat(self.gallery_utils.delete_dialog_shown, | 95 | self.assertThat(self.gallery_utils.delete_dialog_shown, |
2432 | 88 | Eventually(Is(True))) | 96 | Eventually(Is(True))) |
2433 | 89 | 97 | ||
2434 | @@ -94,7 +102,7 @@ | |||
2435 | 94 | self.assertThat(lambda: exists(self.sample_file), | 102 | self.assertThat(lambda: exists(self.sample_file), |
2436 | 95 | Eventually(Equals(True))) | 103 | Eventually(Equals(True))) |
2437 | 96 | 104 | ||
2439 | 97 | self.main_view.open_toolbar().click_button("deleteButton") | 105 | self.main_view.get_header().click_action_button("deleteButton") |
2440 | 98 | self.assertThat(self.gallery_utils.delete_dialog_shown, | 106 | self.assertThat(self.gallery_utils.delete_dialog_shown, |
2441 | 99 | Eventually(Is(True))) | 107 | Eventually(Is(True))) |
2442 | 100 | 108 | ||
2443 | @@ -123,13 +131,8 @@ | |||
2444 | 123 | 131 | ||
2445 | 124 | # Check if Camera Button is not visible at Desktop mode | 132 | # Check if Camera Button is not visible at Desktop mode |
2446 | 125 | def test_camera_button_visible(self): | 133 | def test_camera_button_visible(self): |
2453 | 126 | self.main_view.open_toolbar() | 134 | cameraButtonVisible = self.check_header_button_exist("cameraButton") |
2448 | 127 | toolbar = self.main_view.get_toolbar() | ||
2449 | 128 | cameraButton = toolbar.select_single( | ||
2450 | 129 | "ActionItem", | ||
2451 | 130 | objectName="cameraButton" | ||
2452 | 131 | ) | ||
2454 | 132 | if model() == "Desktop": | 135 | if model() == "Desktop": |
2456 | 133 | self.assertThat(cameraButton.visible, Equals(False)) | 136 | self.assertThat(cameraButtonVisible, Equals(False)) |
2457 | 134 | else: | 137 | else: |
2459 | 135 | self.assertThat(cameraButton.visible, Equals(True)) | 138 | self.assertThat(cameraButtonVisible, Equals(True)) |
2460 | 136 | 139 | ||
2461 | === modified file 'tests/autopilot/gallery_app/tests/test_photo_viewer.py' | |||
2462 | --- tests/autopilot/gallery_app/tests/test_photo_viewer.py 2014-07-02 22:11:12 +0000 | |||
2463 | +++ tests/autopilot/gallery_app/tests/test_photo_viewer.py 2014-09-03 23:54:36 +0000 | |||
2464 | @@ -41,7 +41,8 @@ | |||
2465 | 41 | super(TestPhotoViewerBase, self).setUp() | 41 | super(TestPhotoViewerBase, self).setUp() |
2466 | 42 | self.main_view.switch_to_tab("eventsTab") | 42 | self.main_view.switch_to_tab("eventsTab") |
2467 | 43 | self.open_first_photo() | 43 | self.open_first_photo() |
2469 | 44 | self.main_view.open_toolbar() | 44 | # Need to click on the photo to toggle header |
2470 | 45 | self.pointing_device.click() | ||
2471 | 45 | 46 | ||
2472 | 46 | def open_first_photo(self): | 47 | def open_first_photo(self): |
2473 | 47 | self.assertThat( | 48 | self.assertThat( |
2474 | @@ -49,10 +50,6 @@ | |||
2475 | 49 | Eventually(GreaterThan(0)) | 50 | Eventually(GreaterThan(0)) |
2476 | 50 | ) | 51 | ) |
2477 | 51 | 52 | ||
2478 | 52 | # workaround lp:1247698 | ||
2479 | 53 | # toolbar needs to be gone to click on an image. | ||
2480 | 54 | self.main_view.close_toolbar() | ||
2481 | 55 | |||
2482 | 56 | self.events_view.click_photo(self.sample_file) | 53 | self.events_view.click_photo(self.sample_file) |
2483 | 57 | 54 | ||
2484 | 58 | photo_viewer_loader = self.photo_viewer.get_main_photo_viewer_loader() | 55 | photo_viewer_loader = self.photo_viewer.get_main_photo_viewer_loader() |
2485 | @@ -107,7 +104,7 @@ | |||
2486 | 107 | 104 | ||
2487 | 108 | def test_nav_bar_back_button(self): | 105 | def test_nav_bar_back_button(self): |
2488 | 109 | """Clicking the back button must close the photo.""" | 106 | """Clicking the back button must close the photo.""" |
2490 | 110 | self.main_view.open_toolbar().click_button("backButton") | 107 | self.main_view.get_header().click_custom_back_button() |
2491 | 111 | photo_viewer = self.photo_viewer.get_main_photo_viewer() | 108 | photo_viewer = self.photo_viewer.get_main_photo_viewer() |
2492 | 112 | self.assertThat(photo_viewer.visible, Eventually(Equals(False))) | 109 | self.assertThat(photo_viewer.visible, Eventually(Equals(False))) |
2493 | 113 | 110 | ||
2494 | @@ -115,7 +112,7 @@ | |||
2495 | 115 | def test_share_button(self): | 112 | def test_share_button(self): |
2496 | 116 | """Clicking the share button must show the ContentPeerPicker.""" | 113 | """Clicking the share button must show the ContentPeerPicker.""" |
2497 | 117 | photo_viewer = self.photo_viewer.get_main_photo_viewer() | 114 | photo_viewer = self.photo_viewer.get_main_photo_viewer() |
2499 | 118 | self.main_view.open_toolbar().click_button("shareButton") | 115 | self.main_view.get_header().click_action_button("shareButton") |
2500 | 119 | share_picker = self.photo_viewer.get_share_peer_picker() | 116 | share_picker = self.photo_viewer.get_share_peer_picker() |
2501 | 120 | self.assertThat(share_picker.visible, Eventually(Equals(True))) | 117 | self.assertThat(share_picker.visible, Eventually(Equals(True))) |
2502 | 121 | cancel_button = self.photo_viewer.get_content_peer_picker_cancel_button() | 118 | cancel_button = self.photo_viewer.get_content_peer_picker_cancel_button() |
2503 | @@ -123,7 +120,7 @@ | |||
2504 | 123 | self.assertThat(share_picker.visible, Eventually(Equals(False))) | 120 | self.assertThat(share_picker.visible, Eventually(Equals(False))) |
2505 | 124 | 121 | ||
2506 | 125 | def delete_one_picture(self): | 122 | def delete_one_picture(self): |
2508 | 126 | self.main_view.open_toolbar().click_button("deleteButton") | 123 | self.main_view.get_header().click_action_button("deleteButton") |
2509 | 127 | self.get_delete_dialog() | 124 | self.get_delete_dialog() |
2510 | 128 | delete_item = self.photo_viewer.get_delete_popover_delete_item() | 125 | delete_item = self.photo_viewer.get_delete_popover_delete_item() |
2511 | 129 | self.click_item(delete_item) | 126 | self.click_item(delete_item) |
2512 | @@ -131,7 +128,7 @@ | |||
2513 | 131 | 128 | ||
2514 | 132 | def test_photo_delete_works(self): | 129 | def test_photo_delete_works(self): |
2515 | 133 | """Clicking the trash button must show the delete dialog.""" | 130 | """Clicking the trash button must show the delete dialog.""" |
2517 | 134 | self.main_view.open_toolbar().click_button("deleteButton") | 131 | self.main_view.get_header().click_action_button("deleteButton") |
2518 | 135 | self.get_delete_dialog() | 132 | self.get_delete_dialog() |
2519 | 136 | 133 | ||
2520 | 137 | photo_viewer = self.photo_viewer.get_main_photo_viewer() | 134 | photo_viewer = self.photo_viewer.get_main_photo_viewer() |
2521 | @@ -157,7 +154,7 @@ | |||
2522 | 157 | 154 | ||
2523 | 158 | def test_nav_bar_album_picker_button(self): | 155 | def test_nav_bar_album_picker_button(self): |
2524 | 159 | """Clicking the album picker must show the picker dialog.""" | 156 | """Clicking the album picker must show the picker dialog.""" |
2526 | 160 | self.main_view.open_toolbar().click_button("addButton") | 157 | self.main_view.get_header().click_action_button("addButton") |
2527 | 161 | album_picker = self.photo_viewer.get_popup_album_picker() | 158 | album_picker = self.photo_viewer.get_popup_album_picker() |
2528 | 162 | self.assertThat(album_picker.visible, Eventually(Equals(True))) | 159 | self.assertThat(album_picker.visible, Eventually(Equals(True))) |
2529 | 163 | 160 | ||
2530 | @@ -169,19 +166,11 @@ | |||
2531 | 169 | self.pointing_device.click() | 166 | self.pointing_device.click() |
2532 | 170 | self.pointing_device.click() | 167 | self.pointing_device.click() |
2533 | 171 | 168 | ||
2534 | 172 | self.assertThat( | ||
2535 | 173 | opened_photo.isZoomAnimationInProgress, | ||
2536 | 174 | Eventually(Equals(False)) | ||
2537 | 175 | ) | ||
2538 | 176 | self.assertThat(opened_photo.fullyZoomed, Eventually(Equals(True))) | 169 | self.assertThat(opened_photo.fullyZoomed, Eventually(Equals(True))) |
2539 | 177 | 170 | ||
2540 | 178 | self.pointing_device.click() | 171 | self.pointing_device.click() |
2541 | 179 | self.pointing_device.click() | 172 | self.pointing_device.click() |
2542 | 180 | 173 | ||
2543 | 181 | self.assertThat( | ||
2544 | 182 | opened_photo.isZoomAnimationInProgress, | ||
2545 | 183 | Eventually(Equals(False)) | ||
2546 | 184 | ) | ||
2547 | 185 | self.assertThat(opened_photo.fullyUnzoomed, Eventually(Equals(True))) | 174 | self.assertThat(opened_photo.fullyUnzoomed, Eventually(Equals(True))) |
2548 | 186 | 175 | ||
2549 | 187 | def test_swipe_change_image(self): | 176 | def test_swipe_change_image(self): |
2550 | @@ -219,7 +208,7 @@ | |||
2551 | 219 | self.media_view = self.app.select_single(MediaViewer) | 208 | self.media_view = self.app.select_single(MediaViewer) |
2552 | 220 | 209 | ||
2553 | 221 | def click_edit_button(self): | 210 | def click_edit_button(self): |
2555 | 222 | self.main_view.open_toolbar().click_button("editButton") | 211 | self.main_view.get_header().click_action_button("editButton") |
2556 | 223 | edit_dialog = self.photo_viewer.get_photo_edit_dialog() | 212 | edit_dialog = self.photo_viewer.get_photo_edit_dialog() |
2557 | 224 | self.assertThat(edit_dialog.visible, (Eventually(Equals(True)))) | 213 | self.assertThat(edit_dialog.visible, (Eventually(Equals(True)))) |
2558 | 225 | self.assertThat(edit_dialog.opacity, (Eventually(Equals(1)))) | 214 | self.assertThat(edit_dialog.opacity, (Eventually(Equals(1)))) |
2559 | @@ -281,7 +270,6 @@ | |||
2560 | 281 | self.assertThat(lambda: is_landscape(), | 270 | self.assertThat(lambda: is_landscape(), |
2561 | 282 | Eventually(Equals(False))) | 271 | Eventually(Equals(False))) |
2562 | 283 | 272 | ||
2563 | 284 | self.main_view.open_toolbar() | ||
2564 | 285 | self.click_edit_button() | 273 | self.click_edit_button() |
2565 | 286 | self.photo_viewer.click_undo_item() | 274 | self.photo_viewer.click_undo_item() |
2566 | 287 | self.media_view.ensure_spinner_not_running() | 275 | self.media_view.ensure_spinner_not_running() |
2567 | @@ -291,7 +279,6 @@ | |||
2568 | 291 | self.assertThat(lambda: is_landscape(), | 279 | self.assertThat(lambda: is_landscape(), |
2569 | 292 | Eventually(Equals(True))) | 280 | Eventually(Equals(True))) |
2570 | 293 | 281 | ||
2571 | 294 | self.main_view.open_toolbar() | ||
2572 | 295 | self.click_edit_button() | 282 | self.click_edit_button() |
2573 | 296 | self.photo_viewer.click_redo_item() | 283 | self.photo_viewer.click_redo_item() |
2574 | 297 | self.media_view.ensure_spinner_not_running() | 284 | self.media_view.ensure_spinner_not_running() |
2575 | @@ -301,10 +288,8 @@ | |||
2576 | 301 | is_landscape = opened_photo.paintedWidth > opened_photo.paintedHeight | 288 | is_landscape = opened_photo.paintedWidth > opened_photo.paintedHeight |
2577 | 302 | self.assertThat(is_landscape, Equals(False)) | 289 | self.assertThat(is_landscape, Equals(False)) |
2578 | 303 | 290 | ||
2579 | 304 | self.main_view.open_toolbar() | ||
2580 | 305 | self.click_edit_button() | 291 | self.click_edit_button() |
2581 | 306 | self.photo_viewer.click_rotate_item() | 292 | self.photo_viewer.click_rotate_item() |
2582 | 307 | self.main_view.open_toolbar() | ||
2583 | 308 | self.click_edit_button() | 293 | self.click_edit_button() |
2584 | 309 | self.photo_viewer.click_revert_item() | 294 | self.photo_viewer.click_revert_item() |
2585 | 310 | 295 | ||
2586 | 311 | 296 | ||
2587 | === modified file 'tests/autopilot/gallery_app/tests/test_photos_view.py' | |||
2588 | --- tests/autopilot/gallery_app/tests/test_photos_view.py 2014-05-20 20:59:52 +0000 | |||
2589 | +++ tests/autopilot/gallery_app/tests/test_photos_view.py 2014-09-03 23:54:36 +0000 | |||
2590 | @@ -12,6 +12,7 @@ | |||
2591 | 12 | from testtools import skipUnless | 12 | from testtools import skipUnless |
2592 | 13 | from autopilot.matchers import Eventually | 13 | from autopilot.matchers import Eventually |
2593 | 14 | from autopilot.platform import model | 14 | from autopilot.platform import model |
2594 | 15 | from autopilot.introspection.dbus import StateNotFoundError | ||
2595 | 15 | 16 | ||
2596 | 16 | from gallery_app.tests import GalleryTestCase | 17 | from gallery_app.tests import GalleryTestCase |
2597 | 17 | from gallery_app.emulators.photos_view import PhotosView | 18 | from gallery_app.emulators.photos_view import PhotosView |
2598 | @@ -56,8 +57,16 @@ | |||
2599 | 56 | photo = self.photos_view.get_first_photo_in_photos_view() | 57 | photo = self.photos_view.get_first_photo_in_photos_view() |
2600 | 57 | self.click_item(photo) | 58 | self.click_item(photo) |
2601 | 58 | 59 | ||
2602 | 60 | def check_header_button_exist(self, button): | ||
2603 | 61 | header = self.main_view.get_header() | ||
2604 | 62 | buttonName = button + "_header_button" | ||
2605 | 63 | try: | ||
2606 | 64 | header.select_single(objectName=buttonName) | ||
2607 | 65 | except StateNotFoundError: | ||
2608 | 66 | return False | ||
2609 | 67 | return True | ||
2610 | 68 | |||
2611 | 59 | def test_open_photo(self): | 69 | def test_open_photo(self): |
2612 | 60 | self.main_view.close_toolbar() | ||
2613 | 61 | self.click_first_photo() | 70 | self.click_first_photo() |
2614 | 62 | sleep(5) | 71 | sleep(5) |
2615 | 63 | photo_viewer = self.photos_view.get_main_photo_viewer() | 72 | photo_viewer = self.photos_view.get_main_photo_viewer() |
2616 | @@ -69,13 +78,11 @@ | |||
2617 | 69 | photos_overview = self.app.select_single("PhotosOverview") | 78 | photos_overview = self.app.select_single("PhotosOverview") |
2618 | 70 | self.assertFalse(photos_overview.inSelectionMode) | 79 | self.assertFalse(photos_overview.inSelectionMode) |
2619 | 71 | 80 | ||
2621 | 72 | self.main_view.open_toolbar().click_button("selectButton") | 81 | self.main_view.get_header().click_action_button("selectButton") |
2622 | 73 | self.assertTrue(photos_overview.inSelectionMode) | 82 | self.assertTrue(photos_overview.inSelectionMode) |
2623 | 74 | 83 | ||
2625 | 75 | self.main_view.open_toolbar().click_custom_button("cancelButton") | 84 | self.main_view.get_header().click_custom_back_button() |
2626 | 76 | 85 | ||
2627 | 77 | toolbar = self.main_view.get_toolbar() | ||
2628 | 78 | self.assertThat(toolbar.opened, Eventually(Equals(False))) | ||
2629 | 79 | self.assertFalse(photos_overview.inSelectionMode) | 86 | self.assertFalse(photos_overview.inSelectionMode) |
2630 | 80 | 87 | ||
2631 | 81 | first_photo = self.photos_view.get_first_photo_in_photos_view() | 88 | first_photo = self.photos_view.get_first_photo_in_photos_view() |
2632 | @@ -84,9 +91,9 @@ | |||
2633 | 84 | 91 | ||
2634 | 85 | def test_delete_photo_dialog_appears(self): | 92 | def test_delete_photo_dialog_appears(self): |
2635 | 86 | """Selecting a photo must make the delete button clickable.""" | 93 | """Selecting a photo must make the delete button clickable.""" |
2637 | 87 | self.main_view.open_toolbar().click_button("selectButton") | 94 | self.main_view.get_header().click_action_button("selectButton") |
2638 | 88 | self.click_first_photo() | 95 | self.click_first_photo() |
2640 | 89 | self.main_view.open_toolbar().click_button("deleteButton") | 96 | self.main_view.get_header().click_action_button("deleteButton") |
2641 | 90 | 97 | ||
2642 | 91 | self.assertThat(self.gallery_utils.delete_dialog_shown, | 98 | self.assertThat(self.gallery_utils.delete_dialog_shown, |
2643 | 92 | Eventually(Is(True))) | 99 | Eventually(Is(True))) |
2644 | @@ -99,15 +106,13 @@ | |||
2645 | 99 | def test_delete_a_photo(self): | 106 | def test_delete_a_photo(self): |
2646 | 100 | """Must be able to select a photo and use the dialog to delete it.""" | 107 | """Must be able to select a photo and use the dialog to delete it.""" |
2647 | 101 | number_of_photos = self.photos_view.number_of_photos() | 108 | number_of_photos = self.photos_view.number_of_photos() |
2649 | 102 | self.main_view.open_toolbar().click_button("selectButton") | 109 | self.main_view.get_header().click_action_button("selectButton") |
2650 | 103 | self.click_first_photo() | 110 | self.click_first_photo() |
2652 | 104 | self.main_view.open_toolbar().click_button("deleteButton") | 111 | self.main_view.get_header().click_action_button("deleteButton") |
2653 | 105 | 112 | ||
2654 | 106 | self.assertThat(self.gallery_utils.delete_dialog_shown, | 113 | self.assertThat(self.gallery_utils.delete_dialog_shown, |
2655 | 107 | Eventually(Is(True))) | 114 | Eventually(Is(True))) |
2656 | 108 | 115 | ||
2657 | 109 | self.main_view.open_toolbar().click_button("deleteButton") | ||
2658 | 110 | |||
2659 | 111 | delete_item = self.photos_view.get_delete_dialog_delete_button() | 116 | delete_item = self.photos_view.get_delete_dialog_delete_button() |
2660 | 112 | self.click_item(delete_item) | 117 | self.click_item(delete_item) |
2661 | 113 | self.assertThat( | 118 | self.assertThat( |
2662 | @@ -157,13 +162,8 @@ | |||
2663 | 157 | 162 | ||
2664 | 158 | # Check if Camera Button is not visible at Desktop mode | 163 | # Check if Camera Button is not visible at Desktop mode |
2665 | 159 | def test_camera_button_visible(self): | 164 | def test_camera_button_visible(self): |
2672 | 160 | self.main_view.open_toolbar() | 165 | cameraButtonVisible = self.check_header_button_exist("cameraButton") |
2667 | 161 | toolbar = self.main_view.get_toolbar() | ||
2668 | 162 | cameraButton = toolbar.select_single( | ||
2669 | 163 | "ActionItem", | ||
2670 | 164 | objectName="cameraButton" | ||
2671 | 165 | ) | ||
2673 | 166 | if model() == "Desktop": | 166 | if model() == "Desktop": |
2675 | 167 | self.assertThat(cameraButton.visible, Equals(False)) | 167 | self.assertThat(cameraButtonVisible, Equals(False)) |
2676 | 168 | else: | 168 | else: |
2678 | 169 | self.assertThat(cameraButton.visible, Equals(True)) | 169 | self.assertThat(cameraButtonVisible, Equals(True)) |
FAILED: Continuous integration, rev:1076 jenkins. qa.ubuntu. com/job/ gallery- app-ci/ 981/ jenkins. qa.ubuntu. com/job/ gallery- app-utopic- amd64-ci/ 156 jenkins. qa.ubuntu. com/job/ gallery- app-utopic- armhf-ci/ 156 jenkins. qa.ubuntu. com/job/ gallery- app-utopic- armhf-ci/ 156/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ gallery- app-utopic- i386-ci/ 156 jenkins. qa.ubuntu. com/job/ generic- click-autopilot -utopic- touch/332 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 3304 jenkins. qa.ubuntu. com/job/ generic- click-autopilot -runner- mako/473 jenkins. qa.ubuntu. com/job/ generic- click-builder- utopic- armhf/528 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 12586 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 2712 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/3598 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/3598/ artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/gallery- app-ci/ 981/rebuild
http://