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