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