[Merge] lp:~artmello/gallery-app/gallery-app-new_header into lp:gallery-app

Ugo Riboni ugo.riboni at canonical.com
Wed Aug 27 15:03:38 UTC 2014


Review: Needs Fixing

I added some inline comments for things to check and fix. 
Other than that testing the branch on a device does not bring up any major problems.

Diff comments:

> === modified file 'rc/qml/AlbumEditor/AlbumEditor.qml'
> --- rc/qml/AlbumEditor/AlbumEditor.qml	2014-06-10 00:13:50 +0000
> +++ rc/qml/AlbumEditor/AlbumEditor.qml	2014-08-27 03:28:24 +0000
> @@ -20,7 +20,7 @@
>  
>  import QtQuick 2.0
>  import Gallery 1.0
> -import Ubuntu.Components 0.1
> +import Ubuntu.Components 1.1
>  import "../../js/GalleryUtility.js" as GalleryUtility
>  import "../../js/GraphicsRoutines.js" as GraphicsRoutines
>  import "../AlbumViewer"
> @@ -33,17 +33,14 @@
>      objectName: "mainAlbumEditor"
>  
>      title: "Edit album"
> -    tools: ToolbarItems {
> -        back: Button {
> -            objectName: "cancelButton"
> -            anchors.verticalCenter: parent.verticalCenter
> -            text: i18n.tr("Cancel")
> -            width: units.gu(10)
> -            onClicked: {
> -                if(album.newAlbum)
> -                    albumModel.destroyAlbum(album);
> -                albumEditor.closeRequested(albumEditor.album, false);
> -            }
> +    head.backAction: Action {
> +        objectName: "cancelButton"
> +        text: i18n.tr("Cancel")
> +        iconName: "back"
> +        onTriggered: {
> +            if(album.newAlbum)
> +                albumModel.destroyAlbum(album);
> +            albumEditor.closeRequested(albumEditor.album, false);
>          }
>      }
>  
> 
> === modified file 'rc/qml/AlbumViewer/AlbumViewer.qml'
> --- rc/qml/AlbumViewer/AlbumViewer.qml	2014-06-18 17:43:41 +0000
> +++ rc/qml/AlbumViewer/AlbumViewer.qml	2014-08-27 03:28:24 +0000
> @@ -19,7 +19,7 @@
>   */
>  
>  import QtQuick 2.0
> -import Ubuntu.Components 0.1
> +import Ubuntu.Components 1.1
>  import Gallery 1.0
>  import "../../js/Gallery.js" as Gallery
>  import "../../js/GalleryUtility.js" as GalleryUtility
> @@ -74,10 +74,6 @@
>  
>      onVisibleChanged: {
>          if (visible) reopenPicture();
> -
> -        if (albumViewer.header) {
> -            albumViewer.header.visible = !visible;
> -        }
>      }
>  
>      onCloseRequested: {
> @@ -135,6 +131,11 @@
>          overview.pushPage(component_mediaSelector);
>      }
>  
> +    function toggleHeaderVisibility()
> +    {
> +        header.visible = !header.visible;
> +    }
> +
>      AlbumSpreadViewer {
>          id: albumSpreadViewer
>          objectName: "spreadViewer"
> @@ -188,8 +189,10 @@
>                  if (hit.objectName === "addButton")
>                      showMediaSelector();
>  
> -                if (!hit.mediaSource)
> +                if (!hit.mediaSource) {
> +                    albumViewer.toggleHeaderVisibility();
>                      return;
> +                }
>  
>                  albumViewer.mediaCurrentlyInView = hit.mediaSource.path;
>                  photoViewerLoader.fadeOpen(hit.mediaSource);
> @@ -302,6 +305,7 @@
>  
>              onOpened: {
>                  overview.pushPage(target);
> +                header.visible = false;
>              }
>              onCloseRequested: {
>                  albumViewer.mediaCurrentlyInView = "";
> @@ -353,36 +357,35 @@
>      }
>  
>      /// Contains the actions for the toolbar in the album view
> -    tools: ToolbarItems {
> -        ToolbarButton {
> +    head.actions: [
> +        Action {
>              objectName: "addButton"
> -            action: Action {
> -                text: i18n.tr("Add to album") // text in HUD
> -                iconSource: Qt.resolvedUrl("../../img/add.png")
> -                onTriggered: {
> -                    showMediaSelector();
> -                }
> -            }
> -            text: i18n.tr("Add") // text in toolbar
> -        }
> -        ToolbarButton {
> -            id: deleteButton
> +            text: i18n.tr("Add to album") // text in HUD
> +            iconName: "add"
> +            onTriggered: showMediaSelector();
> +        },
> +        Action {
>              objectName: "deleteButton"
>              text: i18n.tr("Delete")
> -            iconSource: Qt.resolvedUrl("../../img/delete.png")
> -            onTriggered: {
> -                albumTrashDialog.album = album
> -                albumTrashDialog.caller = deleteButton
> -                albumTrashDialog.show()
> -            }
> -        }
> -        back: ToolbarButton {
> -            text: i18n.tr("Back")
> -            objectName: "backButton"
> -            iconSource: Qt.resolvedUrl("../../img/back.png")
> -            onTriggered: {
> -                __close()
> -            }
> -        }
> +            iconName: "delete"
> +            onTriggered: {
> +                albumTrashDialog.album = album;
> +                albumTrashDialog.show();
> +            }
> +        }
> +    ]
> +
> +    head.backAction: Action {
> +        iconName: "back"
> +        onTriggered: __close();
> +    }
> +
> +    Rectangle {
> +        id: headerBackground
> +
> +        width: parent.width
> +        height: header.height
> +
> +        visible: header.visible
>      }
>  }
> 
> === modified file 'rc/qml/AlbumsOverview.qml'
> --- rc/qml/AlbumsOverview.qml	2014-06-10 16:56:56 +0000
> +++ rc/qml/AlbumsOverview.qml	2014-08-27 03:28:24 +0000
> @@ -169,10 +169,9 @@
>          root.visible = false;
>  
>          if (albumViewer.origin) {
> -            if (header.visible)
> -                header.visible = false;
>              albumViewer.visible = true;
>              overview.pushPage(albumViewer);
> +            header.visible = false;
>          }
>          else
>              albumViewer.visible = true
> @@ -221,10 +220,10 @@
>      tools: ToolbarItems {
>          id: albumOverviewTools
>          ToolbarButton {
> -            objectName: "addButton"
>              action: Action {
> +                objectName: "addButton"
>                  text: i18n.tr("Add new album") // Text in HUD
> -                iconSource: Qt.resolvedUrl("../img/add.png")
> +                iconName: "add"
>                  onTriggered: {
>                      var album = albumCollectionModel.createOrphan();
>                      albumCollectionModel.addOrphan(album);
> @@ -239,9 +238,9 @@
>          }
>          ToolbarButton {
>              objectName: "cameraButton"
> -            visible: !APP.desktopMode
>              action: Action {
>                  text: i18n.tr("Camera")
> +                visible: !APP.desktopMode
>                  iconSource: Qt.resolvedUrl("../img/camera.png")
>                  onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version")
>              }
> 
> === modified file 'rc/qml/Components/MediaSelector.qml'
> --- rc/qml/Components/MediaSelector.qml	2014-05-23 08:24:38 +0000
> +++ rc/qml/Components/MediaSelector.qml	2014-08-27 03:28:24 +0000
> @@ -16,7 +16,7 @@
>  
>  import QtQuick 2.0
>  import Gallery 1.0
> -import Ubuntu.Components 0.1
> +import Ubuntu.Components 1.1
>  import "../../js/Gallery.js" as Gallery
>  import "../OrganicView"
>  import "../Utility"
> @@ -74,31 +74,26 @@
>          selection: mediaSelector.selection
>      }
>  
> -    tools: ToolbarItems {
> -        Button {
> -            anchors.verticalCenter: parent.verticalCenter
> +    head.actions: [
> +        Action {
> +            objectName: "addButton"
>              text: i18n.tr("Add to Album")
> -            objectName: "addButton"
> -            color: Gallery.HIGHLIGHT_BUTTON_COLOR
> -            width: units.gu(16)
> +            iconName: "add"
>              enabled: mediaSelector.selection.selectedCount
>              onTriggered: {
>                  mediaSelector.addClicked();
>                  mediaSelector.hide();
>              }
>          }
> +    ]
>  
> -        back: Button {
> -            anchors.verticalCenter: parent.verticalCenter
> -            text: i18n.tr("Cancel")
> -            objectName: "cancelButton"
> -            width: units.gu(10)
> -            onClicked: {
> -                mediaSelector.hide();
> -            }
> +    head.backAction: Action {
> +        objectName: "cancelButton"
> +        text: i18n.tr("Cancel")
> +        iconName: "back"
> +        onTriggered: {
> +            mediaSelector.hide();
>          }
> -        opened: true
> -        locked: true
>      }
>  
>      PropertyAnimation {
> 
> === modified file 'rc/qml/EventsOverview.qml'
> --- rc/qml/EventsOverview.qml	2014-03-10 17:20:03 +0000
> +++ rc/qml/EventsOverview.qml	2014-08-27 03:28:24 +0000
> @@ -94,7 +94,7 @@
>          }
>          onAddClicked: {
>              __albumPicker = PopupUtils.open(Qt.resolvedUrl("Components/PopupAlbumPicker.qml"),
> -                                            caller,
> +                                            null,
>                                              {contentHeight: organicEventView.__pickerContentHeight});
>          }
>          onDeleteClicked: {
> 
> === modified file 'rc/qml/GalleryApplication.qml'
> --- rc/qml/GalleryApplication.qml	2014-08-14 21:53:31 +0000
> +++ rc/qml/GalleryApplication.qml	2014-08-27 03:28:24 +0000
> @@ -201,9 +201,7 @@
>          source: allLoaded ? ((APP.pickModeEnabled) ? Qt.resolvedUrl("PickerScreen.qml") :
>                                                       Qt.resolvedUrl("MainScreen.qml")) : ""
>          visible: status === Loader.Ready
> -	// FIXME: this causes https://bugs.launchpad.net/bugs/1356841 
> -	// even though it fixes the spinner loading animation, comment out for now
> -        //asynchronous: true
> +        asynchronous: true

Are you sure it's safe to uncomment this ? Shouldn't it be done in another separate MR as it's not part of enabling the new header anyway ?

>      }
>  
>      Component.onCompleted: {
> 
> === modified file 'rc/qml/MainScreen.qml'
> --- rc/qml/MainScreen.qml	2014-06-10 18:54:21 +0000
> +++ rc/qml/MainScreen.qml	2014-08-27 03:28:24 +0000
> @@ -31,6 +31,8 @@
>      id: overview
>      objectName: "overview"
>  
> +    useDeprecatedToolbar: false

if you use components 1.1 this should be the default. I would update the version and remove this property setting.

> +
>      anchors.fill: parent
>      applicationName: "gallery-app"
>      automaticOrientation: application.automaticOrientation
> 
> === modified file 'rc/qml/MediaViewer/GalleryPhotoComponent.qml'
> --- rc/qml/MediaViewer/GalleryPhotoComponent.qml	2014-08-11 20:34:23 +0000
> +++ rc/qml/MediaViewer/GalleryPhotoComponent.qml	2014-08-27 03:28:24 +0000
> @@ -108,10 +108,8 @@
>          //           prevent this segfault & crash from occurring.
>          visible: isLoaded;
>  
> -        sourceSize: {
> -            width: width
> -            height: height
> -        }
> +        sourceSize.width: width
> +        sourceSize.height: height
>  
>          // use cache: !isAnimate setting for flicker-free animations and reflows
>          asynchronous: !isAnimate
> 
> === modified file 'rc/qml/MediaViewer/MediaViewer.qml'
> --- rc/qml/MediaViewer/MediaViewer.qml	2014-07-04 11:29:31 +0000
> +++ rc/qml/MediaViewer/MediaViewer.qml	2014-08-27 03:28:24 +0000
> @@ -20,7 +20,7 @@
>  
>  import QtQuick 2.0
>  import Gallery 1.0
> -import Ubuntu.Components 0.1
> +import Ubuntu.Components 1.1
>  import Ubuntu.Components.Popups 0.1
>  import Ubuntu.Components.ListItems 0.1 as ListItem
>  import Ubuntu.Content 0.1
> @@ -60,13 +60,14 @@
>      //
>      // Since there is no current item if there are no more photo objects left in the model,
>      // the check catches this before we can inadvertently follow a stale pointer.
> -    property bool isReady: model != null && model.count > 0 &&
> -                           (galleryPhotoViewer.currentItem ? galleryPhotoViewer.currentItem.isLoaded : false)
> +    property bool isReady: model != null && model.count > 0 && galleryPhotoViewer.currentItem
>  
>      // tooolbar actions for the full view
> -    property Item tools: (media && !sharePicker.visible) ? (media.type === MediaSource.Photo ?
> -                                      d.photoToolbar : d.videoToolbar)
> -                               : null
> +    property variant actions: (media && !sharePicker.visible) ? (media.type === MediaSource.Photo ?
> +                                      d.photoActions : d.videoActions)
> +                               : []
> +
> +    property variant backAction: d.backAction
>  
>      /*!
>      */
> @@ -113,6 +114,16 @@
>          galleryPhotoViewer.currentItem.togglePlayPause();
>      }
>  
> +    function setHeaderVisibility(visible)
> +    {
> +        header.visible = visible;    
> +    }
> +
> +    function toggleHeaderVisibility()
> +    {
> +        setHeaderVisibility(!header.visible);    
> +    }
> +
>      Rectangle{
>          color: "black"
>          anchors.fill: parent
> @@ -152,37 +163,18 @@
>                  media = model.getAt(currentIndex);
>          }
>  
> -        delegate: Item {
> -            /// Is true while the media content is loaded
> -            property bool isLoaded: delegateView.item.isLoaded
> -            /// Is true when the view is in a state, where the user possibly
> -            /// interacts with the media (and not swipe to another media)
> -            property bool userInteracting: delegateView.item.state === "zoomed"
> -            /// Needed as ListView.isCurrentItem can't be used directly
> -            property bool isActive: ListView.isCurrentItem
> -            /// True if a video is currently played
> -            property bool isPlayingVideo: galleryPhotoViewer.currentItem ?
> -                                              galleryPhotoViewer.currentItem.state === "playing"
> -                                            : false
> -
> -            // set the view to it's original state
> -            function reset() {
> -                delegateView.item.reset();
> -            }
> -            /// Toggles between play and pause - only usful when a video is shown
> -            function togglePlayPause() {
> -                if (model.mediaSource.type === MediaSource.Video)
> -                    delegateView.item.togglePlayPause();
> -            }
> -
> -            onIsActiveChanged: {
> -                if (!isActive)
> -                    reset()
> -            }
> +        delegate: SingleMediaViewer {
> +            id: media
> +            mediaFileURL: model.mediaSource.path
> +            mediaFileType: model.mediaSource.type
> +            maxDimension: Math.max(galleryPhotoViewer.width, galleryPhotoViewer.height)
>  
>              width: galleryPhotoViewer.width
>              height: galleryPhotoViewer.height
> -            state: delegateView.item.state
> +
> +            // Needed as ListView.isCurrentItem can't be used directly in a change handler
> +            property bool isActive: ListView.isCurrentItem
> +            onIsActiveChanged: if (!isActive) reset();
>  
>              opacity: {
>                  if (!galleryPhotoViewer.moving || galleryPhotoViewer.contentX < 0
> @@ -192,26 +184,12 @@
>                  return 1.0 - Math.abs((galleryPhotoViewer.contentX - x) / width);
>              }
>  
> -            Component {
> -                id: component_delegatePhotoView
> -                PhotoViewerDelegate {
> -                    useInteractivePreview: false
> -                    mediaSource: model.mediaSource
> -                }
> -            }
> -            Component {
> -                id: component_delegateVideoView
> -                VideoViewerDelegate {
> -                    mediaSource: model.mediaSource
> -                }
> -            }
> -            Loader {
> -                id: delegateView
> -                anchors.fill: parent
> -                sourceComponent: model.mediaSource.type === MediaSource.Photo ?
> -                                     component_delegatePhotoView : component_delegateVideoView
> -            }
> -
> +            onClicked: viewerWrapper.toggleHeaderVisibility()
> +            
> +            Connections {
> +                target: model.mediaSource
> +                onDataChanged: media.reload()
> +            }
>          }
>  
>          // Don't allow flicking while the chrome is actively displaying a popup
> @@ -233,6 +211,8 @@
>              anchors.fill: parent
>              visible: false
>  
> +            onVisibleChanged: viewerWrapper.setHeaderVisibility(!visible)
> +
>              ContentPeerPicker {
>                  objectName: "sharePicker"
>                  anchors.fill: parent
> @@ -488,123 +468,95 @@
>      Item {
>          id: d
>  
> -        property Item photoToolbar: ToolbarItems {
> -            ToolbarButton {
> -                id: photoEditButton
> +        property list<Action> photoActions: [
> +            Action {
>                  objectName: "editButton"
> -                action: Action {
> -                    text: i18n.tr("Edit")
> -                    iconSource: "../../img/edit.png"
> -                    onTriggered: {
> -                        PopupUtils.open(editPopoverComponent, photoEditButton);
> -                    }
> -                }
> -            }
> -            ToolbarButton {
> -                id: photoAddButton
> +                text: i18n.tr("Edit")
> +                iconSource: "../../img/edit.png"
> +                onTriggered: PopupUtils.open(editPopoverComponent, null);
> +            },
> +            Action {
>                  objectName: "addButton"
> -                action: Action {
> -                    text: i18n.tr("Add photo to album")
> -                    iconSource: "../../img/add.png"
> -                    onTriggered: {
> -                        __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"),
> -                                                        photoAddButton,
> -                                                        {contentHeight: viewerWrapper.__pickerContentHeight});
> -                    }
> +                text: i18n.tr("Add to album")
> +                iconName: "add"
> +                onTriggered: {
> +                    __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"),
> +                                                    null,
> +                                                    {contentHeight: viewerWrapper.__pickerContentHeight});
>                  }
> -                text: i18n.tr("Add")
> -            }
> -            ToolbarButton {
> +            },
> +            Action {
>                  objectName: "deleteButton"
> -                action: Action {
> -                    text: i18n.tr("Delete")
> -                    iconSource: "../../img/delete.png"
> -                    onTriggered: {
> -                        if (album)
> -                            PopupUtils.open(removeFromAlbumDialog, null);
> -                        else
> -                            PopupUtils.open(deleteDialog, null);
> -                    }
> -                }
>                  text: i18n.tr("Delete")
> -            }
> -            ToolbarButton {
> -                id: photoShareButton
> -                objectName: "shareButton"
> +                iconName: "delete"
> +                onTriggered: {
> +                    if (album)
> +                        PopupUtils.open(removeFromAlbumDialog, null);
> +                    else
> +                        PopupUtils.open(deleteDialog, null);
> +                }
> +            },
> +            Action {
> +                text: i18n.tr("Share photo")
> +                iconName: "share"
>                  visible: !APP.desktopMode
> -                action: Action {
> -                    text: i18n.tr("Share photo")
> -                    iconSource: "../../img/share.png"
> -                    onTriggered: {
> -                        sharePicker.visible = true;
> -                    }
> -                }
> -                text: i18n.tr("Share")
> -            }
> -            back: ToolbarButton {
> -                objectName: "backButton"
> -                text: i18n.tr("Back")
> -                iconSource: "../../img/back.png"
> -                onTriggered: {
> -                    galleryPhotoViewer.currentItem.reset();
> -                    closeRequested();
> -                }
> -            }
> -        }
> +                onTriggered: sharePicker.visible = true;
> +            }
> +        ]
> + 
>  
> -        property Item videoToolbar: ToolbarItems {
> -            ToolbarButton {
> +        property list<Action> videoActions: [
> +            Action {
>                  text: galleryPhotoViewer.currentItem ?
> -                          (galleryPhotoViewer.currentItem.isPlayingVideo ?
> -                               i18n.tr("Pause") : i18n.tr("Play"))
> -                        : ""
> +                    (galleryPhotoViewer.currentItem.isPlayingVideo ?
> +                        i18n.tr("Pause") : i18n.tr("Play"))
> +                    : ""
>                  iconSource: galleryPhotoViewer.currentItem ?
> -                                (galleryPhotoViewer.currentItem.isPlayingVideo ?
> -                                     "../../img/icon_pause.png" : "../../img/icon_play.png")
> -                              : ""
> -                onTriggered: {
> -                    galleryPhotoViewer.currentItem.togglePlayPause();
> -                }
> -            }
> -            ToolbarButton {
> -                id: videoAddButton
> -                objectName: "addButton"
> -                text: i18n.tr("Add")
> -                iconSource: "../../img/add.png"
> +                    (galleryPhotoViewer.currentItem.isPlayingVideo ?
> +                        "../../img/icon_pause.png" : "../../img/icon_play.png")
> +                    : ""
> +                onTriggered: galleryPhotoViewer.currentItem.togglePlayPause();
> +            },
> +            Action {
> +                text: i18n.tr("Add to album")
> +                iconName: "add"
>                  onTriggered: {
>                      __albumPicker = PopupUtils.open(Qt.resolvedUrl("../Components/PopupAlbumPicker.qml"),
> -                                                    videoAddButton,
> +                                                    null,
>                                                      {contentHeight: viewerWrapper.__pickerContentHeight});
>                  }
> -            }
> -            ToolbarButton {
> -                objectName: "deleteButton"
> +            },
> +            Action {
>                  text: i18n.tr("Delete")
> -                iconSource: "../../img/delete.png"
> +                iconName: "delete"
>                  onTriggered: {
> -                    PopupUtils.open(deleteDialog, null);
> +                    if (album)
> +                        PopupUtils.open(removeFromAlbumDialog, null);
> +                    else
> +                        PopupUtils.open(deleteDialog, null);
>                  }
> -            }
> -            ToolbarButton {
> -                id: videoShareButton
> -                objectName: "shareButton"
> +            },
> +            Action {
> +                text: i18n.tr("Share photo")
> +                iconName: "share"
>                  visible: !APP.desktopMode
> -                text: i18n.tr("Share")
> -                iconSource: "../../img/share.png"
> -                onTriggered: {
> -                    sharePicker.visible = true;
> -                }
> +                onTriggered: sharePicker.visible = true;
>              }
> +        ]
>  
> -            back: ToolbarButton {
> -                objectName: "backButton"
> -                text: i18n.tr("Back")
> -                iconSource: "../../img/back.png"
> -                onTriggered: {
> -                    galleryPhotoViewer.currentItem.reset();
> -                    closeRequested();
> -                }
> +        property Action backAction: Action {
> +            iconName: "back"
> +            onTriggered: {
> +                galleryPhotoViewer.currentItem.reset();
> +                closeRequested();
>              }
>          }
>      }
> +
> +    Rectangle{
> +        id: headerBackground
> +        width: parent.width
> +        height: header.height
> +        visible: header.visible
> +    }
>  }
> 
> === removed file 'rc/qml/MediaViewer/PhotoViewerDelegate.qml'
> --- rc/qml/MediaViewer/PhotoViewerDelegate.qml	2014-03-19 20:01:31 +0000
> +++ rc/qml/MediaViewer/PhotoViewerDelegate.qml	1970-01-01 00:00:00 +0000
> @@ -1,129 +0,0 @@
> -/*
> - * Copyright (C) 2011-2012 Canonical Ltd
> - *
> - * This program is free software: you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 3 as
> - * published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> - *
> - * Authors:
> - * Lucas Beeler <lucas at yorba.org>
> - */
> -
> -import QtQuick 2.0
> -import Gallery 1.0
> -import Ubuntu.Components 0.1
> -import Ubuntu.Components.Popups 0.1
> -import Ubuntu.Components.ListItems 0.1 as ListItem
> -import "../../js/Gallery.js" as Gallery
> -
> -/*!
> -*/
> -Item {
> -    id: photoViewerDelegate
> -
> -    /// The photo to show
> -    property MediaSource mediaSource
> -    /*!
> -    */
> -    property bool useInteractivePreview
> -    /*!
> -    */
> -    property alias isLoaded: fullPhotoComponentLoader.isLoaded
> -
> -    /*!
> -    */
> -    signal clicked()
> -    /*!
> -    */
> -    signal zoomed()
> -    /*!
> -    */
> -    signal unzoomed()
> -
> -    /// Resets the view to it's initial state
> -    function reset() {
> -        if (!isLoaded)
> -            return;
> -
> -        fullPhotoComponentLoader.item.unzoom();
> -    }
> -
> -    Connections {
> -        target: mediaSource
> -        onDataChanged: {
> -            // Force the image to be reloaded, to pick up the new thumbnail
> -            interactivePreviewImage.active = false;
> -            interactivePreviewImage.active = true;
> -        }
> -    }
> -
> -    // Note that we haven't defined a state set in this component, even though
> -    // we bind the "state" property here. This is intentional and is necessary
> -    // to work around a binding issue on Qt 5.0 beta 1. Given a later version
> -    // of Qt, this treatment might not be necessary.
> -    state: (fullPhotoComponentLoader.item &&
> -            !fullPhotoComponentLoader.item.fullyUnzoomed) ? "zoomed" :
> -                                                            "unzoomed";
> -    Component {
> -        id: interactivePreviewImageSource
> -        Image {
> -            fillMode: Image.PreserveAspectFit
> -
> -            source: mediaSource ? mediaSource.galleryPreviewPath : ""
> -            sourceSize.width: 256
> -            cache: false
> -        }
> -    }
> -
> -    Loader {
> -        id: interactivePreviewImage
> -        z: 0
> -        anchors.fill: parent
> -
> -        visible: photoViewerDelegate.state == "unzoomed"
> -        sourceComponent: interactivePreviewImageSource
> -    }
> -
> -    Loader {
> -        id: fullPhotoComponentLoader
> -
> -        property bool isLoaded: status == Loader.Ready
> -
> -        z: 1
> -        asynchronous: true
> -        anchors.fill: parent
> -        opacity: (isLoaded && !useInteractivePreview) ? 1.0 : 0.0
> -
> -        sourceComponent: (!useInteractivePreview && !sourceComponent) ?
> -                             fullPhotoComponent : sourceComponent;
> -
> -        Component {
> -            id: fullPhotoComponent
> -
> -            ZoomablePhotoComponent {
> -                id: galleryPhotoComponent
> -                objectName: "openedPhoto" + index
> -
> -                anchors.fill: parent
> -                color: "transparent"
> -
> -                mediaSource: photoViewerDelegate.mediaSource
> -                load: true;
> -
> -                ownerName: "photoViewerDelegate"
> -
> -                onZoomed: photoViewerDelegate.zoomed()
> -                onUnzoomed: photoViewerDelegate.unzoomed()
> -                onClicked: photoViewerDelegate.clicked()
> -            }
> -        }
> -    }
> -}
> 
> === modified file 'rc/qml/MediaViewer/PopupPhotoViewer.qml'
> --- rc/qml/MediaViewer/PopupPhotoViewer.qml	2014-06-10 15:26:17 +0000
> +++ rc/qml/MediaViewer/PopupPhotoViewer.qml	2014-08-27 03:28:24 +0000
> @@ -18,7 +18,7 @@
>   */
>  
>  import QtQuick 2.0
> -import Ubuntu.Components 0.1
> +import Ubuntu.Components 1.1
>  import "../Utility"
>  
>  // A PhotoViewer that is opened and closed with the PhotoViewerTransition.
> @@ -40,18 +40,18 @@
>      property bool isPoppedUp: popupPhotoViewer.visible && viewer.visible && !animationRunning
>  
>      // updating active will automatically set the tools of the toolbar when activating.
> -    onActiveChanged: {
> -        if (active && popupPhotoViewer.header) {
> -            popupPhotoViewer.header.hide();
> -            // FIXME: The hide function of header is not hiding it sometimes.
> -            // The issue started after we changed the page title
> -            popupPhotoViewer.header.visible = false;
> -        }
> -
> -        if (!active && popupPhotoViewer.header && popupPhotoViewer.header.visible == false) {
> -            popupPhotoViewer.header.visible = true;
> -        }
> -    }
> +    //onActiveChanged: {
> +    //    if (active && popupPhotoViewer.header) {
> +    //        popupPhotoViewer.header.hide();
> +    //        // FIXME: The hide function of header is not hiding it sometimes.
> +    //        // The issue started after we changed the page title
> +    //        popupPhotoViewer.header.visible = false;
> +    //    }
> +    //
> +    //    if (!active && popupPhotoViewer.header && popupPhotoViewer.header.visible == false) {
> +    //        popupPhotoViewer.header.visible = true;
> +    //    }
> +    //}

If this code is not necessary anymore can you please remove it instead of leaving it commented ?

>  
>      title: i18n.tr("Gallery")
>  
> @@ -95,7 +95,8 @@
>          closed();
>      }
>  
> -    tools: viewer.tools
> +    head.actions: viewer.actions
> +    head.backAction: viewer.backAction
>  
>      MediaViewer {
>          id: viewer
> @@ -133,6 +134,7 @@
>              setCurrentPhoto(forMediaSource);
>              viewer.openCompleted = true;
>              overview.pushPage(popupPhotoViewer);
> +            header.visible = false;
>              opened();
>              viewer.playVideo();
>          }
> 
> === added file 'rc/qml/MediaViewer/SingleMediaViewer.qml'
> --- rc/qml/MediaViewer/SingleMediaViewer.qml	1970-01-01 00:00:00 +0000
> +++ rc/qml/MediaViewer/SingleMediaViewer.qml	2014-08-27 03:28:24 +0000
> @@ -0,0 +1,241 @@
> +/*
> + * Copyright 2014 Canonical Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 3.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +import QtQuick 2.2
> +import QtMultimedia 5.0
> +import Ubuntu.Components 1.0
> +import Ubuntu.Components.ListItems 1.0 as ListItems
> +import Ubuntu.Components.Popups 1.0
> +import Ubuntu.Content 0.1
> +import Ubuntu.Thumbnailer 0.1
> +import Gallery 1.0
> +import "../Components"
> +
> +Item {
> +    id: viewer
> +    property bool pinchInProgress: zoomPinchArea.active
> +    property var mediaFileType
> +    property string mediaFileURL
> +    property real maxDimension
> +
> +    property bool isVideo: mediaFileType === MediaSource.Video
> +    property bool isPlayingVideo: isVideo && video.isPlaying
> +    property bool userInteracting: pinchInProgress || flickable.sizeScale != 1.0
> +
> +    signal clicked()
> +
> +    function zoomIn(centerX, centerY, factor) {
> +        flickable.scaleCenterX = centerX / (flickable.sizeScale * flickable.width);
> +        flickable.scaleCenterY = centerY / (flickable.sizeScale * flickable.height);
> +        flickable.sizeScale = factor;
> +    }
> +
> +    function zoomOut() {
> +        if (flickable.sizeScale != 1.0) {
> +            flickable.scaleCenterX = flickable.contentX / flickable.width / (flickable.sizeScale - 1);
> +            flickable.scaleCenterY = flickable.contentY / flickable.height / (flickable.sizeScale - 1);
> +            flickable.sizeScale = 1.0;
> +        }
> +    }
> +
> +    function reload() {
> +        if (!viewer.isVideo) {
> +            var src = image.source
> +            image.asynchronous = false
> +            image.source = ""
> +            image.asynchronous = true
> +            image.source = src;
> +
> +            src = highResolutionImage.source
> +            highResolutionImage.asynchronous = false
> +            highResolutionImage.source = ""
> +            highResolutionImage.asynchronous = true
> +            highResolutionImage.source = src
> +        }
> +    }
> +
> +    function reset() {
> +        if (viewer.isVideo) {
> +            if (video.item) {
> +                video.item.stop();
> +                video.sourceComponent = null;
> +            }
> +        } else zoomOut()
> +    }
> +
> +    function togglePlayPause() {
> +        if (video.isPlaying) video.pause();
> +        else video.play();
> +    }
> +
> +    ActivityIndicator {
> +        anchors.centerIn: parent
> +        visible: running
> +        running: image.status != Image.Ready
> +    }
> +
> +    PinchArea {
> +        id: zoomPinchArea
> +        anchors.fill: parent
> +
> +        property real initialZoom
> +        property real maximumScale: 3.0
> +        property real minimumZoom: 1.0
> +        property real maximumZoom: 3.0
> +        property bool active: false
> +        property var center
> +
> +        onPinchStarted: {
> +            active = true;
> +            initialZoom = flickable.sizeScale;
> +            center = zoomPinchArea.mapToItem(media, pinch.startCenter.x, pinch.startCenter.y);
> +            zoomIn(center.x, center.y, initialZoom);
> +        }
> +        onPinchUpdated: {
> +            var zoomFactor = MathUtils.clamp(initialZoom * pinch.scale, minimumZoom, maximumZoom);
> +            flickable.sizeScale = zoomFactor;
> +        }
> +        onPinchFinished: {
> +            active = false;
> +        }
> +
> +        Flickable {
> +            id: flickable
> +            anchors.fill: parent
> +            contentWidth: media.width
> +            contentHeight: media.height
> +            contentX: (sizeScale - 1) * scaleCenterX * width
> +            contentY: (sizeScale - 1) * scaleCenterY * height
> +            interactive: !viewer.pinchInProgress
> +
> +            property real sizeScale: 1.0
> +            property real scaleCenterX: 0.0
> +            property real scaleCenterY: 0.0
> +            Behavior on sizeScale {
> +                enabled: !viewer.pinchInProgress
> +                UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
> +            }
> +            Behavior on scaleCenterX {
> +                UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
> +            }
> +            Behavior on scaleCenterY {
> +                UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
> +            }
> +
> +            Item {
> +                id: media
> +
> +                width: flickable.width * flickable.sizeScale
> +                height: flickable.height * flickable.sizeScale
> +
> +                Image {
> +                    id: image
> +                    anchors.fill: parent
> +                    asynchronous: true
> +                    cache: false
> +                    source: "image://thumbnailer/" + mediaFileURL.toString()
> +                    sourceSize {
> +                        width: viewer.maxDimension
> +                        height: viewer.maxDimension
> +                    }
> +                    fillMode: Image.PreserveAspectFit
> +                    opacity: status == Image.Ready ? 1.0 : 0.0
> +                    Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
> +
> +                }
> +
> +                Image {
> +                    id: highResolutionImage
> +                    anchors.fill: parent
> +                    asynchronous: true
> +                    cache: false
> +                    source: flickable.sizeScale > 1.0 ? mediaFileURL : ""
> +                    sourceSize {
> +                        width: width
> +                        height: height
> +                    }
> +                    fillMode: Image.PreserveAspectFit
> +                }
> +            }
> +
> +            Loader {
> +                id: video
> +                anchors.fill: parent
> +                visible: viewer.isVideo && video.status == Loader.Ready &&
> +                         video.item.playbackState !== MediaPlayer.StoppedState
> +                onLoaded: {
> +                    item.source = mediaFileURL;
> +                    item.play()
> +                }
> +
> +                property bool isPlaying: item && item.playbackState === MediaPlayer.PlayingState
> +                function play() {
> +                    if (item) item.play();
> +                    else sourceComponent = component_video;
> +                }
> +                function pause() {
> +                    if (item) item.pause();
> +                }
> +            }
> +
> +            Icon {
> +                width: units.gu(5)
> +                height: units.gu(5)
> +                anchors.centerIn: parent
> +                name: "media-playback-start"
> +                color: "white"
> +                opacity: 0.8
> +                visible: viewer.isVideo &&
> +                         (!video.item || item.playbackState === MediaPlayer.StoppedState)
> +            }
> +
> +            MouseArea {
> +                anchors.fill: parent
> +                onDoubleClicked: {
> +                    clickTimer.stop();
> +                    if (viewer.isVideo) return;
> +
> +                    if (flickable.sizeScale < zoomPinchArea.maximumZoom) {
> +                        zoomIn(mouse.x, mouse.y, zoomPinchArea.maximumZoom);
> +                    } else {
> +                        zoomOut();
> +                    }
> +                }
> +                onClicked: clickTimer.start()
> +
> +                Timer {
> +                    id: clickTimer
> +                    interval: APP.doubleClickInterval + 20
> +                    onTriggered: viewer.clicked()
> +                }
> +            }
> +
> +            MouseArea {
> +                anchors.centerIn: parent
> +                width: units.gu(10)
> +                height: units.gu(10)
> +                enabled: viewer.isVideo
> +                onClicked: viewer.togglePlayPause()
> +            }
> +        }
> +
> +        Component {
> +            id: component_video
> +            Video { }
> +        }
> +    }
> +}
> +
> 
> === removed file 'rc/qml/MediaViewer/VideoViewerDelegate.qml'
> --- rc/qml/MediaViewer/VideoViewerDelegate.qml	2014-03-21 22:11:44 +0000
> +++ rc/qml/MediaViewer/VideoViewerDelegate.qml	1970-01-01 00:00:00 +0000
> @@ -1,125 +0,0 @@
> -/*
> - * Copyright (C) 2013 Canonical Ltd
> - *
> - * This program is free software: you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 3 as
> - * published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -import QtQuick 2.0
> -import QtMultimedia 5.0
> -import Gallery 1.0
> -
> -/*!
> -VideoViewerDelegate is an item to show a vide thumbnail, and play the video
> -if requrested
> -*/
> -Item {
> -    id: videoViewerDelegate
> -
> -    /// The video item that to be shown by this component
> -    property MediaSource mediaSource
> -    /// Is true, once this component is fully usable
> -    property bool isLoaded: thumbnail.status === Image.Ready
> -
> -    /// Stops the video playback if running
> -    function reset() {
> -        state = "stopped";
> -    }
> -
> -    /// Starts playing the video
> -    function playVideo() {
> -        if (!loader_video.item)
> -            loader_video.sourceComponent = component_video;
> -
> -        if (loader_video.item.source !== mediaSource.path)
> -            loader_video.item.source = mediaSource.path;
> -        loader_video.item.play();
> -    }
> -
> -    /// Toggles between playing and pausing the video playback
> -    function togglePlayPause() {
> -        if (!loader_video.item)
> -            loader_video.sourceComponent = component_video;
> -
> -        if (videoViewerDelegate.state === "playing") {
> -            loader_video.item.pause();
> -        } else {
> -            videoViewerDelegate.playVideo();
> -        }
> -    }
> -
> -    Image {
> -        id: thumbnail
> -
> -        anchors.fill: parent
> -        fillMode: Image.PreserveAspectFit
> -        source: mediaSource.galleryPreviewPath
> -        asynchronous: true
> -    }
> -
> -    Image {
> -        // Display a play icon if the media is a video
> -        source: "../../img/icon_play.png"
> -        anchors.centerIn: parent
> -    }
> -
> -    MouseArea {
> -        anchors.fill: parent
> -        onClicked: {
> -            videoViewerDelegate.togglePlayPause();
> -        }
> -    }
> -
> -    Component {
> -        id: component_video
> -        Video {
> -            id: video
> -            onStopped: {
> -                videoViewerDelegate.state = "stopped";
> -            }
> -            onPaused: {
> -                videoViewerDelegate.state = "paused"
> -            }
> -            onPlaying: {
> -                videoViewerDelegate.state = "playing"
> -            }
> -        }
> -    }
> -    Loader {
> -        id: loader_video
> -        anchors.fill: parent
> -    }
> -
> -
> -    state: "stopped"
> -    states: [
> -        State {
> -            name: "playing"
> -            PropertyChanges { target: thumbnail; visible: false }
> -        },
> -        State {
> -            name: "paused"
> -            PropertyChanges { target: thumbnail; visible: false }
> -        },
> -        State {
> -            name: "stopped"
> -            PropertyChanges { target: thumbnail; visible: true }
> -        }
> -    ]
> -    onStateChanged: {
> -        if (state === "stopped") {
> -            if (loader_video.item)
> -                loader_video.item.stop()
> -            loader_video.sourceComponent = null
> -        }
> -    }
> -}
> 
> === removed file 'rc/qml/MediaViewer/ZoomablePhotoComponent.qml'
> --- rc/qml/MediaViewer/ZoomablePhotoComponent.qml	2014-04-04 13:16:49 +0000
> +++ rc/qml/MediaViewer/ZoomablePhotoComponent.qml	1970-01-01 00:00:00 +0000
> @@ -1,409 +0,0 @@
> -/*
> - * Copyright (C) 2012 Canonical Ltd
> - *
> - * This program is free software: you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 3 as
> - * published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> - *
> - * Authors:
> - * Charles Lindsay <chaz at yorba.org>
> - * Lucas Beeler <lucas at yorba.org>
> - */
> -
> -import QtQuick 2.0
> -import "../../js/Gallery.js" as Gallery
> -import "../../js/GalleryUtility.js" as GalleryUtility
> -import "../../js/GraphicsRoutines.js" as GraphicsRoutines
> -import "../Components"
> -
> -// PhotoComponent that allows you to zoom in on the photo.
> -Rectangle {
> -    id: zoomablePhotoComponent
> -
> -    /*!
> -    */
> -    signal loaded()
> -    /*!
> -    */
> -    signal clicked()
> -    /*!
> -    */
> -    signal zoomed()
> -    /*!
> -    */
> -    signal unzoomed()
> -
> -    /*!
> -    */
> -    property var mediaSource
> -    /*!
> -    */
> -    property bool load: false
> -    /*!
> -    */
> -    property bool isPreview
> -    /*!
> -    */
> -    property string ownerName
> -
> -    // read-only
> -    /*!
> -    */
> -    property alias paintedWidth: unzoomedPhoto.paintedWidth
> -    /*!
> -    */
> -    property alias paintedHeight: unzoomedPhoto.paintedHeight
> -    /*!
> -    */
> -    property alias isLoaded: unzoomedPhoto.isLoaded
> -    /*!
> -    */
> -    property int zoomFocusX: 0 // Relative to zoomablePhotoComponent.
> -    /*!
> -    */
> -    property int zoomFocusY: 0
> -    /*!
> -    */
> -    property real zoomFactor: 1
> -    /*!
> -    */
> -    property bool fullyUnzoomed: (state === "unzoomed" && zoomFactor === 1)
> -    /*!
> -    */
> -    property bool fullyZoomed: (state === "full_zoom" && zoomFactor === maxZoomFactor)
> -
> -    // Though little documented, Qt has a dedicated background thread, separate
> -    // from the main GUI thread, in which it renders on-screen objects (see
> -    // http://blog.qt.digia.com/blog/2012/08/20/render-thread-animations-in-qt-quick-2-0/
> -    // for a discussion of this topic). Unfortunately, animation ticks are timed
> -    // by the main GUI thread, but actual drawing in response to these ticks
> -    // is done in the separate rendering thread. Because of this, you can get
> -    // into a situation in which an animation reports that it has completed but
> -    // the separate rendering thread still has a frame to draw. In all of my
> -    // testing, I've never seen this timing mismatch exceed 1/30th of a second,
> -    // which makes sense because the QML animation clock ticks every 1/60th of a
> -    // second, according to the docs (see http://qt-project.org/doc/qt-5.0/qtqml/qml-qtquick2-timer.html),
> -    // though implementations appear to be free to drop to half this rate
> -    // (see https://bugreports.qt-project.org/browse/QTBUG-28487). So we define
> -    // an animation frame as 1/30th of a second and wait this long before doing
> -    // more drawing in response to the completion of an animation to prevent
> -    // stuttering.
> -    property int oneFrame: Math.ceil(1000 / 30);
> -
> -    // internal
> -    /*!
> -    */
> -    property real maxZoomFactor: 2.5
> -    /*!
> -    */
> -    property real photoFocusX: zoomFocusX - unzoomedPhoto.leftEdge
> -    /*!
> -    */
> -    property real photoFocusY: zoomFocusY - unzoomedPhoto.topEdge
> -    /*!
> -    */
> -    property bool isZoomAnimationInProgress: false
> -
> -    clip: true
> -
> -    /*!
> -    */
> -    function zoom(x, y) {
> -        zoomFocusX = x;
> -        zoomFocusY = y;
> -        state = "full_zoom";
> -    }
> -
> -    /*!
> -    */
> -    function unzoom() {
> -        state = "unzoomed";
> -    }
> -
> -    /*!
> -    */
> -    function toggleZoom(x, y) {
> -        if (state === "unzoomed")
> -            zoom(x, y);
> -        else
> -            unzoom();
> -    }
> -
> -    states: [
> -        State { name: "unzoomed";
> -            PropertyChanges { target: zoomablePhotoComponent; zoomFactor: 1; }
> -        },
> -        State { name: "full_zoom";
> -            PropertyChanges { target: zoomablePhotoComponent; zoomFactor: maxZoomFactor; }
> -        },
> -        State { name: "pinching";
> -            // Setting the zoom factor to itself seems odd, but it's necessary to
> -            // prevent zoomFactor from jumping when you start pinching.
> -            PropertyChanges { target: zoomablePhotoComponent; zoomFactor: zoomFactor;
> -                explicit: true; }
> -        }
> -    ]
> -
> -    transitions: [
> -        // Double-click transitions.
> -        Transition { from: "full_zoom"; to: "unzoomed";
> -            SequentialAnimation {
> -                ScriptAction { script: isZoomAnimationInProgress = true; }
> -                NumberAnimation { properties: "zoomFactor"; easing.type: Easing.InQuad;
> -                    duration: Gallery.FAST_DURATION; }
> -                PauseAnimation { duration: oneFrame }
> -                ScriptAction { script: isZoomAnimationInProgress = false; }
> -            }
> -        },
> -
> -        Transition { from: "unzoomed"; to: "full_zoom";
> -            SequentialAnimation {
> -                ScriptAction { script: isZoomAnimationInProgress = true; }
> -                NumberAnimation { properties: "zoomFactor"; easing.type: Easing.InQuad;
> -                    duration: Gallery.FAST_DURATION; }
> -                PauseAnimation { duration: oneFrame }
> -                ScriptAction { script: isZoomAnimationInProgress = false; }
> -            }
> -        },
> -
> -        Transition { from: "pinching"; to: "unzoomed";
> -            SequentialAnimation {
> -                ScriptAction { script: isZoomAnimationInProgress = true; }
> -                NumberAnimation { properties: "zoomFactor"; easing.type: Easing.Linear;
> -                    duration: Gallery.SNAP_DURATION; }
> -                PauseAnimation { duration: oneFrame }
> -                ScriptAction { script: isZoomAnimationInProgress = false; }
> -            }
> -        },
> -
> -        Transition { from: "pinching"; to: "full_zoom";
> -            SequentialAnimation {
> -                ScriptAction { script: isZoomAnimationInProgress = true; }
> -                NumberAnimation { properties: "zoomFactor"; easing.type: Easing.Linear;
> -                    duration: Gallery.SNAP_DURATION; }
> -                PauseAnimation { duration: oneFrame }
> -                ScriptAction { script: isZoomAnimationInProgress = false; }
> -            }
> -        }
> -    ]
> -
> -    state: "unzoomed"
> -
> -    onStateChanged: {
> -        if (state === "full_zoom")
> -            zoomed();
> -        else if (state === "unzoomed")
> -            unzoomed();
> -    }
> -
> -    GalleryPhotoComponent {
> -        id: unzoomedPhoto
> -
> -        property real leftEdge: (parent.width - paintedWidth) / 2
> -        property real topEdge: (parent.height - paintedHeight) / 2
> -
> -        function isInsidePhoto(x, y) {
> -            return (x >= leftEdge && x < leftEdge + paintedWidth &&
> -                    y >= topEdge && y < topEdge + paintedHeight);
> -        }
> -
> -        anchors.fill: parent
> -        visible: fullyUnzoomed
> -        color: zoomablePhotoComponent.color
> -
> -        mediaSource: zoomablePhotoComponent.mediaSource
> -        load: zoomablePhotoComponent.load && zoomablePhotoComponent.fullyUnzoomed
> -        isPreview: zoomablePhotoComponent.isPreview
> -        ownerName: zoomablePhotoComponent.ownerName + "unzoomedPhoto"
> -    }
> -
> -    PinchArea {
> -        id: pinchArea
> -
> -        property bool zoomingIn // Splaying to zoom in, vs. pinching to zoom out.
> -        property real initialZoomFactor
> -
> -        anchors.fill: parent
> -
> -        // QML seems to ignore these, so we have to manually keep scale in check
> -        // inside onPinchUpdated.  The 0.9 and 1.1 are just fudge factors to give
> -        // us a little bounce when you go past the zoom limit.
> -        pinch.minimumScale: 1 / initialZoomFactor * 0.9
> -        pinch.maximumScale: maxZoomFactor / initialZoomFactor * 1.1
> -
> -        onPinchStarted: {
> -            zoomingIn = false;
> -            initialZoomFactor = zoomFactor;
> -
> -            if (fullyUnzoomed) {
> -                if (unzoomedPhoto.isInsidePhoto(pinch.center.x, pinch.center.y)) {
> -                    zoomFocusX = pinch.center.x;
> -                    zoomFocusY = pinch.center.y;
> -                } else {
> -                    zoomFocusX = parent.width / 2;
> -                    zoomFocusY = parent.height / 2;
> -                }
> -            }
> -
> -            zoomablePhotoComponent.state = "pinching";
> -        }
> -
> -        onPinchUpdated: {
> -            // Determine if we're still zooming in or out.  Allow for a small
> -            // variance to account for touch noise.
> -            if (Math.abs(pinch.scale - pinch.previousScale) > 0.001)
> -                zoomingIn = (pinch.scale > pinch.previousScale);
> -
> -            // For some reason, the PinchArea ignores these settings.
> -            var scale = GraphicsRoutines.clamp(pinch.scale,
> -                                               pinchArea.pinch.minimumScale, pinchArea.pinch.maximumScale);
> -
> -            zoomFactor = initialZoomFactor * scale;
> -        }
> -
> -        onPinchFinished: zoomablePhotoComponent.state = (zoomingIn ? "full_zoom" : "unzoomed")
> -
> -        MouseAreaWithMultipoint {
> -            desktop: APP.desktopMode
> -            anchors.fill: parent
> -            enabled: fullyUnzoomed
> -
> -            onClicked: zoomablePhotoComponent.clicked()
> -            onDoubleClicked: {
> -                if (unzoomedPhoto.isInsidePhoto(mouse.x, mouse.y))
> -                    zoom(mouse.x, mouse.y);
> -                else
> -                    zoomablePhotoComponent.clicked();
> -            }
> -        }
> -    }
> -
> -    Loader {
> -        id: zoomAssemblyLoader
> -
> -        anchors.fill: parent
> -
> -        sourceComponent: (fullyUnzoomed ? undefined : zoomAssemblyComponent)
> -
> -        Component {
> -            id: zoomAssemblyComponent
> -
> -            Item {
> -                anchors.fill: parent
> -
> -                Flickable {
> -                    id: zoomArea
> -
> -                    property real zoomAreaZoomFactor: maxZoomFactor
> -                    property real minContentFocusX: (contentWidth < parent.width
> -                                                     ? contentWidth : parent.width) / 2
> -                    property real maxContentFocusX: contentWidth - minContentFocusX
> -                    property real minContentFocusY: (contentHeight < parent.height
> -                                                     ? contentHeight : parent.height) / 2
> -                    property real maxContentFocusY: contentHeight - minContentFocusY
> -                    property real contentFocusX: GraphicsRoutines.clamp(
> -                                                     photoFocusX * zoomAreaZoomFactor,
> -                                                     minContentFocusX, maxContentFocusX)
> -                    property real contentFocusY: GraphicsRoutines.clamp(
> -                                                     photoFocusY * zoomAreaZoomFactor,
> -                                                     minContentFocusY, maxContentFocusY)
> -                    // Translate between focus point and top/left point.  Note: you might think
> -                    // that this should take into account the left and top margins, but
> -                    // apparently not.
> -                    property real contentFocusLeft: contentFocusX - parent.width / 2
> -                    property real contentFocusTop: contentFocusY - parent.height / 2
> -
> -                    anchors.fill: parent
> -                    visible: fullyZoomed && !isZoomAnimationInProgress
> -
> -                    onVisibleChanged: {
> -                        if (visible) {
> -                            contentX = contentFocusLeft;
> -                            contentY = contentFocusTop;
> -                        }
> -                    }
> -
> -                    onContentXChanged: {
> -                        var contentFocusX = contentX + width / 2;
> -                        var photoFocusX = contentFocusX / zoomAreaZoomFactor;
> -                        zoomFocusX = photoFocusX + unzoomedPhoto.leftEdge;
> -                    }
> -
> -                    onContentYChanged: {
> -                        var contentFocusY = contentY + height / 2;
> -                        var photoFocusY = contentFocusY / zoomAreaZoomFactor;
> -                        zoomFocusY = photoFocusY + unzoomedPhoto.topEdge;
> -                    }
> -
> -                    flickableDirection: Flickable.HorizontalAndVerticalFlick
> -                    contentWidth: unzoomedPhoto.paintedWidth * zoomAreaZoomFactor
> -                    contentHeight: unzoomedPhoto.paintedHeight * zoomAreaZoomFactor
> -
> -                    leftMargin: Math.max(0, (parent.width - contentWidth) / 2)
> -                    rightMargin: leftMargin
> -                    topMargin: Math.max(0, (parent.height - contentHeight) / 2)
> -                    bottomMargin: topMargin
> -
> -                    GalleryPhotoComponent {
> -                        id: zoomedPhoto
> -
> -                        anchors.fill: parent
> -                        color: zoomablePhotoComponent.color
> -
> -                        mediaSource: zoomablePhotoComponent.mediaSource
> -                        load: zoomablePhotoComponent.load && fullyZoomed
> -
> -                        isPreview: zoomablePhotoComponent.isPreview
> -                        ownerName: zoomablePhotoComponent.ownerName + "zoomedPhoto"
> -
> -                        MouseAreaWithMultipoint {
> -                            desktop: APP.desktopMode
> -                            anchors.fill: parent
> -
> -                            onClicked: zoomablePhotoComponent.clicked()
> -                            onDoubleClicked: unzoom()
> -                        }
> -                    }
> -                }
> -
> -                GalleryPhotoComponent {
> -                    id: transitionPhoto
> -
> -                    property real unzoomedX: unzoomedPhoto.leftEdge
> -                    property real unzoomedY: unzoomedPhoto.topEdge
> -                    property real zoomedX: -zoomArea.contentFocusLeft
> -                    property real zoomedY: -zoomArea.contentFocusTop
> -
> -                    property real zoomFraction: (zoomFactor - 1) / (maxZoomFactor - 1)
> -
> -                    x: GalleryUtility.interpolate(unzoomedX, zoomedX, zoomFraction)
> -                    y: GalleryUtility.interpolate(unzoomedY, zoomedY, zoomFraction)
> -                    width: unzoomedPhoto.paintedWidth
> -                    height: unzoomedPhoto.paintedHeight
> -                    scale: zoomFactor
> -                    transformOrigin: Item.TopLeft
> -
> -                    visible: zoomablePhotoComponent.isZoomAnimationInProgress ||
> -                             zoomablePhotoComponent.state == "pinching" ||
> -                             !zoomedPhoto.isLoaded
> -
> -                    color: zoomablePhotoComponent.color
> -
> -                    mediaSource: zoomablePhotoComponent.mediaSource
> -                    load: zoomablePhotoComponent.load
> -                    isPreview: zoomablePhotoComponent.isPreview
> -                    isAnimate: true
> -                    ownerName: zoomablePhotoComponent.ownerName + "transitionPhoto"
> -                }
> -            }
> -        }
> -    }
> -}
> 
> === modified file 'rc/qml/OrganicView/OrganicView.qml'
> --- rc/qml/OrganicView/OrganicView.qml	2014-03-10 17:20:03 +0000
> +++ rc/qml/OrganicView/OrganicView.qml	2014-08-27 03:28:24 +0000
> @@ -18,7 +18,7 @@
>   */
>  
>  import QtQuick 2.0
> -import Ubuntu.Components 0.1
> +import Ubuntu.Components 1.1
>  import "../Utility"
>  import "../../js/Gallery.js" as Gallery
>  
> 
> === modified file 'rc/qml/PhotosOverview.qml'
> --- rc/qml/PhotosOverview.qml	2013-09-30 17:01:38 +0000
> +++ rc/qml/PhotosOverview.qml	2014-08-27 03:28:24 +0000
> @@ -111,7 +111,7 @@
>              }
>              onAddClicked: {
>                  __albumPicker = PopupUtils.open(Qt.resolvedUrl("Components/PopupAlbumPicker.qml"),
> -                                                caller,
> +                                                null,
>                                                  {contentHeight: photosOverview.__pickerContentHeight});
>              }
>              onDeleteClicked: {
> 
> === modified file 'rc/qml/Utility/PhotosToolbarActions.qml'
> --- rc/qml/Utility/PhotosToolbarActions.qml	2014-03-19 20:19:57 +0000
> +++ rc/qml/Utility/PhotosToolbarActions.qml	2014-08-27 03:28:24 +0000
> @@ -29,23 +29,29 @@
>      signal startCamera()
>  
>      ToolbarButton {
> -        objectName: "selectButton"
> -        text: i18n.tr("Select")
> -        iconSource: Qt.resolvedUrl("../../img/select.png")
> -        enabled: root.selection !== null
> -        onTriggered: root.selection.inSelectionMode = true;
> +        action: Action {
> +            objectName: "selectButton"
> +            text: i18n.tr("Select")
> +            iconSource: Qt.resolvedUrl("../../img/select.png")
> +            enabled: root.selection !== null
> +            onTriggered: root.selection.inSelectionMode = true;
> +        }
>      }
>      ToolbarButton {
>          objectName: "importButton"
> -        text: i18n.tr("Import")
> -        iconSource: Qt.resolvedUrl("../../img/import-image.png")
> -        enabled: false
> +        action: Action {
> +            text: i18n.tr("Import")
> +            iconSource: Qt.resolvedUrl("../../img/import-image.png")
> +            visible: false
> +        }
>      }
>      ToolbarButton {
> -        objectName: "cameraButton"
> -        text: i18n.tr("Camera")
> -        visible: !APP.desktopMode
> -        iconSource: Qt.resolvedUrl("../../img/camera.png")
> -        onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version")
> +        action: Action {
> +            objectName: "cameraButton"
> +            text: i18n.tr("Camera")
> +            visible: !APP.desktopMode
> +            iconSource: Qt.resolvedUrl("../../img/camera.png")
> +            onTriggered: Qt.openUrlExternally("appid://com.ubuntu.camera/camera/current-user-version")
> +        }
>      }
>  }
> 
> === modified file 'rc/qml/Utility/SelectionToolbarAction.qml'
> --- rc/qml/Utility/SelectionToolbarAction.qml	2013-09-19 14:53:09 +0000
> +++ rc/qml/Utility/SelectionToolbarAction.qml	2014-08-27 03:28:24 +0000
> @@ -33,6 +33,8 @@
>      signal addClicked(var caller)
>      ///Emitted when delete was clicked
>      signal deleteClicked()
> +    ///Emitted when share was clicked
> +    signal shareClicked()
>  
>      // in selection mode, never hide the toolbar:
>      opened: true
> @@ -41,32 +43,40 @@
>      ToolbarButton {
>          id: addButton
>          objectName: "addButton"
> -        text: i18n.tr("Add")
> -        iconSource: Qt.resolvedUrl("../../img/add.png")
> -        enabled: root.selection.selectedCount > 0
> -        onTriggered: root.addClicked(addButton);
> +        action: Action {
> +            text: i18n.tr("Add")
> +            iconName: "add"
> +            enabled: root.selection.selectedCount > 0
> +            onTriggered: root.addClicked(addButton);
> +        }
>      }
>      ToolbarButton {
> -        objectName: "deleteButton"
> -        text: i18n.tr("Delete")
> -        iconSource: Qt.resolvedUrl("../../img/delete.png")
> -        enabled: root.selection.selectedCount > 0
> -        onTriggered:root.deleteClicked();
> +        action: Action {
> +            objectName: "deleteButton"
> +            text: i18n.tr("Delete")
> +            iconName: "delete"
> +            enabled: root.selection.selectedCount > 0
> +            onTriggered:root.deleteClicked();
> +        }
>      }
>      ToolbarButton {
>          objectName: "shareButton"
> -        text: i18n.tr("Share")
> -        iconSource: Qt.resolvedUrl("../../img/share.png")
> -        enabled: false
> +        action: Action {
> +            text: i18n.tr("Share")
> +            iconName: "share"
> +            enabled: root.selection.selectedCount > 0
> +            onTriggered: root.shareClicked();
> +        }
>      }
>  
>      back:  Button {
>          objectName: "cancelButton"
> -        anchors.verticalCenter: parent.verticalCenter
> -        text: i18n.tr("Cancel")
> -        width: units.gu(10)
> -        onClicked: {
> -            root.cancelClicked();
> +        action: Action {
> +            text: i18n.tr("Cancel")
> +            iconName: "back"
> +            onTriggered: {
> +                root.cancelClicked();
> +            }
>          }
>      }
>  }
> 
> === modified file 'tests/autopilot/gallery_app/tests/__init__.py'
> --- tests/autopilot/gallery_app/tests/__init__.py	2014-07-14 15:29:11 +0000
> +++ tests/autopilot/gallery_app/tests/__init__.py	2014-08-27 03:28:24 +0000
> @@ -262,8 +262,6 @@
>  
>      def open_album_at(self, position):
>          album = self.album_view.get_album_at(position)
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          self.click_item(album)
>          self.ensure_view_is_fully_open()
>  
> 
> === modified file 'tests/autopilot/gallery_app/tests/test_album_editor.py'
> --- tests/autopilot/gallery_app/tests/test_album_editor.py	2014-06-10 19:00:23 +0000
> +++ tests/autopilot/gallery_app/tests/test_album_editor.py	2014-08-27 03:28:24 +0000
> @@ -33,13 +33,10 @@
>          self.ARGS = []
>          super(TestAlbumEditor, self).setUp()
>          self.switch_to_albums_tab()
> -        self.main_view.close_toolbar()
>          self.edit_first_album()
>  
>      def edit_first_album(self):
>          first_album = self.gallery_utils.get_first_album()
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          self.tap_item(first_album)
>          edit_button = self.gallery_utils.get_edit_album_button()
>          self.click_item(edit_button)
> @@ -58,8 +55,7 @@
>          text = "Ubuntu"
>          self.assertThat(subtitle_field.text, Eventually(Equals(text)))
>  
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
> +        sleep(5)
>          editor.click_title_field()
>          self.assertThat(title_field.activeFocus, Eventually(Equals(True)))
>          self.keyboard.press_and_release("Ctrl+a")
> @@ -81,38 +77,40 @@
>          """Tests adding a photo using the media selector"""
>          # first open, but cancel before adding a photo
>          editor = self.app.select_single(album_editor.AlbumEditor)
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          editor.add_photos()
>          self.media_selector.ensure_fully_open()
>  
>          sleep(5)
> -        self.main_view.get_toolbar().click_custom_button("cancelButton")
> +        self.main_view.get_header().click_custom_back_button()
> +
>          editor.ensure_fully_closed()
>  
> -        self.main_view.close_toolbar()
> +        sleep(5)
>          self.open_first_album()
>          num_photos_start = self.album_view.number_of_photos()
>          self.assertThat(num_photos_start, Equals(1))
> -        self.main_view.open_toolbar().click_button("backButton")
> +
> +        # should click away of any photo to toggle header
> +        photo = self.album_view.get_first_photo()
> +        x, y, w, h = photo.globalRect
> +        self.pointing_device.move(x + 40 , y + h + 40)
> +        self.pointing_device.click()
> +
> +        self.main_view.get_header().click_custom_back_button()
>          self.album_view.ensure_album_view_fully_closed()
>  
>          # now open to add a photo
> -        self.main_view.close_toolbar()
>          self.edit_first_album()
>          editor = self.app.select_single(album_editor.AlbumEditor)
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          editor.add_photos()
>          self.media_selector.ensure_fully_open()
>  
>          photo = self.media_selector.get_second_photo()
>          self.click_item(photo)
> -        self.main_view.get_toolbar().click_custom_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          editor = self.app.select_single(album_editor.AlbumEditor)
>          editor.ensure_fully_closed()
>  
> -        self.main_view.close_toolbar()
>          self.open_first_album()
>          num_photos = self.album_view.number_of_photos()
>          self.assertThat(num_photos, Equals(num_photos_start + 1))
> @@ -124,11 +122,8 @@
>          self.assertThat(
>              cover_image.source.endswith("album-cover-default-large.png"),
>              Equals(True))
> -        self.main_view.close_toolbar()
>  
>          # click somewhere rather at the bottom of the cover
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          x, y, w, h = cover_image.globalRect
>          self.pointing_device.move(x + int(w / 2), y + h - int(h / 10))
>          self.pointing_device.click()
> 
> === modified file 'tests/autopilot/gallery_app/tests/test_album_view.py'
> --- tests/autopilot/gallery_app/tests/test_album_view.py	2014-06-12 16:42:04 +0000
> +++ tests/autopilot/gallery_app/tests/test_album_view.py	2014-08-27 03:28:24 +0000
> @@ -48,24 +48,17 @@
>          self.switch_to_albums_tab()
>  
>      def test_album_view_open_photo(self):
> -        self.main_view.close_toolbar()
>          self.open_first_album()
> -        self.main_view.close_toolbar()
>          photo = self.album_view.get_first_photo()
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          self.click_item(photo)
>          sleep(5)
>          photo_view = self.main_view.wait_select_single("PopupPhotoViewer")
>          self.assertThat(photo_view.visible, Eventually(Equals(True)))
>  
>      def test_album_view_flipping(self):
> -        self.main_view.close_toolbar()
> -
>          # For some reason here the album at position 0 in the autopilot list is
>          # actually the second album, they seem to be returned in reverse order.
>          self.open_album_at(0)
> -        self.main_view.close_toolbar()
>  
>          spread = self.album_view.get_spread_view()
>  
> @@ -84,35 +77,39 @@
>          self.assertThat(spread.viewingPage, Eventually(GreaterThan(1)))
>  
>      def test_add_photo(self):
> -        self.main_view.close_toolbar()
>          self.open_first_album()
>          num_photos_start = self.album_view.number_of_photos()
>          self.assertThat(num_photos_start, Equals(1))
>  
> +        # should click away of any photo to toggle header
> +        photo = self.album_view.get_first_photo()
> +        x, y, w, h = photo.globalRect
> +        self.pointing_device.move(x + 40 , y + h + 40)
> +        self.pointing_device.click()
> +
>          # open media selector but cancel
> -        self.main_view.open_toolbar().click_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          self.media_selector.ensure_fully_open()
>  
> -        self.main_view.get_toolbar().click_custom_button("cancelButton")
> +        self.main_view.get_header().click_custom_back_button()
>          sleep(1)
>  
>          num_photos = self.album_view.number_of_photos()
>          self.assertThat(num_photos, Equals(num_photos_start))
>  
>          # open media selector and add a photo
> -        self.main_view.open_toolbar().click_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          self.media_selector.ensure_fully_open()
>  
>          photo = self.media_selector.get_second_photo()
>          self.click_item(photo)
> -        self.main_view.get_toolbar().click_custom_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>  
>          self.assertThat(
>              lambda: self.album_view.number_of_photos(),
>              Eventually(Equals(num_photos_start + 1)))
>  
>      def test_remove_photo_from_album(self):
> -        self.main_view.close_toolbar()
>          self.open_first_album()
>          num_photos_start = self.album_view.number_of_photos()
>          self.assertThat(num_photos_start, Equals(1))
> @@ -125,7 +122,11 @@
>          photo_view = self.album_view.get_album_photo_view()
>          self.assertThat(photo_view.visible, Eventually(Equals(True)))
>  
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        x, y, w, h = photo_view.globalRect
> +        self.pointing_device.move(x + int(w/2), y + int(h/2))
> +        self.pointing_device.click()
> +
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.album_view.click_remove_from_album_remove_button()
>  
>          self.assertThat(lambda: self.album_view.number_of_photos(),
> @@ -135,7 +136,6 @@
>                          Eventually(Equals(True)))
>  
>      def test_remove_photo_from_album_and_delete(self):
> -        self.main_view.close_toolbar()
>          self.open_first_album()
>          num_photos_start = self.album_view.number_of_photos()
>          self.assertThat(num_photos_start, Equals(1))
> @@ -148,7 +148,11 @@
>          photo_view = self.album_view.get_album_photo_view()
>          self.assertThat(photo_view.visible, Eventually(Equals(True)))
>  
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        x, y, w, h = photo_view.globalRect
> +        self.pointing_device.move(x + int(w/2), y + int(h/2))
> +        self.pointing_device.click()
> +
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.album_view.click_remove_from_album_delete_button()
>  
>          self.assertThat(lambda: self.album_view.number_of_photos(),
> @@ -158,7 +162,6 @@
>                          Eventually(Equals(False)))
>  
>      def test_cancel_remove_photo_from_album(self):
> -        self.main_view.close_toolbar()
>          self.open_first_album()
>          num_photos_start = self.album_view.number_of_photos()
>          self.assertThat(num_photos_start, Equals(1))
> @@ -171,10 +174,13 @@
>          photo_view = self.album_view.get_album_photo_view()
>          self.assertThat(photo_view.visible, Eventually(Equals(True)))
>  
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        x, y, w, h = photo_view.globalRect
> +        self.pointing_device.move(x + int(w/2), y + int(h/2))
> +        self.pointing_device.click()
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.album_view.click_remove_from_album_cancel_button()
>  
> -        self.main_view.open_toolbar().click_button("backButton")
> +        self.main_view.get_header().click_custom_back_button()
>  
>          self.assertThat(lambda: self.album_view.number_of_photos(),
>                          Eventually(Equals(num_photos_start)))
> @@ -183,28 +189,24 @@
>                          Eventually(Equals(True)))
>  
>      def test_add_photo_to_new_album(self):
> -        self.main_view.open_toolbar().click_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          self.ui_update()
>  
>          editor = self.app.select_single(album_editor.AlbumEditor)
>          editor.ensure_fully_open()
> -        self.main_view.close_toolbar()
>          editor.close()
>  
>          self.open_first_album()
> -        self.main_view.close_toolbar()
>          num_photos_start = self.album_view.number_of_photos()
>          self.assertThat(num_photos_start, Equals(0))
>  
>          plus = self.album_view.get_plus_icon_empty_album()
> -        # workaround lp:1247698
> -        self.main_view.close_toolbar()
>          self.click_item(plus)
>          self.media_selector.ensure_fully_open()
>  
>          photo = self.media_selector.get_second_photo()
>          self.click_item(photo)
> -        self.main_view.get_toolbar().click_custom_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>  
>          self.assertThat(
>              lambda: self.album_view.number_of_photos(),
> 
> === modified file 'tests/autopilot/gallery_app/tests/test_albums_view.py'
> --- tests/autopilot/gallery_app/tests/test_albums_view.py	2014-05-20 15:19:35 +0000
> +++ tests/autopilot/gallery_app/tests/test_albums_view.py	2014-08-27 03:28:24 +0000
> @@ -11,6 +11,7 @@
>  from testtools.matchers import Equals
>  from autopilot.matchers import Eventually
>  from autopilot.platform import model
> +from autopilot.introspection.dbus import StateNotFoundError
>  
>  from gallery_app.tests import GalleryTestCase
>  from gallery_app.emulators.albums_view import AlbumsView
> @@ -47,10 +48,19 @@
>  
>          super(TestAlbumsView, self).tearDown()
>  
> +    def check_header_button_exist(self, button):
> +        header = self.main_view.get_header()
> +        buttonName = button + "_header_button"
> +        try:
> +            header.select_single(objectName=buttonName)
> +        except StateNotFoundError:
> +            return False
> +        return True
> +
>      def test_add_album(self):
>          """Add one album, and checks if the number of albums went up by one"""
>          albums = self.albums_view.number_of_albums_in_albums_view()
> -        self.main_view.open_toolbar().click_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          self.assertThat(
>              lambda: self.albums_view.number_of_albums_in_albums_view(),
>              Eventually(Equals(albums+1))
> @@ -61,10 +71,10 @@
>          not change
>          """
>          albums = self.albums_view.number_of_albums_in_albums_view()
> -        self.main_view.open_toolbar().click_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          editor = self.app.select_single(album_editor.AlbumEditor)
>          editor.ensure_fully_open()
> -        self.main_view.get_toolbar().click_custom_button("cancelButton")
> +        self.main_view.get_header().click_custom_back_button()
>          self.assertThat(
>              lambda: self.albums_view.number_of_albums_in_albums_view(),
>              Eventually(Equals(albums))
> @@ -72,13 +82,8 @@
>  
>      # Check if Camera Button is not visible at Desktop mode
>      def test_camera_button_visible(self):
> -        self.main_view.open_toolbar()
> -        toolbar = self.main_view.get_toolbar()
> -        cameraButton = toolbar.select_single(
> -            "ActionItem",
> -            objectName="cameraButton"
> -        )
> +        cameraButtonVisible = self.check_header_button_exist("cameraButton")
>          if model() == "Desktop":
> -            self.assertThat(cameraButton.visible, Equals(False))
> +            self.assertThat(cameraButtonVisible, Equals(False))
>          else:
> -            self.assertThat(cameraButton.visible, Equals(True))
> +            self.assertThat(cameraButtonVisible, Equals(True))
> 
> === modified file 'tests/autopilot/gallery_app/tests/test_events_view.py'
> --- tests/autopilot/gallery_app/tests/test_events_view.py	2014-06-16 13:46:21 +0000
> +++ tests/autopilot/gallery_app/tests/test_events_view.py	2014-08-27 03:28:24 +0000
> @@ -11,6 +11,7 @@
>  from testtools.matchers import Equals, NotEquals, Is, GreaterThan
>  from autopilot.matchers import Eventually
>  from autopilot.platform import model
> +from autopilot.introspection.dbus import StateNotFoundError
>  
>  from gallery_app.tests import GalleryTestCase
>  from gallery_app.emulators.events_view import EventsView
> @@ -59,7 +60,16 @@
>                                             objectName="organicEventView")
>  
>      def enable_select_mode(self):
> -        self.main_view.open_toolbar().click_button("selectButton")
> +        self.main_view.get_header().click_action_button("selectButton")
> +
> +    def check_header_button_exist(self, button):
> +        header = self.main_view.get_header()
> +        buttonName = button + "_header_button"
> +        try:
> +            header.select_single(objectName=buttonName)
> +        except StateNotFoundError:
> +            return False
> +        return True
>  
>      def test_select_button_cancel(self):
>          """Clicking the cancel button after clicking the select button must
> @@ -70,10 +80,8 @@
>          self.enable_select_mode()
>          self.assertTrue(events_view.inSelectionMode)
>  
> -        self.main_view.get_toolbar().click_custom_button("cancelButton")
> +        self.main_view.get_header().click_custom_back_button()
>  
> -        toolbar = self.main_view.get_toolbar()
> -        self.assertThat(toolbar.opened, Eventually(Equals(False)))
>          self.assertFalse(events_view.inSelectionMode)
>  
>      def test_delete_a_photo(self):
> @@ -83,7 +91,7 @@
>  
>          self.enable_select_mode()
>          self.events_view.click_photo(self.sample_file)
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.assertThat(self.gallery_utils.delete_dialog_shown,
>                          Eventually(Is(True)))
>  
> @@ -94,7 +102,7 @@
>          self.assertThat(lambda: exists(self.sample_file),
>                          Eventually(Equals(True)))
>  
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.assertThat(self.gallery_utils.delete_dialog_shown,
>                          Eventually(Is(True)))
>  
> @@ -123,13 +131,8 @@
>  
>      # Check if Camera Button is not visible at Desktop mode
>      def test_camera_button_visible(self):
> -        self.main_view.open_toolbar()
> -        toolbar = self.main_view.get_toolbar()
> -        cameraButton = toolbar.select_single(
> -            "ActionItem",
> -            objectName="cameraButton"
> -        )
> +        cameraButtonVisible = self.check_header_button_exist("cameraButton")
>          if model() == "Desktop":
> -            self.assertThat(cameraButton.visible, Equals(False))
> +            self.assertThat(cameraButtonVisible, Equals(False))
>          else:
> -            self.assertThat(cameraButton.visible, Equals(True))
> +            self.assertThat(cameraButtonVisible, Equals(True))
> 
> === modified file 'tests/autopilot/gallery_app/tests/test_photo_viewer.py'
> --- tests/autopilot/gallery_app/tests/test_photo_viewer.py	2014-07-02 22:11:12 +0000
> +++ tests/autopilot/gallery_app/tests/test_photo_viewer.py	2014-08-27 03:28:24 +0000
> @@ -41,7 +41,8 @@
>          super(TestPhotoViewerBase, self).setUp()
>          self.main_view.switch_to_tab("eventsTab")
>          self.open_first_photo()
> -        self.main_view.open_toolbar()
> +        # Need to click on the photo to toggle header
> +        self.pointing_device.click()
>  
>      def open_first_photo(self):
>          self.assertThat(
> @@ -49,10 +50,6 @@
>              Eventually(GreaterThan(0))
>          )
>  
> -        # workaround lp:1247698
> -        # toolbar needs to be gone to click on an image.
> -        self.main_view.close_toolbar()
> -
>          self.events_view.click_photo(self.sample_file)
>  
>          photo_viewer_loader = self.photo_viewer.get_main_photo_viewer_loader()
> @@ -107,7 +104,7 @@
>  
>      def test_nav_bar_back_button(self):
>          """Clicking the back button must close the photo."""
> -        self.main_view.open_toolbar().click_button("backButton")
> +        self.main_view.get_header().click_custom_back_button()
>          photo_viewer = self.photo_viewer.get_main_photo_viewer()
>          self.assertThat(photo_viewer.visible, Eventually(Equals(False)))
>  
> @@ -123,7 +120,7 @@
>          self.assertThat(share_picker.visible, Eventually(Equals(False)))
>  
>      def delete_one_picture(self):
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.get_delete_dialog()
>          delete_item = self.photo_viewer.get_delete_popover_delete_item()
>          self.click_item(delete_item)
> @@ -131,7 +128,7 @@
>  
>      def test_photo_delete_works(self):
>          """Clicking the trash button must show the delete dialog."""
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        self.main_view.get_header().click_action_button("deleteButton")
>          self.get_delete_dialog()
>  
>          photo_viewer = self.photo_viewer.get_main_photo_viewer()
> @@ -157,7 +154,7 @@
>  
>      def test_nav_bar_album_picker_button(self):
>          """Clicking the album picker must show the picker dialog."""
> -        self.main_view.open_toolbar().click_button("addButton")
> +        self.main_view.get_header().click_action_button("addButton")
>          album_picker = self.photo_viewer.get_popup_album_picker()
>          self.assertThat(album_picker.visible, Eventually(Equals(True)))
>  
> @@ -219,7 +216,7 @@
>          self.media_view = self.app.select_single(MediaViewer)
>  
>      def click_edit_button(self):
> -        self.main_view.open_toolbar().click_button("editButton")
> +        self.main_view.get_header().click_action_button("editButton")
>          edit_dialog = self.photo_viewer.get_photo_edit_dialog()
>          self.assertThat(edit_dialog.visible, (Eventually(Equals(True))))
>          self.assertThat(edit_dialog.opacity, (Eventually(Equals(1))))
> @@ -281,7 +278,6 @@
>          self.assertThat(lambda: is_landscape(),
>                          Eventually(Equals(False)))
>  
> -        self.main_view.open_toolbar()
>          self.click_edit_button()
>          self.photo_viewer.click_undo_item()
>          self.media_view.ensure_spinner_not_running()
> @@ -291,7 +287,6 @@
>          self.assertThat(lambda: is_landscape(),
>                          Eventually(Equals(True)))
>  
> -        self.main_view.open_toolbar()
>          self.click_edit_button()
>          self.photo_viewer.click_redo_item()
>          self.media_view.ensure_spinner_not_running()
> @@ -301,10 +296,8 @@
>          is_landscape = opened_photo.paintedWidth > opened_photo.paintedHeight
>          self.assertThat(is_landscape, Equals(False))
>  
> -        self.main_view.open_toolbar()
>          self.click_edit_button()
>          self.photo_viewer.click_rotate_item()
> -        self.main_view.open_toolbar()
>          self.click_edit_button()
>          self.photo_viewer.click_revert_item()
>  
> 
> === modified file 'tests/autopilot/gallery_app/tests/test_photos_view.py'
> --- tests/autopilot/gallery_app/tests/test_photos_view.py	2014-05-20 20:59:52 +0000
> +++ tests/autopilot/gallery_app/tests/test_photos_view.py	2014-08-27 03:28:24 +0000
> @@ -12,6 +12,7 @@
>  from testtools import skipUnless
>  from autopilot.matchers import Eventually
>  from autopilot.platform import model
> +from autopilot.introspection.dbus import StateNotFoundError
>  
>  from gallery_app.tests import GalleryTestCase
>  from gallery_app.emulators.photos_view import PhotosView
> @@ -56,8 +57,16 @@
>          photo = self.photos_view.get_first_photo_in_photos_view()
>          self.click_item(photo)
>  
> +    def check_header_button_exist(self, button):
> +        header = self.main_view.get_header()
> +        buttonName = button + "_header_button"
> +        try:
> +            header.select_single(objectName=buttonName)
> +        except StateNotFoundError:
> +            return False
> +        return True
> +
>      def test_open_photo(self):
> -        self.main_view.close_toolbar()
>          self.click_first_photo()
>          sleep(5)
>          photo_viewer = self.photos_view.get_main_photo_viewer()
> @@ -69,13 +78,11 @@
>          photos_overview = self.app.select_single("PhotosOverview")
>          self.assertFalse(photos_overview.inSelectionMode)
>  
> -        self.main_view.open_toolbar().click_button("selectButton")
> +        self.main_view.get_header().click_action_button("selectButton")
>          self.assertTrue(photos_overview.inSelectionMode)
>  
> -        self.main_view.open_toolbar().click_custom_button("cancelButton")
> +        self.main_view.get_header().click_custom_back_button()
>  
> -        toolbar = self.main_view.get_toolbar()
> -        self.assertThat(toolbar.opened, Eventually(Equals(False)))
>          self.assertFalse(photos_overview.inSelectionMode)
>  
>          first_photo = self.photos_view.get_first_photo_in_photos_view()
> @@ -84,9 +91,9 @@
>  
>      def test_delete_photo_dialog_appears(self):
>          """Selecting a photo must make the delete button clickable."""
> -        self.main_view.open_toolbar().click_button("selectButton")
> +        self.main_view.get_header().click_action_button("selectButton")
>          self.click_first_photo()
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        self.main_view.get_header().click_action_button("deleteButton")
>  
>          self.assertThat(self.gallery_utils.delete_dialog_shown,
>                          Eventually(Is(True)))
> @@ -99,15 +106,13 @@
>      def test_delete_a_photo(self):
>          """Must be able to select a photo and use the dialog to delete it."""
>          number_of_photos = self.photos_view.number_of_photos()
> -        self.main_view.open_toolbar().click_button("selectButton")
> +        self.main_view.get_header().click_action_button("selectButton")
>          self.click_first_photo()
> -        self.main_view.open_toolbar().click_button("deleteButton")
> +        self.main_view.get_header().click_action_button("deleteButton")
>  
>          self.assertThat(self.gallery_utils.delete_dialog_shown,
>                          Eventually(Is(True)))
>  
> -        self.main_view.open_toolbar().click_button("deleteButton")
> -
>          delete_item = self.photos_view.get_delete_dialog_delete_button()
>          self.click_item(delete_item)
>          self.assertThat(
> @@ -157,13 +162,8 @@
>  
>      # Check if Camera Button is not visible at Desktop mode
>      def test_camera_button_visible(self):
> -        self.main_view.open_toolbar()
> -        toolbar = self.main_view.get_toolbar()
> -        cameraButton = toolbar.select_single(
> -            "ActionItem",
> -            objectName="cameraButton"
> -        )
> +        cameraButtonVisible = self.check_header_button_exist("cameraButton")
>          if model() == "Desktop":
> -            self.assertThat(cameraButton.visible, Equals(False))
> +            self.assertThat(cameraButtonVisible, Equals(False))
>          else:
> -            self.assertThat(cameraButton.visible, Equals(True))
> +            self.assertThat(cameraButtonVisible, Equals(True))
> 


-- 
https://code.launchpad.net/~artmello/gallery-app/gallery-app-new_header/+merge/231601
Your team Ubuntu Phablet Team is subscribed to branch lp:gallery-app.



More information about the Ubuntu-reviews mailing list