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