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