8bbd1d4b89cffbe6d85523ad1f92ca594b56e2a2
[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 Item {
30     id: postCaptureView
31
32     property Camera camera: null
33     property bool pressed: view.currentItem ? view.currentItem.playing : false
34     property int policyMode: view.currentItem && view.currentItem.playing ?
35         CameraResources.Player : settings.mode == Camera.VideoMode ? CameraResources.Video :
36         CameraResources.Image
37     property bool available: view.currentItem ? view.currentItem.itemData.available : false
38
39     Connections {
40         target: view.currentItem
41         onPlayingChanged: {
42             if (view.currentItem.playing) {
43                 hideTimer.running = false
44             }
45         }
46     }
47
48     ShareHelper {
49         id: share
50         settings: platformSettings
51     }
52
53     GalleryHelper {
54         id: gallery
55         settings: platformSettings
56     }
57
58     ListView {
59         id: view
60         anchors.fill: parent
61         snapMode: ListView.SnapOneItem
62         cacheBuffer: height * 3
63         model: postCaptureModel
64         highlightRangeMode: ListView.StrictlyEnforceRange
65         interactive: view.currentItem && view.currentItem.playing ? false : true
66
67         delegate: PostCaptureItem {
68             width: view.width
69             height: view.height
70             onClicked: hideTimer.running = !hideTimer.running
71         }
72
73         onFlickingChanged: {
74             if (flicking && hideTimer.running) {
75                 restartTimer()
76             }
77         }
78     }
79
80     property variant postCaptureModel: postCaptureModelLoader.item ?
81         postCaptureModelLoader.item.model : null
82     property bool loadModel: mainView.currentIndex == 2 && Qt.application.active
83
84     Loader {
85         id: postCaptureModelLoader
86         sourceComponent: loadModel ? postCaptureModelComponent : undefined
87     }
88
89     // We have to do it that way because Loader does not support non-visual elements.
90     Component {
91         id: postCaptureModelComponent
92
93         Item {
94             property alias model: postCaptureModel
95
96             PostCaptureModel {
97                 id: postCaptureModel
98                 manufacturer: deviceInfo.manufacturer
99                 model: deviceInfo.model
100                 Component.onCompleted: reload()
101                 onError: {
102                     console.log("Error populating model " + msg)
103                     showError(qsTr("Failed to load captures"))
104                 }
105             }
106         }
107     }
108
109     Timer {
110         id: hideTimer
111         running: false
112         interval: 3000
113     }
114
115     CameraToolBar {
116         id: toolBar
117         expanded: true
118         hideBack: true
119         anchors.bottom: parent.bottom
120         anchors.bottomMargin: show ? 20 : -1 * (height + 20)
121         anchors.left: parent.left
122         anchors.leftMargin: 20
123         anchors.right: parent.right
124         anchors.rightMargin: 20
125         opacity: 0.8
126
127         property bool show: deleteDialog.isOpen || deleteDialog.isOpening ||
128             hideTimer.running || menu.isOpen || menu.isOpening ||
129             (view.currentItem && view.currentItem.error) && !view.currentItem.playing
130
131         Behavior on anchors.bottomMargin {
132             PropertyAnimation { duration: view.currentItem && view.currentItem.playing ? 0 : 200 }
133         }
134
135         tools: CameraToolBarTools {
136             CameraToolIcon {
137                 iconId: available && view.currentItem.itemData.favorite ? cameraTheme.favoriteMarkIconId : cameraTheme.favoriteUnmarkIconId
138                 opacity: available ? 1.0 : 0.4
139                 onClicked: {
140                     addOrRemoveFavorite()
141                     restartTimer()
142                 }
143             }
144
145             CameraToolIcon {
146                 iconId: cameraTheme.shareIconId
147                 opacity: available ? 1.0 : 0.4
148                 onClicked: {
149                     shareCurrentItem()
150                     restartTimer()
151                 }
152             }
153
154             CameraToolIcon {
155                 iconId: cameraTheme.deleteIconId
156                 opacity: available ? 1.0 : 0.4
157                 onClicked: {
158                     deleteCurrentItem()
159                     restartTimer()
160                 }
161             }
162
163             CameraToolIcon {
164                 iconId: cameraTheme.menuIconId
165                 onClicked: {
166                     menu.open()
167                     restartTimer()
168                 }
169             }
170         }
171     }
172
173     CameraQueryDialog {
174         id: deleteDialog
175         titleText: qsTr("Delete item?");
176         acceptButtonText: qsTr("Yes");
177         rejectButtonText: qsTr("No");
178
179         onStatusChanged: restartTimer()
180
181         onAccepted: {
182             if (!remove.remove(view.currentItem.itemData.url)) {
183                 showError(qsTr("Failed to delete item"))
184             } else {
185                 postCaptureModel.remove(view.currentItem.itemData);
186             }
187         }
188
189         DeleteHelper {
190             id: remove
191         }
192     }
193
194     CameraMenu {
195         id: menu
196         onStatusChanged: restartTimer()
197
198         actions: [
199             CameraMenuAction {
200                 text: qsTr("Captures in gallery")
201                 onClicked: launchGallery()
202             },
203             CameraMenuAction {
204                 // TODO: this is not working...
205                 text: qsTr("View in gallery")
206                 enabled: available
207                 onClicked: showInGallery()
208             }
209         ]
210     }
211
212     Rectangle {
213         opacity: toolBar.opacity
214         anchors.top: parent.top
215         anchors.topMargin: toolBar.show ? 20 : -1 * (height + 20)
216         anchors.left: parent.left
217         anchors.leftMargin: 20
218         anchors.right: parent.right
219         anchors.rightMargin: 20
220         visible: toolBar.visible
221         height: screen.isPortrait ? toolBar.height * 2 : toolBar.height
222         color: toolBar.color
223         border.color: toolBar.border.color
224         radius: toolBar.radius
225
226         Behavior on anchors.topMargin {
227             PropertyAnimation { duration: view.currentItem && view.currentItem.playing ? 0 : 200 }
228         }
229
230         Flow {
231             width: parent.width - 40
232             x: 20
233             height: parent.height
234
235             CameraLabel {
236                 text: view.currentItem ? view.currentItem.itemData.title : ""
237                 width: parent.width / 2
238                 height: parent.height
239                 font.bold: true
240                 verticalAlignment: Text.AlignVCenter
241                 horizontalAlignment: Text.AlignLeft
242             }
243
244             CameraLabel {
245                 text: view.currentItem ? view.currentItem.itemData.created : ""
246                 width: parent.width / 2
247                 height: parent.height
248                 font.bold: true
249                 verticalAlignment: Text.AlignVCenter
250                 horizontalAlignment: Text.AlignRight
251             }
252         }
253     }
254
255     function launchGallery() {
256         if (!gallery.launch()) {
257             showError(qsTr("Failed to launch gallery"))
258         }
259     }
260
261     function showInGallery() {
262         if (!available) {
263             return
264         }
265
266         if (!gallery.show(view.currentItem.itemUrl)) {
267             showError(qsTr("Failed to launch gallery"))
268         }
269     }
270
271     function deleteCurrentItem() {
272         if (!available) {
273             return
274         }
275
276         deleteDialog.message = view.currentItem.itemData.fileName
277         deleteDialog.open()
278     }
279
280     function shareCurrentItem() {
281         if (!available) {
282             return
283         }
284
285         if (!share.share(view.currentItem.itemData.url)) {
286             showError(qsTr("Failed to launch share service"))
287         }
288     }
289
290     function addOrRemoveFavorite() {
291         if (!available) {
292             return
293         }
294
295         if (view.currentItem.itemData.favorite) {
296             if (!trackerStore.removeFromFavorites(view.currentItem.itemData.url)) {
297                 showError(qsTr("Failed to remove favorite"))
298             } else {
299                 view.currentItem.itemData.favorite = false
300             }
301         } else {
302             if (!trackerStore.addToFavorites(view.currentItem.itemData.url)) {
303                 showError(qsTr("Failed to add favorite"))
304             } else {
305                 view.currentItem.itemData.favorite = true
306             }
307         }
308     }
309
310     function restartTimer() {
311         hideTimer.restart()
312     }
313
314     function policyLost() {
315         if (view.currentItem && view.currentItem.playing) {
316             view.currentItem.stopPlayback()
317         }
318     }
319 }