84d0b745e05d8b4abc8e7ecf2c6a1744c59847ad
[harmattan/cameraplus] / qml / PostCapturePage.qml
1 // -*- qml -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012 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 1.1
24 import com.nokia.meego 1.1
25 import QtCamera 1.0
26 import CameraPlus 1.0
27
28 // TODO: losing resources while playback won't show an error
29
30 CameraPage {
31         id: page
32
33         controlsVisible: false
34         policyMode: CameraResources.PostCapture
35         needsPipeline: false
36         standbyVisible: !Qt.application.active
37
38         property Item currentItem: null
39         property bool available: currentItem ? currentItem.itemData.available : false
40
41         Component.onCompleted: postCaptureModel.reload();
42
43         function launchGallery() {
44                 if (!gallery.launch()) {
45                         showError(qsTr("Failed to launch gallery"));
46                 }
47         }
48
49         function showInGallery() {
50                 if (!available) {
51                         return;
52                 }
53
54                 if (!gallery.show(currentItem.itemUrl)) {
55                         showError(qsTr("Failed to launch gallery"));
56                 }
57         }
58
59         Menu {
60                 id: menu
61                 onStatusChanged: page.restartTimer();
62
63                 MenuLayout {
64                         MenuItem {text: qsTr("Captures in gallery"); onClicked: launchGallery(); }
65                         MenuItem {text: qsTr("View in gallery"); enabled: available; onClicked: showInGallery(); }
66                 }
67         }
68
69         function deleteCurrentItem() {
70                 if (!available) {
71                         return;
72                 }
73
74                 deleteDialog.message = currentItem.itemData.fileName;
75                 deleteDialog.open();
76         }
77
78         QueryDialog {
79                 id: deleteDialog
80                 titleText: qsTr("Delete item?");
81                 acceptButtonText: qsTr("Yes");
82                 rejectButtonText: qsTr("No");
83
84                 onStatusChanged: page.restartTimer();
85
86                 onAccepted: {
87                         if (!remove.remove(currentItem.itemData.url)) {
88                                 showError(qsTr("Failed to delete item"));
89                         }
90                         else {
91                                 postCaptureModel.remove(currentItem.itemData);
92                         }
93                 }
94
95                 DeleteHelper {
96                         id: remove
97                 }
98         }
99
100         function shareCurrentItem() {
101                 if (!available) {
102                         return;
103                 }
104
105                 if (!share.share(currentItem.itemData.url)) {
106                                 showError(qsTr("Failed to launch share service"));
107                 }
108         }
109
110         function addOrRemoveFavorite() {
111                 if (!available) {
112                         return;
113                 }
114
115                 if (currentItem.itemData.favorite) {
116                         if (!trackerStore.removeFromFavorites(currentItem.itemData.url)) {
117                                 showError(qsTr("Failed to remove favorite"));
118                         }
119                         else {
120                                 currentItem.itemData.favorite = false;
121                         }
122                 }
123                 else {
124                         if (!trackerStore.addToFavorites(currentItem.itemData.url)) {
125                                 showError(qsTr("Failed to add favorite"));
126                         }
127                         else {
128                                 currentItem.itemData.favorite = true;
129                         }
130                 }
131         }
132
133         ShareHelper {
134                 id: share
135         }
136
137         GalleryHelper {
138                 id: gallery
139         }
140
141         Rectangle {
142                 color: "black"
143                 anchors.fill: parent
144         }
145
146         PathView {
147                 id: view
148                 anchors.fill: parent
149
150                 path: Path {
151                         startX: - view.width
152                         startY: view.height / 2
153                         PathLine { x: view.width * 2; y: view.height / 2 }
154                 }
155
156                 // Insanely high value to prevent panning multiple images
157                 flickDeceleration: 999999
158
159                 preferredHighlightBegin: 0.5
160                 preferredHighlightEnd: 0.5
161                 highlightRangeMode: PathView.StrictlyEnforceRange
162                 pathItemCount: 3
163
164                 model: PostCaptureModel {
165                         id: postCaptureModel
166                         manufacturer: deviceInfo.manufacturer
167                         model: deviceInfo.model
168                         onError: {
169                                 console.log("Error populating model " + msg);
170                                 showError(qsTr("Failed to load captures"));
171                         }
172                 }
173
174                 Label {
175                         // TODO: Hide this when we have no items
176                         text: qsTr("No captures available");
177                         anchors.centerIn: parent
178                         font.pixelSize: 36
179                         visible: currentItem == null
180                 }
181
182                 delegate: PostCaptureItem {
183                         width: view.width
184                         height: view.height
185                         onClicked: hideTimer.running = !hideTimer.running;
186                 }
187         }
188
189         function restartTimer() {
190                 hideTimer.running = true;
191         }
192
193         Timer {
194                 id: hideTimer
195                 running: false
196                 interval: 3000
197         }
198
199         CameraToolBar {
200                 id: toolBar
201                 expanded: true
202                 manualBack: true
203                 anchors.bottom: parent.bottom
204                 anchors.bottomMargin: show ? 20 : -1 * (height + 20)
205                 anchors.left: parent.left
206                 anchors.leftMargin: 20
207                 opacity: 0.8
208
209                 property bool show: deleteDialog.status == DialogStatus.Open || deleteDialog.status == DialogStatus.Opening || hideTimer.running || menu.status == DialogStatus.Open || menu.status == DialogStatus.Opening || (currentItem && currentItem.error)
210
211                 onClicked: pageStack.pop();
212
213                 Behavior on anchors.bottomMargin {
214                         PropertyAnimation { duration: 200; }
215                 }
216
217                 items: [
218                         ToolIcon { iconId: !available ? "icon-m-toolbar-favorite-mark-dimmed-white" : currentItem.itemData.favorite ? "icon-m-toolbar-favorite-mark-white" : "icon-m-toolbar-favorite-unmark-white"; onClicked: { addOrRemoveFavorite(); page.restartTimer(); } },
219                         ToolIcon { iconId: available ? "icon-m-toolbar-share-white" : "icon-m-toolbar-share-dimmed-white"; onClicked: { shareCurrentItem(); page.restartTimer(); } },
220                         ToolIcon { iconId: available ? "icon-m-toolbar-delete-white" : "icon-m-toolbar-delete-dimmed-white"; onClicked: { deleteCurrentItem(); page.restartTimer(); } },
221                         ToolIcon { iconId: "icon-m-toolbar-view-menu-white"; onClicked: { menu.open(); page.restartTimer(); } }
222                 ]
223         }
224
225         Rectangle {
226                 opacity: toolBar.opacity
227                 anchors.top: parent.top
228                 anchors.topMargin: toolBar.show ? 20 : -1 * (height + 20)
229                 anchors.left: parent.left
230                 anchors.leftMargin: 20
231                 anchors.right: parent.right
232                 anchors.rightMargin: 20
233                 visible: toolBar.visible
234                 height: toolBar.height
235                 color: toolBar.color
236                 border.color: toolBar.border.color
237                 radius: toolBar.radius
238
239                 Behavior on anchors.topMargin {
240                         PropertyAnimation { duration: 200; }
241                 }
242
243                 Label {
244                         text: currentItem ? currentItem.itemData.title : ""
245                         anchors.top: parent.top
246                         anchors.bottom: parent.bottom
247                         anchors.left: parent.left
248                         anchors.leftMargin: 20
249                         font.bold: true
250                         verticalAlignment: Text.AlignVCenter
251                 }
252
253                 Label {
254                         text: currentItem ? currentItem.itemData.created : ""
255                         font.bold: true
256                         anchors.top: parent.top
257                         anchors.bottom: parent.bottom
258                         anchors.right: parent.right
259                         anchors.rightMargin: 20
260                         verticalAlignment: Text.AlignVCenter
261                 }
262         }
263 }