9bd1e8ccdd7a89029f217876abf654f4aed0e905
[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: on error ?
30 // TODO: resources lost?
31 // TODO: closing camera in the middle of recording will hang camera
32 // TODO: optional resources?
33 // TODO: get touch focus settings from VideoPage
34
35 CameraPage {
36         id: page
37         modesVisible: false
38
39         Component.onDestruction: videoMode.stopRecording();
40
41         onStatusChanged: {
42                 if (page.status == PageStatus.Active) {
43                         startRecording();
44                 }
45         }
46
47         function startRecording() {
48                 if (!pipelineManager.acquired || pipelineManager.hijacked) {
49                         showError(qsTr("Failed to acquire needed resources."));
50                         pageStack.pop(undefined, true);
51                         return;
52                 }
53
54                 metaData.setMetaData();
55
56                 if (!mountProtector.lock()) {
57                         showError(qsTr("Failed to lock images directory."));
58                         pageStack.pop(undefined, true);
59                         return;
60                 }
61
62                 var file = fileNaming.videoFileName();
63                 var tmpFile = fileNaming.temporaryVideoFileName();
64
65                 if (!videoMode.startRecording(file, tmpFile)) {
66                         showError(qsTr("Failed to record video. Please restart the camera."));
67                         pageStack.pop(undefined, true);
68                         mountProtector.unlock();
69                 }
70
71                 // TODO: sometimes this fails (fast stop after start).
72                 trackerStore.storeVideo(file);
73         }
74
75         function stopRecording() {
76                 mountProtector.unlock();
77                 pageStack.pop(undefined, true);
78         }
79
80         policyMode: CameraResources.Recording
81
82         controlsVisible: cam.running && videoMode.recording && !cameraMode.animationRunning && !previewAnimationRunning && !standbyWidget.visible
83
84         orientationLock: PageOrientation.LockLandscape
85
86         DisplayState {
87                 inhibitDim: true
88         }
89
90         onBatteryLow: {
91                 if (!checkBattery()) {
92                         page.stopRecording();
93                         showError(qsTr("Not enough battery to record video."));
94                 }
95         }
96
97         CaptureButton {
98                 id: recording
99                 anchors.right: parent.right
100                 anchors.rightMargin: 20
101                 anchors.verticalCenter: parent.verticalCenter
102                 iconSource: "image://theme/icon-m-camera-video-record"
103                 width: 75
104                 height: 75
105                 opacity: 0.5
106
107                 onClicked: page.stopRecording();
108                 visible: controlsVisible
109         }
110
111         Connections {
112                 target: Qt.application
113                 onActiveChanged: {
114                         if (!Qt.application.active) {
115                                 page.stopRecording();
116                         }
117                 }
118         }
119
120         VideoMode {
121                 id: videoMode
122                 camera: cam
123         }
124
125         VideoTorchButton {
126                 id: torch
127                 camera: cam
128                 visible: controlsVisible
129                 anchors.top: parent.top
130                 anchors.left: parent.left
131                 anchors.topMargin: 20
132                 anchors.leftMargin: 20
133                 opacity: 0.5
134         }
135
136         VideoEvCompButton {
137                 id: evComp
138                 visible: controlsVisible
139                 anchors.top: torch.bottom
140                 anchors.left: parent.left
141                 anchors.topMargin: 10
142                 anchors.leftMargin: 20
143         }
144
145         Rectangle {
146                 anchors.left: parent.left
147                 anchors.bottom: parent.bottom
148                 anchors.leftMargin: 20
149                 anchors.bottomMargin: 20
150
151                 visible: controlsVisible
152
153                 color: "black"
154                 opacity: 0.5
155                 width: 100
156                 height: 30
157
158                 Timer {
159                         id: recordingDuration
160
161                         property int duration: 0
162
163                         running: videoMode.recording
164                         interval: 1000
165                         repeat: true
166
167                         onTriggered: {
168                                 duration = duration + 1;
169                                 if (duration == 3600) {
170                                         page.stopRecording();
171                                         showError(qsTr("Maximum recording time reached."));
172                                 }
173                                 else if (!checkDiskSpace()) {
174                                         page.stopRecording();
175                                         showError(qsTr("Not enough space to continue recording."));
176                                 }
177                         }
178                 }
179
180                 Image {
181                         id: recordingIcon
182                         source: "image://theme/icon-m-camera-ongoing-recording"
183                         width: 20
184                         height: 20
185                         anchors.verticalCenter: parent.verticalCenter
186                         anchors.left: parent.left
187                         anchors.leftMargin: 5
188                         sourceSize.width: 20
189                         sourceSize.height: 20
190                 }
191
192                 Label {
193                         function formatDuration(dur) {
194                                 var secs = parseInt(recordingDuration.duration);
195                                 var minutes = Math.floor(secs / 60);
196                                 var seconds = secs - (minutes * 60);
197
198                                 var date = new Date();
199                                 date.setSeconds(seconds);
200                                 date.setMinutes(minutes);
201                                 return Qt.formatTime(date, "mm:ss");
202                         }
203
204                         id: durationLabel
205                         text: formatDuration(recordingDuration.duration);
206                         anchors.left: recordingIcon.right
207                         anchors.leftMargin: 5
208                 }
209         }
210 }