Added a note about PositionSource not resetting the position when we lose the signal
[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: battery low state
33 // TODO: disk space
34 // TODO: flash not ready
35 // TODO: focus, caf, ...
36 // TODO: portrait/landscape
37 // TODO: record video in a hidden directory and then copy the video to avoid tracker indexing it.
38 // TODO: stop viewfinder in settings pages ?
39 // TODO: prevent going to mass storage while recording and capturing
40 // TODO: grid lines, face tracking, ambr
41 // TODO: complete settings pages
42 // TODO: stop camera properly when we get closed.
43 // TODO: select primary/secondary camera.
44 // TODO: disable debug builds.
45 // TODO: a way to get buffers to the application
46 // TODO: fcam like functionality (precise control over capture parameters).
47
48 PageStackWindow {
49         id: root
50
51         property alias dimmer: camDimmer
52
53         showStatusBar: false
54
55         Component.onCompleted: {
56                 theme.inverted = true;
57                 if (settings.mode == 0) {
58                         openFile("ImagePage.qml");
59                 }
60                 else {
61                         openFile("VideoPage.qml");
62                 }
63         }
64
65         function showError(msg) {
66                 error.text = msg;
67                 error.show();
68         }
69
70         PositionSource {
71                 // NOTE: The source will not reset the position when we lose the signal.
72                 // This shouldn't be a big problem as we are course enough.
73                 // If we ever need street level updates then this will be an issue.
74                 id: positionSource
75                 active: settings.useGps
76                 // TODO: we cannot bind to cam.running because camera will stop
77                 // when the connection dialog pops up and we end up with an infinite loop
78                 // active: cam.running && settings.useGps
79                 onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude);
80         }
81
82         MetaData {
83                 id: metaData
84                 camera: cam
85                 manufacturer: deviceInfo.manufacturer
86                 model: deviceInfo.model
87                 country: geocode.country
88                 city: geocode.city
89                 suburb: geocode.suburb
90                 longitude: positionSource.position.coordinate.longitude
91                 longitudeValid: positionSource.position.longitudeValid && settings.useGps
92                 latitude: positionSource.position.coordinate.latitude
93                 latitudeValid: positionSource.position.latitudeValid && settings.useGps
94                 elevation: positionSource.position.coordinate.altitude
95                 elevationValid: positionSource.position.altitudeValid && settings.useGps
96                 orientation: orientation.orientation
97                 artist: settings.creatorName
98                 captureDirection: compass.direction
99                 captureDirectionValid: compass.directionValid
100                 horizontalError: positionSource.position.horizontalAccuracy
101                 horizontalErrorValid: positionSource.position.horizontalAccuracyValid && settings.useGps
102                 dateTimeEnabled: true
103         }
104
105         Orientation {
106                 id: orientation
107                 active: cam.running
108         }
109
110         Compass {
111                 id: compass
112                 active: cam.running
113         }
114
115         ReverseGeocode {
116                 id: geocode
117                 active: cam.running && settings.useGps && settings.useGeotags
118         }
119
120         CameraResources {
121                 id: resourcePolicy
122                 onAcquiredChanged: {
123                         if (resourcePolicy.acquired) {
124                                 // TODO:
125                         }
126                         else {
127                                 // TODO: We need a way to force a stop.
128                         }
129                 }
130         }
131
132         DeviceInfo {
133                 id: deviceInfo
134         }
135
136         FSMonitor {
137                 id: fileSystem
138         }
139
140         InfoBanner {
141                 id: error
142         }
143
144         Settings {
145                 id: settings
146         }
147
148         FileNaming {
149                 id: fileNaming
150                 imageSuffix: cam.imageSuffix
151                 videoSuffix: cam.videoSuffix
152         }
153
154         function replacePage(file) {
155                 pageStack.replace(Qt.resolvedUrl(file), {cam: cam}, true);
156         }
157
158         function openFile(file) {
159                 pageStack.push(Qt.resolvedUrl(file), {cam: cam});
160         }
161
162         platformStyle: PageStackWindowStyle {
163                 // TODO: Hack
164                 background: " "
165         }
166
167         ImageSettings {
168                 id: imageSettings
169                 camera: cam
170                 function setImageResolution() {
171                         if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
172                                 showError(qsTr("Failed to set required resolution"));
173                         }
174                 }
175
176                 onReadyChanged: {
177                         if (ready) {
178                                 imageSettings.setImageResolution();
179                         }
180                 }
181         }
182
183         VideoSettings {
184                 id: videoSettings
185                 camera: cam
186
187                 function setVideoResolution() {
188                         if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
189                                 showError(qsTr("Failed to set required resolution"));
190                         }
191                 }
192
193                 onReadyChanged: {
194                         if (ready) {
195                                 videoSettings.setVideoResolution();
196                         }
197                 }
198         }
199
200         Connections {
201                 target: settings
202
203                 onImageAspectRatioChanged: {
204                         imageSettings.setImageResolution();
205                 }
206
207                 onImageResolutionChanged: {
208                         imageSettings.setImageResolution();
209                 }
210
211                 onVideoResolutionChanged: {
212                         videoSettings.setVideoResolution();
213                 }
214         }
215
216         Camera {
217 /*
218                 onDeviceIdChanged: {
219                         // TODO: is this needed ?
220                         if (platformWindow.active) {
221                                 cam.start();
222                         }
223                 }
224 */
225                 id: cam
226                 anchors.fill: parent
227
228                 onError: {
229                         console.log("Camera error (" + code + "): " + message + " " + debug);
230                         showError(qsTr("Camera error. Please restart the application."));
231                         cam.stop();
232                 }
233
234                 // TODO: hardcoding device id
235                 Component.onCompleted: { cam.deviceId = 0; mode = settings.mode; }
236                 Component.onDestruction: {
237                 console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
238                 }
239
240                 // TODO: Hack
241                 z: -1
242
243                 Rectangle {
244                         id: camDimmer
245                         z: 1
246                         anchors.fill: parent
247                         opacity: 0
248                         color: "black"
249                 }
250
251                 notifications: Sounds {
252                         id: sounds
253                         mute: !settings.soundEnabled
254                 }
255         }
256
257         Scene {
258                 id: sceneController
259                 camera: cam
260                 value: ready ? camera.mode == Camera.VideoMode ? settings.videoSceneMode : settings.imageSceneMode : 0
261         }
262
263         ColorTone {
264                 id: colorToneController
265                 camera: cam
266                 value: ready ? camera.mode == Camera.VideoMode ? settings.videoColorFilter : settings.imageColorFilter : 0
267         }
268
269         WhiteBalance {
270                 id: whiteBalanceController
271                 camera: cam
272                 value: ready ? camera.mode == Camera.VideoMode ? settings.videoWhiteBalance : settings.imageWhiteBalance : 0
273         }
274
275         ModeController {
276                 id: cameraMode
277                 cam: cam
278                 dimmer: root.dimmer
279         }
280
281         Iso {
282                 id: iso
283                 camera: cam
284                 value: ready ? settings.imageIso : 0
285         }
286
287         Connections {
288                 target: cam
289                 onModeChanged: {
290                         if (cam.mode == Camera.VideoMode) {
291                                 replacePage("VideoPage.qml");
292                         }
293                         else {
294                                 replacePage("ImagePage.qml");
295                         }
296                 }
297         }
298 }