Disable viewfinder in settings pages
[harmattan/cameraplus] / qml / main.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 com.nokia.extras 1.1
26 import QtCamera 1.0
27 import CameraPlus 1.0
28 import QtMobility.systeminfo 1.2
29 import QtMobility.location 1.2
30
31 // TODO: postcapture
32 // TODO: flash not ready (battery low or flash not ready message)
33 // TODO: portrait/landscape
34 // TODO: grid lines, face tracking
35 // TODO: select primary/secondary camera.
36 // TODO: disable debug builds.
37 // TODO: a way to get buffers to the application
38 // TODO: fcam like functionality (precise control over capture parameters).
39 // TODO: mute video sound
40
41 PageStackWindow {
42         id: root
43
44         property alias dimmer: camDimmer
45
46         showStatusBar: false
47
48         Component.onCompleted: {
49                 theme.inverted = true;
50                 // TODO: hardcoding device id
51                 root.resetCamera(0, settings.mode);
52         }
53
54         function showError(msg) {
55                 error.text = msg;
56                 error.show();
57         }
58
59         function resetCamera(deviceId, mode) {
60                 if (!cam.reset(deviceId, mode)) {
61                         showError(qsTr("Failed to set camera device and mode. Please restart the application."));
62                 }
63         }
64
65         PositionSource {
66                 // NOTE: The source will not reset the position when we lose the signal.
67                 // This shouldn't be a big problem as we are course enough.
68                 // If we ever need street level updates then this will be an issue.
69                 id: positionSource
70                 active: settings.useGps
71                 // TODO: we cannot bind to cam.running because camera will stop
72                 // when the connection dialog pops up and we end up with an infinite loop
73                 // active: cam.running && settings.useGps
74                 onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude);
75         }
76
77         MetaData {
78                 id: metaData
79                 camera: cam
80                 manufacturer: deviceInfo.manufacturer
81                 model: deviceInfo.model
82                 country: geocode.country
83                 city: geocode.city
84                 suburb: geocode.suburb
85                 longitude: positionSource.position.coordinate.longitude
86                 longitudeValid: positionSource.position.longitudeValid && settings.useGps
87                 latitude: positionSource.position.coordinate.latitude
88                 latitudeValid: positionSource.position.latitudeValid && settings.useGps
89                 elevation: positionSource.position.coordinate.altitude
90                 elevationValid: positionSource.position.altitudeValid && settings.useGps
91                 orientation: orientation.orientation
92                 artist: settings.creatorName
93                 captureDirection: compass.direction
94                 captureDirectionValid: compass.directionValid
95                 horizontalError: positionSource.position.horizontalAccuracy
96                 horizontalErrorValid: positionSource.position.horizontalAccuracyValid && settings.useGps
97                 dateTimeEnabled: true
98         }
99
100         Orientation {
101                 id: orientation
102                 active: cam.running
103         }
104
105         Compass {
106                 id: compass
107                 active: cam.running
108         }
109
110         ReverseGeocode {
111                 id: geocode
112                 active: cam.running && settings.useGps && settings.useGeotags
113         }
114
115         PipelineManager {
116                 id: pipelineManager
117                 camera: cam
118         }
119
120         DeviceInfo {
121                 id: deviceInfo
122         }
123
124         FSMonitor {
125                 id: fileSystem
126         }
127
128         InfoBanner {
129                 id: error
130         }
131
132         Settings {
133                 id: settings
134         }
135
136         FileNaming {
137                 id: fileNaming
138                 imageSuffix: cam.imageSuffix
139                 videoSuffix: cam.videoSuffix
140         }
141
142         MountProtector {
143                 id: mountProtector
144                 path: fileNaming.path
145         }
146
147         function replacePage(file) {
148                 pageStack.replace(Qt.resolvedUrl(file), {cam: cam}, true);
149         }
150
151         function openFile(file) {
152                 pageStack.push(Qt.resolvedUrl(file), {cam: cam});
153         }
154
155         function openFileNow(file) {
156                 pageStack.push(Qt.resolvedUrl(file), {cam: cam}, true);
157         }
158
159         platformStyle: PageStackWindowStyle {
160                 cornersVisible: false
161                 background: ""
162                 backgroundColor: "transparent"
163         }
164
165         ImageSettings {
166                 id: imageSettings
167                 camera: cam
168                 function setImageResolution() {
169                         if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
170                                 showError(qsTr("Failed to set required resolution"));
171                         }
172                 }
173
174                 onReadyChanged: {
175                         if (ready) {
176                                 imageSettings.setImageResolution();
177                         }
178                 }
179         }
180
181         VideoSettings {
182                 id: videoSettings
183                 camera: cam
184
185                 function setVideoResolution() {
186                         if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
187                                 showError(qsTr("Failed to set required resolution"));
188                         }
189                 }
190
191                 onReadyChanged: {
192                         if (ready) {
193                                 videoSettings.setVideoResolution();
194                         }
195                 }
196         }
197
198         Connections {
199                 target: settings
200
201                 onImageAspectRatioChanged: {
202                         imageSettings.setImageResolution();
203                 }
204
205                 onImageResolutionChanged: {
206                         imageSettings.setImageResolution();
207                 }
208
209                 onVideoResolutionChanged: {
210                         videoSettings.setVideoResolution();
211                 }
212         }
213
214         Camera {
215                 id: cam
216                 anchors.fill: parent
217
218                 FocusReticle {
219                         id: focusReticle
220                         cam: cam
221                         visible: pageStack.currentPage && pageStack.currentPage.controlsVisible && pageStack.currentPage.focusReticleVisible && cam && cam.autoFocus.canFocus(cam.scene.value);
222                         cafStatus: cam ? cam.autoFocus.cafStatus : -1
223                         status: cam ? cam.autoFocus.status : -1
224         }
225
226 /*
227                 onDeviceIdChanged: {
228                         // TODO: is this needed ?
229                         if (platformWindow.active) {
230                                 cam.start();
231                         }
232                 }
233 */
234                 onError: {
235                         if (pipelineManager.error) {
236                                 // Ignore any subsequent errors.
237                                 // Killing pulseaudio while recording will lead to an
238                                 // infinite supply of errors which will break the UI
239                                 // if we show a banner for each.
240                                 return;
241                         }
242
243                         pipelineManager.error = true;
244                         pageStack.currentPage.cameraError();
245                         console.log("Camera error (" + code + "): " + message + " " + debug);
246                         showError(qsTr("Camera error. Please restart the application."));
247
248                         // We cannot stop camera here. Seems there is a race condition somewhere
249                         // which leads to a freeze if we do so.
250                 }
251
252                 onRunningChanged: {
253                         if (!cam.running) {
254                                 mountProtector.unlock();
255                         }
256                 }
257
258                 Component.onDestruction: cam.stop();
259
260                 // We need to show viewfinder below pages.
261                 z: -1
262
263                 Rectangle {
264                         id: camDimmer
265                         z: 1
266                         anchors.fill: parent
267                         opacity: 0
268                         color: "black"
269                 }
270
271                 notifications: Sounds {
272                         id: sounds
273                         mute: !settings.soundEnabled
274                 }
275
276         }
277
278         Binding {
279                 target: cam.flash
280                 property: "value"
281                 when: cam.mode == Camera.ImageMode
282                 value: settings.imageFlashMode
283         }
284
285         Binding {
286                 target: settings
287                 property: "imageFlashMode"
288                 when: cam.mode == Camera.ImageMode
289                 value: cam.flash.value
290         }
291
292         Binding {
293                 target: cam.scene
294                 property: "value"
295                 when: cam.mode == Camera.VideoMode
296                 value: settings.videoSceneMode
297         }
298
299         Binding {
300                 target: cam.scene
301                 property: "value"
302                 when: cam.mode == Camera.ImageMode
303                 value: settings.imageSceneMode
304         }
305
306         Binding {
307                 target: cam.evComp
308                 property: "value"
309                 when: cam.mode == Camera.ImageMode
310                 value: settings.imageEvComp
311         }
312
313         Binding {
314                 target: cam.evComp
315                 property: "value"
316                 when: cam.mode == Camera.VideoMode
317                 value: settings.videoEvComp
318         }
319
320         Binding {
321                 target: settings
322                 property: "imageEvComp"
323                 when: cam.mode == Camera.ImageMode
324                 value: cam.evComp.value
325         }
326
327         Binding {
328                 target: settings
329                 property: "videoEvComp"
330                 when: cam.mode == Camera.VideoMode
331                 value: cam.evComp.value
332         }
333
334         Binding {
335                 target: cam.whiteBalance
336                 property: "value"
337                 when: cam.mode == Camera.ImageMode
338                 value: settings.imageWhiteBalance
339         }
340
341         Binding {
342                 target: cam.whiteBalance
343                 property: "value"
344                 when: cam.mode == Camera.VideoMode
345                 value: settings.videoWhiteBalance
346         }
347
348         Binding {
349                 target: cam.colorTone
350                 property: "value"
351                 when: cam.mode == Camera.ImageMode
352                 value: settings.imageColorFilter
353         }
354
355         Binding {
356                 target: cam.colorTone
357                 property: "value"
358                 when: cam.mode == Camera.VideoMode
359                 value: settings.videoColorFilter
360         }
361
362         Binding {
363                 target: cam.iso
364                 property: "value"
365                 when: cam.mode == Camera.ImageMode
366                 value: settings.imageIso
367         }
368
369         Binding {
370                 target: settings
371                 property: "imageIso"
372                 when: cam.mode == Camera.ImageMode
373                 value: cam.iso.value
374         }
375
376         TrackerStore {
377                 id: trackerStore
378                 active: cam.running
379                 manufacturer: deviceInfo.manufacturer
380                 model: deviceInfo.model
381         }
382
383         ModeController {
384                 id: cameraMode
385                 cam: cam
386                 dimmer: root.dimmer
387         }
388
389         Connections {
390                 target: cam
391                 onModeChanged: {
392                         if (cam.mode == Camera.VideoMode) {
393                                 replacePage("VideoPage.qml");
394                         }
395                         else {
396                                 replacePage("ImagePage.qml");
397                         }
398                 }
399         }
400 }