// -*- qml -*-
+
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
import QtQuick 1.1
import com.nokia.meego 1.1
+import com.nokia.extras 1.1
import QtCamera 1.0
+import CameraPlus 1.0
+import QtMobility.systeminfo 1.2
+import QtMobility.location 1.2
+
+// TODO: postcapture
+// TODO: flash not ready
+// TODO: focus, caf, ...
+// TODO: portrait/landscape
+// TODO: stop viewfinder in settings pages ?
+// TODO: grid lines, face tracking, ambr
+// TODO: complete settings pages
+// TODO: select primary/secondary camera.
+// TODO: disable debug builds.
+// TODO: a way to get buffers to the application
+// TODO: fcam like functionality (precise control over capture parameters).
+// TODO: mute video sound
PageStackWindow {
id: root
property alias dimmer: camDimmer
showStatusBar: false
- Component.onCompleted: theme.inverted = true;
- // Stolen from https://qt.gitorious.org/qt-components/qt-components/blobs/master/examples/meego/QmlComponentGallery/qml/ListPage.qml
+ Component.onCompleted: {
+ theme.inverted = true;
+ // TODO: hardcoding device id
+ root.resetCamera(0, settings.mode);
+ }
+
+ function showError(msg) {
+ error.text = msg;
+ error.show();
+ }
+
+ function resetCamera(deviceId, mode) {
+ if (!cam.reset(deviceId, mode)) {
+ showError(qsTr("Failed to set camera device and mode. Please restart the application."));
+ }
+ }
+
+ PositionSource {
+ // NOTE: The source will not reset the position when we lose the signal.
+ // This shouldn't be a big problem as we are course enough.
+ // If we ever need street level updates then this will be an issue.
+ id: positionSource
+ active: settings.useGps
+ // TODO: we cannot bind to cam.running because camera will stop
+ // when the connection dialog pops up and we end up with an infinite loop
+ // active: cam.running && settings.useGps
+ onPositionChanged: geocode.search(position.coordinate.longitude, position.coordinate.latitude);
+ }
+
+ MetaData {
+ id: metaData
+ camera: cam
+ manufacturer: deviceInfo.manufacturer
+ model: deviceInfo.model
+ country: geocode.country
+ city: geocode.city
+ suburb: geocode.suburb
+ longitude: positionSource.position.coordinate.longitude
+ longitudeValid: positionSource.position.longitudeValid && settings.useGps
+ latitude: positionSource.position.coordinate.latitude
+ latitudeValid: positionSource.position.latitudeValid && settings.useGps
+ elevation: positionSource.position.coordinate.altitude
+ elevationValid: positionSource.position.altitudeValid && settings.useGps
+ orientation: orientation.orientation
+ artist: settings.creatorName
+ captureDirection: compass.direction
+ captureDirectionValid: compass.directionValid
+ horizontalError: positionSource.position.horizontalAccuracy
+ horizontalErrorValid: positionSource.position.horizontalAccuracyValid && settings.useGps
+ dateTimeEnabled: true
+ }
+
+ Orientation {
+ id: orientation
+ active: cam.running
+ }
+
+ Compass {
+ id: compass
+ active: cam.running
+ }
+
+ ReverseGeocode {
+ id: geocode
+ active: cam.running && settings.useGps && settings.useGeotags
+ }
+
+ CameraResources {
+ id: resourcePolicy
+ }
+
+ DeviceInfo {
+ id: deviceInfo
+ }
+
+ FSMonitor {
+ id: fileSystem
+ }
+
+ InfoBanner {
+ id: error
+ }
+
+ Settings {
+ id: settings
+ }
+
+ FileNaming {
+ id: fileNaming
+ imageSuffix: cam.imageSuffix
+ videoSuffix: cam.videoSuffix
+ }
+
+ MountProtector {
+ id: mountProtector
+ path: fileNaming.path
+ }
+
function replacePage(file) {
- var component = Qt.createComponent(file)
+ pageStack.replace(Qt.resolvedUrl(file), {cam: cam}, true);
+ }
- if (component.status == Component.Ready) {
- pageStack.replace(component, {cam: cam}, true);
+ function openFile(file) {
+ pageStack.push(Qt.resolvedUrl(file), {cam: cam});
+ }
+
+ platformStyle: PageStackWindowStyle {
+ // TODO: Hack
+ background: " "
+ }
+
+ ImageSettings {
+ id: imageSettings
+ camera: cam
+ function setImageResolution() {
+ if (!imageSettings.setResolution(settings.imageAspectRatio, settings.imageResolution)) {
+ showError(qsTr("Failed to set required resolution"));
+ }
}
- else {
- console.log("Error loading component:", component.errorString());
+
+ onReadyChanged: {
+ if (ready) {
+ imageSettings.setImageResolution();
+ }
}
}
- function openFile(file) {
- var component = Qt.createComponent(file)
+ VideoSettings {
+ id: videoSettings
+ camera: cam
- if (component.status == Component.Ready) {
- pageStack.push(component);
+ function setVideoResolution() {
+ if (!videoSettings.setResolution(settings.videoAspectRatio, settings.videoResolution)) {
+ showError(qsTr("Failed to set required resolution"));
+ }
}
- else {
- console.log("Error loading component:", component.errorString());
+
+ onReadyChanged: {
+ if (ready) {
+ videoSettings.setVideoResolution();
+ }
}
}
- platformStyle: PageStackWindowStyle {
- // TODO: Hack
- background: " "
- portraitBackground: " "
- landscapeBackground: " "
+ Connections {
+ target: settings
+
+ onImageAspectRatioChanged: {
+ imageSettings.setImageResolution();
+ }
+
+ onImageResolutionChanged: {
+ imageSettings.setImageResolution();
+ }
+
+ onVideoResolutionChanged: {
+ videoSettings.setVideoResolution();
+ }
}
Camera {
- onDeviceIdChanged: cam.start();
-
+/*
+ onDeviceIdChanged: {
+ // TODO: is this needed ?
+ if (platformWindow.active) {
+ cam.start();
+ }
+ }
+*/
id: cam
anchors.fill: parent
- // TODO: hardcoding
- Component.onCompleted: { cam.deviceId = 0; }
+ onError: {
+ console.log("Camera error (" + code + "): " + message + " " + debug);
+ showError(qsTr("Camera error. Please restart the application."));
+ cam.stop();
+ resourcePolicy.acquire(CameraResources.None);
+ mountProtector.unlock();
+ }
+
+ onRunningChanged: {
+ if (!cam.running) {
+ mountProtector.unlock();
+ }
+ }
+
+ Component.onDestruction: cam.stop();
// TODO: Hack
z: -1
opacity: 0
color: "black"
}
+
+ notifications: Sounds {
+ id: sounds
+ mute: !settings.soundEnabled
+ }
+
+ }
+
+ Binding {
+ target: cam.flash
+ property: "value"
+ when: cam.mode == Camera.ImageMode
+ value: settings.imageFlashMode
+ }
+
+ Binding {
+ target: settings
+ property: "imageFlashMode"
+ when: cam.mode == Camera.ImageMode
+ value: cam.flash.value
+ }
+
+ Binding {
+ target: cam.scene
+ property: "value"
+ when: cam.mode == Camera.VideoMode
+ value: settings.videoSceneMode
+ }
+
+ Binding {
+ target: cam.scene
+ property: "value"
+ when: cam.mode == Camera.ImageMode
+ value: settings.imageSceneMode
+ }
+
+ Binding {
+ target: cam.evComp
+ property: "value"
+ when: cam.mode == Camera.ImageMode
+ value: settings.imageEvComp
+ }
+
+ Binding {
+ target: cam.evComp
+ property: "value"
+ when: cam.mode == Camera.VideoMode
+ value: settings.videoEvComp
+ }
+
+ Binding {
+ target: settings
+ property: "imageEvComp"
+ when: cam.mode == Camera.ImageMode
+ value: cam.evComp.value
+ }
+
+ Binding {
+ target: settings
+ property: "videoEvComp"
+ when: cam.mode == Camera.VideoMode
+ value: cam.evComp.value
+ }
+
+ Binding {
+ target: cam.whiteBalance
+ property: "value"
+ when: cam.mode == Camera.ImageMode
+ value: settings.imageWhiteBalance
+ }
+
+ Binding {
+ target: cam.whiteBalance
+ property: "value"
+ when: cam.mode == Camera.VideoMode
+ value: settings.videoWhiteBalance
+ }
+
+ Binding {
+ target: cam.colorTone
+ property: "value"
+ when: cam.mode == Camera.ImageMode
+ value: settings.imageColorFilter
+ }
+
+ Binding {
+ target: cam.colorTone
+ property: "value"
+ when: cam.mode == Camera.VideoMode
+ value: settings.videoColorFilter
+ }
+
+ Binding {
+ target: cam.iso
+ property: "value"
+ when: cam.mode == Camera.ImageMode
+ value: settings.imageIso
+ }
+
+ Binding {
+ target: settings
+ property: "imageIso"
+ when: cam.mode == Camera.ImageMode
+ value: cam.iso.value
}
ModeController {
}
}
}
-
- Button {
- text: "select camera"
- anchors.left: parent.left
- anchors.bottom: parent.bottom
- onClicked: sel.open();
- }
-
- SelectionDialog {
- id: sel
- titleText: "Select camera";
- // http://forum.meego.com/showthread.php?t=3873
- selectedIndex: 0
- model: ListModel { id: model }
-
- onAccepted: cam.deviceId = cam.deviceId = selectedIndex;
-
- function populate() {
- var n = cam.deviceCount;
- var x;
- for (x = 0; x < n; x++) {
- var nm = cam.deviceName(x);
- console.log(nm);
- model.append({"name": nm});
- }
- }
-
- Component.onCompleted: populate();
- }
-
-
- // TODO: hardcoding
- initialPage: ImagePage { cam: cam }
}