Don't try to change the resolution while we are changing the device.
[harmattan/cameraplus] / qml / PostCaptureView.qml
1 // -*- qml -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 import QtQuick 2.0
24 import CameraPlus 1.0
25 import QtCamera 1.0
26
27 // TODO: qrc:/qml/PostCaptureView.qml:104:5: QML CameraToolBar: Binding loop detected for property "height"
28 // TODO: try to reload the preview thumbnail when the picture becomes available
29
30 Item {
31     id: postCaptureView
32
33     property Camera camera: null
34     property bool pressed: view.currentItem ? view.currentItem.playing : false
35     property int policyMode: view.currentItem && view.currentItem.playing ?
36         CameraResources.Player : settings.mode == Camera.VideoMode ? CameraResources.Video :
37         CameraResources.Image
38     property bool available: view.currentItem ? view.currentItem.itemData.available : false
39
40     Connections {
41         target: view.currentItem
42         onPlayingChanged: {
43             if (view.currentItem.playing) {
44                 hideTimer.running = false
45             }
46         }
47     }
48
49     ShareHelper {
50         id: share
51         settings: platformSettings
52     }
53
54     GalleryHelper {
55         id: gallery
56         settings: platformSettings
57     }
58
59     ListView {
60         id: view
61         anchors.fill: parent
62         snapMode: ListView.SnapOneItem
63         cacheBuffer: height * 3
64         model: postCaptureModel
65         highlightRangeMode: ListView.StrictlyEnforceRange
66         interactive: view.currentItem && view.currentItem.playing ? false : true
67
68         delegate: PostCaptureItem {
69             width: view.width
70             height: view.height
71             onClicked: hideTimer.running = !hideTimer.running
72         }
73
74         onFlickingChanged: {
75             if (flicking && hideTimer.running) {
76                 restartTimer()
77             }
78         }
79     }
80
81     property variant postCaptureModel: postCaptureModelLoader.item ?
82         postCaptureModelLoader.item.model : null
83     property bool loadModel: mainView.currentIndex == 2 && Qt.application.active
84
85     Loader {
86         id: postCaptureModelLoader
87         sourceComponent: loadModel ? postCaptureModelComponent : undefined
88     }
89
90     // We have to do it that way because Loader does not support non-visual elements.
91     Component {
92         id: postCaptureModelComponent
93
94         Item {
95             property alias model: postCaptureModel
96
97             PostCaptureModel {
98                 id: postCaptureModel
99                 manufacturer: deviceInfo.manufacturer
100                 model: deviceInfo.model
101                 Component.onCompleted: reload()
102                 onError: {
103                     console.log("Error populating model " + msg)
104                     showError(qsTr("Failed to load captures"))
105                 }
106             }
107         }
108     }
109
110     Timer {
111         id: hideTimer
112         running: false
113         interval: 3000
114     }
115
116     CameraToolBar {
117         id: toolBar
118         expanded: true
119         hideBack: true
120         anchors.bottom: parent.bottom
121         anchors.bottomMargin: show ? 20 : -1 * (height + 20)
122         anchors.left: parent.left
123         anchors.leftMargin: 20
124         anchors.right: parent.right
125         anchors.rightMargin: 20
126         opacity: 0.8
127
128         property bool show: deleteDialog.isOpen || deleteDialog.isOpening ||
129             hideTimer.running ||
130             (view.currentItem && view.currentItem.error) && !view.currentItem.playing
131
132         Behavior on anchors.bottomMargin {
133             PropertyAnimation { duration: view.currentItem && view.currentItem.playing ? 0 : 200 }
134         }
135
136         tools: CameraToolBarTools {
137             CameraToolIcon {
138                 iconSource: available && view.currentItem.itemData.favorite ? cameraTheme.favoriteMarkIconId : cameraTheme.favoriteUnmarkIconId
139                 opacity: available ? 1.0 : 0.4
140                 onClicked: {
141                     addOrRemoveFavorite()
142                     restartTimer()
143                 }
144             }
145
146             CameraToolIcon {
147                 iconSource: cameraTheme.shareIconId
148                 opacity: available ? 1.0 : 0.4
149                 onClicked: {
150                     shareCurrentItem()
151                     restartTimer()
152                 }
153             }
154
155             CameraToolIcon {
156                 iconSource: cameraTheme.deleteIconId
157                 opacity: available ? 1.0 : 0.4
158                 onClicked: {
159                     deleteCurrentItem()
160                     restartTimer()
161                 }
162             }
163
164             CameraToolIcon {
165                 iconSource: cameraTheme.galleryIconId
166                 onClicked: {
167                     launchGallery()
168                     restartTimer()
169                 }
170             }
171         }
172     }
173
174     CameraQueryDialog {
175         id: deleteDialog
176         titleText: qsTr("Delete item?");
177         acceptButtonText: qsTr("Yes");
178         rejectButtonText: qsTr("No");
179
180         onStatusChanged: restartTimer()
181
182         onAccepted: {
183             if (!remove.remove(view.currentItem.itemData.url)) {
184                 showError(qsTr("Failed to delete item"))
185             } else {
186                 postCaptureModel.remove(view.currentItem.itemData);
187             }
188         }
189
190         DeleteHelper {
191             id: remove
192         }
193     }
194
195     Rectangle {
196         opacity: toolBar.opacity
197         anchors.top: parent.top
198         anchors.topMargin: toolBar.show ? 20 : -1 * (height + 20)
199         anchors.left: parent.left
200         anchors.leftMargin: 20
201         anchors.right: parent.right
202         anchors.rightMargin: 20
203         visible: toolBar.visible
204         height: screen.isPortrait ? toolBar.height * 2 : toolBar.height
205         color: toolBar.color
206         border.color: toolBar.border.color
207         radius: toolBar.radius
208
209         Behavior on anchors.topMargin {
210             PropertyAnimation { duration: view.currentItem && view.currentItem.playing ? 0 : 200 }
211         }
212
213         Flow {
214             width: parent.width - 40
215             x: 20
216             height: parent.height
217
218             CameraLabel {
219                 text: view.currentItem ? view.currentItem.itemData.title : ""
220                 width: parent.width / 2
221                 height: parent.height
222                 font.bold: true
223                 verticalAlignment: Text.AlignVCenter
224                 horizontalAlignment: Text.AlignLeft
225             }
226
227             CameraLabel {
228                 text: view.currentItem ? view.currentItem.itemData.created : ""
229                 width: parent.width / 2
230                 height: parent.height
231                 font.bold: true
232                 verticalAlignment: Text.AlignVCenter
233                 horizontalAlignment: Text.AlignRight
234             }
235         }
236     }
237
238     function launchGallery() {
239         if (!gallery.launch()) {
240             showError(qsTr("Failed to launch gallery"))
241         }
242     }
243
244     function deleteCurrentItem() {
245         if (!available) {
246             return
247         }
248
249         deleteDialog.message = view.currentItem.itemData.fileName
250         deleteDialog.open()
251     }
252
253     function shareCurrentItem() {
254         if (!available) {
255             return
256         }
257
258         if (!share.share(view.currentItem.itemData.url)) {
259             showError(qsTr("Failed to launch share service"))
260         }
261     }
262
263     function addOrRemoveFavorite() {
264         if (!available) {
265             return
266         }
267
268         if (view.currentItem.itemData.favorite) {
269             if (!trackerStore.removeFromFavorites(view.currentItem.itemData.url)) {
270                 showError(qsTr("Failed to remove favorite"))
271             } else {
272                 view.currentItem.itemData.favorite = false
273             }
274         } else {
275             if (!trackerStore.addToFavorites(view.currentItem.itemData.url)) {
276                 showError(qsTr("Failed to add favorite"))
277             } else {
278                 view.currentItem.itemData.favorite = true
279             }
280         }
281     }
282
283     function restartTimer() {
284         hideTimer.restart()
285     }
286
287     function policyLost() {
288         if (view.currentItem && view.currentItem.playing) {
289             view.currentItem.stopPlayback()
290         }
291     }
292 }