Cleaned unneeded TODO items
[harmattan/cameraplus] / qml / RecordingPage.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 import "data.js" as Data
28
29 // TODO: losing resources in the middle of recording will produce corrupted video
30 // TODO: optional resources?
31
32 CameraPage {
33         id: page
34         modesVisible: false
35         property bool error: false
36
37         policyMode: CameraResources.Recording
38
39         controlsVisible: cam.running && videoMode.recording && !cameraMode.animationRunning && !previewAnimationRunning && !error
40
41         orientationLock: PageOrientation.LockLandscape
42
43         function policyLost() {
44                 page.stopRecording();
45         }
46
47         function cameraError() {
48                 error = true;
49                 page.stopRecording();
50         }
51
52         Component.onDestruction: videoMode.stopRecording();
53
54         onStatusChanged: {
55                 if (page.status == PageStatus.Active) {
56                         startRecording();
57                 }
58         }
59
60         function startRecording() {
61                 if (!pipelineManager.acquired || pipelineManager.hijacked) {
62                         showError(qsTr("Failed to acquire needed resources."));
63                         pageStack.pop(undefined, true);
64                         return;
65                 }
66
67                 metaData.setMetaData();
68
69                 if (!mountProtector.lock()) {
70                         showError(qsTr("Failed to lock images directory."));
71                         pageStack.pop(undefined, true);
72                         return;
73                 }
74
75                 var file = fileNaming.videoFileName();
76                 var tmpFile = fileNaming.temporaryVideoFileName();
77
78                 if (!videoMode.startRecording(file, tmpFile)) {
79                         showError(qsTr("Failed to record video. Please restart the camera."));
80                         pageStack.pop(undefined, true);
81                         mountProtector.unlock();
82                 }
83
84                 trackerStore.storeVideo(file);
85         }
86
87         function stopRecording() {
88                 mountProtector.unlock();
89                 // Something is fishy here but if there is an error
90                 // and we use immediate mode then the page never gets destroyed.
91                 pageStack.pop(undefined, error ? false : true);
92         }
93
94         DisplayState {
95                 inhibitDim: true
96         }
97
98         onBatteryLow: {
99                 if (!checkBattery()) {
100                         page.stopRecording();
101                         showError(qsTr("Not enough battery to record video."));
102                 }
103         }
104
105         CaptureButton {
106                 id: recording
107                 anchors.right: parent.right
108                 anchors.rightMargin: 20
109                 anchors.verticalCenter: parent.verticalCenter
110                 iconSource: "image://theme/icon-m-camera-video-record"
111                 width: 75
112                 height: 75
113                 opacity: 0.5
114
115                 onClicked: page.stopRecording();
116                 visible: controlsVisible
117         }
118
119         Connections {
120                 target: Qt.application
121                 onActiveChanged: {
122                         if (!Qt.application.active) {
123                                 page.stopRecording();
124                         }
125                 }
126         }
127
128         VideoMode {
129                 id: videoMode
130                 camera: cam
131         }
132
133         Rectangle {
134                 anchors.top: parent.top
135                 anchors.topMargin: 20
136                 anchors.left: parent.left
137                 anchors.leftMargin: 20
138                 width: 48
139                 height: col.height
140                 color: "black"
141                 border.color: "gray"
142                 radius: 20
143                 opacity: 0.5
144                 visible: controlsVisible
145
146                 Column {
147                         id: col
148                         width: parent.width
149                         spacing: 5
150
151                         Indicator {
152                                 id: resolutionIndicator
153                                 source: "image://theme/" + Data.videoIcon(settings.videoResolution);
154                         }
155
156                         Indicator {
157                                 id: wbIndicator
158                                 source: visible ? "image://theme/" + Data.wbIcon(settings.videoWhiteBalance) + "-screen" : ""
159                                 visible: settings.videoWhiteBalance != WhiteBalance.Auto
160                         }
161
162                         Indicator {
163                                 id: cfIndicator
164                                 source: "image://theme/" + Data.cfIcon(settings.videoColorFilter) + "-screen"
165                                 visible: settings.videoColorFilter != ColorTone.Normal
166                         }
167
168                         Indicator {
169                                 id: gpsIndicator
170                                 visible: settings.useGps
171                                 source: "image://theme/icon-m-camera-location"
172
173                                 PropertyAnimation on opacity  {
174                                         easing.type: Easing.OutSine
175                                         loops: Animation.Infinite
176                                         from: 0.2
177                                         to: 1.0
178                                         duration: 1000
179                                         running: settings.useGps && !positionSource.position.longitudeValid
180                                         alwaysRunToEnd: true
181                                 }
182                         }
183                 }
184         }
185
186         Rectangle {
187                 anchors.bottom: parent.bottom
188                 anchors.right: parent.right
189                 anchors.rightMargin: 20
190                 anchors.bottomMargin: 20
191
192                 visible: controlsVisible
193
194                 color: "black"
195                 opacity: 0.5
196                 width: 100
197                 height: 30
198
199                 Timer {
200                         id: recordingDuration
201
202                         property int duration: 0
203
204                         running: videoMode.recording
205                         interval: 1000
206                         repeat: true
207
208                         onTriggered: {
209                                 duration = duration + 1;
210                                 if (duration == 3600) {
211                                         page.stopRecording();
212                                         showError(qsTr("Maximum recording time reached."));
213                                 }
214                                 else if (!checkDiskSpace()) {
215                                         page.stopRecording();
216                                         showError(qsTr("Not enough space to continue recording."));
217                                 }
218                         }
219                 }
220
221                 Image {
222                         id: recordingIcon
223                         source: "image://theme/icon-m-camera-ongoing-recording"
224                         width: 20
225                         height: 20
226                         anchors.verticalCenter: parent.verticalCenter
227                         anchors.left: parent.left
228                         anchors.leftMargin: 5
229                         sourceSize.width: 20
230                         sourceSize.height: 20
231                 }
232
233                 Label {
234                         function formatDuration(dur) {
235                                 var secs = parseInt(recordingDuration.duration);
236                                 var minutes = Math.floor(secs / 60);
237                                 var seconds = secs - (minutes * 60);
238
239                                 var date = new Date();
240                                 date.setSeconds(seconds);
241                                 date.setMinutes(minutes);
242                                 return Qt.formatTime(date, "mm:ss");
243                         }
244
245                         id: durationLabel
246                         text: formatDuration(recordingDuration.duration);
247                         anchors.left: recordingIcon.right
248                         anchors.leftMargin: 5
249                 }
250         }
251
252         CameraToolBar {
253                 id: toolBar
254                 anchors.bottom: parent.bottom
255                 anchors.bottomMargin: 20
256                 anchors.left: parent.left
257                 anchors.leftMargin: 20
258                 opacity: 0.5
259                 targetWidth: parent.width - (anchors.leftMargin * 2) - (66 * 1.5)
260                 visible: controlsVisible
261                 expanded: settings.showToolBar
262                 onExpandedChanged: settings.showToolBar = expanded;
263
264                 items: [
265                 VideoTorchButton {
266                         camera: cam
267                 },
268                 VideoEvCompButton {
269                         onClicked: toolBar.push(items);
270                 },
271                 VideoWhiteBalanceButton {
272                         onClicked: toolBar.push(items);
273                 },
274                 VideoColorFilterButton {
275                         onClicked: toolBar.push(items);
276                 },
277                 VideoMuteButton {
278                 },
279                 ToolIcon {
280                         iconSource: "image://theme/icon-m-toolbar-view-menu-white"
281                         onClicked: openFile("VideoSettingsPage.qml");
282                 }
283                 ]
284         }
285 }