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