Indented
[harmattan/cameraplus] / qml / main.qml
1 // -*- qml -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012-2013 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_QT_QUICK@
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.location 1.2
29
30 // TODO: flash not ready (battery low or flash not ready message)
31
32 Window {
33     id: root
34     property alias camera: cam
35
36     VisualItemModel {
37         id: mainModel
38
39         SettingsView {
40             width: mainView.width
41             height: mainView.height
42         }
43
44         CameraView {
45             id: cam
46             width: mainView.width
47             height: mainView.height
48         }
49
50         PostCaptureView {
51             width: mainView.width
52             height: mainView.height
53         }
54     }
55
56     ListView {
57         id: mainView
58         LayoutMirroring.enabled: false
59         anchors.fill: parent
60         orientation: ListView.Horizontal
61         model: mainModel
62         snapMode: ListView.SnapOneItem
63         highlightRangeMode: ListView.StrictlyEnforceRange
64         boundsBehavior: Flickable.StopAtBounds
65         currentIndex: 1
66         interactive: !currentItem.pressed
67     }
68
69     Component.onCompleted: {
70         screen.setAllowedOrientations(Screen.Landscape)
71         theme.inverted = true
72         platformSettings.init()        
73         // TODO: hardcoding device id
74         root.resetCamera(0, settings.mode)
75     }
76
77     PlatformSettings {
78         id: platformSettings
79     }
80
81     Settings {
82         id: settings
83     }
84
85     PipelineManager {
86         id: pipelineManager
87         camera: cam
88         currentItem: mainView.currentItem
89     }
90
91     function resetCamera(deviceId, mode) {
92         if (!cam.reset(deviceId, mode)) {
93             showError(qsTr("Failed to set camera device and mode. Please restart the application."))
94         }
95     }
96
97     function showError(msg) {
98         error.text = msg
99         error.show()
100     }
101
102     property alias dimmer: camDimmer
103
104     PageStack {
105         id: pageStack
106         anchors.fill: parent
107     }
108
109     MouseArea {
110         anchors.fill: parent
111         enabled: pageStack.busy
112     }
113
114     PositionSource {
115         // NOTE: The source will not reset the position when we lose the signal.
116         // This shouldn't be a big problem as we are course enough.
117         // If we ever need street level updates then this will be an issue.
118         id: positionSource
119         active: settings.useGps
120         // TODO: we cannot bind to cam.running because camera will stop
121         // when the connection dialog pops up and we end up with an infinite loop
122         // active: cam.running && settings.useGps
123         onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude)
124     }
125
126     MetaData {
127         id: metaData
128         camera: cam
129         manufacturer: deviceInfo.manufacturer
130         model: deviceInfo.model
131         country: geocode.country
132         city: geocode.city
133         suburb: geocode.suburb
134         longitude: positionSource.position.coordinate.longitude
135         longitudeValid: positionSource.position.longitudeValid && settings.useGps
136         latitude: positionSource.position.coordinate.latitude
137         latitudeValid: positionSource.position.latitudeValid && settings.useGps
138         elevation: positionSource.position.coordinate.altitude
139         elevationValid: positionSource.position.altitudeValid && settings.useGps
140         orientation: orientation.orientation
141         artist: settings.creatorName
142         captureDirection: compass.direction
143         captureDirectionValid: compass.directionValid
144         horizontalError: positionSource.position.horizontalAccuracy
145         horizontalErrorValid: positionSource.position.horizontalAccuracyValid && settings.useGps
146         dateTimeEnabled: true
147     }
148
149     Orientation {
150         id: orientation
151         active: cam.running || (mainView.currentIndex == 2 && Qt.application.active)
152     }
153
154     Compass {
155         id: compass
156         active: cam.running
157     }
158
159     ReverseGeocode {
160         id: geocode
161         active: cam.running && settings.useGps && settings.useGeotags
162     }
163
164     DeviceInfo {
165         id: deviceInfo
166     }
167
168     FSMonitor {
169         id: fileSystem
170     }
171
172     InfoBanner {
173         id: error
174     }
175
176     FileNaming {
177         id: fileNaming
178         imageSuffix: cam.imageSuffix
179         videoSuffix: cam.videoSuffix
180     }
181
182     MountProtector {
183         id: mountProtector
184         path: fileNaming.path
185     }
186
187     TrackerStore {
188         id: trackerStore
189         active: cam.running
190         manufacturer: deviceInfo.manufacturer
191         model: deviceInfo.model
192     }
193
194     function checkDiskSpace() {
195         return fileSystem.hasFreeSpace(fileNaming.path)
196     }
197
198     ImageSettings {
199         id: imageSettings
200         camera: cam
201         function setImageResolution() {
202             if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
203                 showError(qsTr("Failed to set required resolution"))
204             }
205         }
206
207         onReadyChanged: {
208             if (ready) {
209                 imageSettings.setImageResolution()
210             }
211         }
212     }
213
214     VideoSettings {
215         id: videoSettings
216         camera: cam
217
218         function setVideoResolution() {
219             if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
220                 showError(qsTr("Failed to set required resolution"))
221             }
222         }
223
224         onReadyChanged: {
225             if (ready) {
226                 videoSettings.setVideoResolution()
227             }
228         }
229     }
230
231     Connections {
232         target: settings
233
234         onImageAspectRatioChanged: {
235             imageSettings.setImageResolution()
236         }
237
238         onImageResolutionChanged: {
239             imageSettings.setImageResolution()
240         }
241
242         onVideoResolutionChanged: {
243             videoSettings.setVideoResolution()
244         }
245     }
246
247     ModeController {
248         id: cameraMode
249         cam: cam
250         dimmer: root.dimmer
251     }
252
253     Rectangle {
254         property bool dimmed: false
255         id: camDimmer
256         z: 1
257         anchors.fill: parent
258         opacity: dimmed ? 1.0 : 0.0
259         color: "black"
260         Behavior on opacity {
261             PropertyAnimation { duration: 150 }
262         }
263     }
264
265     DeviceKeys {
266         id: keys
267         active: Qt.application.active && pipelineManager.scaleAcquired
268         repeat: !settings.zoomAsShutter
269     }
270
271     Standby {
272         policyLost: pipelineManager.state == "policyLost"
273         show: !Qt.application.active || pipelineManager.showStandBy ||
274             (mainView.currentIndex == 1 && !camera.running)
275     }
276 }