...
 
Commits (118)
<?xml version='1.0' encoding='utf-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.kde.camera"
android:versionName="0.0.1"
android:versionCode="1"
android:installLocation="auto">
<uses-permission android:name="android.permission.CAMERA" />
<application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Plasma Camera">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="Plasma Camera"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="plasma-camera"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<meta-data android:name="android.app.extract_android_style" android:value="minimal"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Splash screen -->
<!-- <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/> -->
<!-- Background running -->
<meta-data android:name="android.app.background_running" android:value="false"/>
<!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="true"/>
</activity>
</application>
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
</manifest>
project(plasma-camera)
cmake_minimum_required(VERSION 2.8.12)
set(KF5_MIN_VERSION "5.18.0")
set(QT_MIN_VERSION "5.5.0")
################# Disallow in-source build #################
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "This application requires an out of source build. Please create a separate build directory.")
endif()
# Make CPack available to easy generate binary packages
include(CPack)
include(FeatureSummary)
find_package(PkgConfig)
################# set KDE specific information #################
......@@ -13,17 +22,39 @@ find_package(ECM 0.0.8 REQUIRED NO_MODULE)
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
include(ECMSetupVersion)
include(ECMGenerateHeaders)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(ECMPoQmTools)
include(KDECompilerSettings NO_POLICY_SCOPE)
set(KF5_VERSION "5.22.0")
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui Svg QuickControls2)
if(ANDROID)
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS AndroidExtras)
endif()
# find_package(Qt5 REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Kirigami2 CoreAddons I18n)
################# Enable C++11 features for clang and gcc #################
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++0x")
endif()
################# now find all used packages #################
set (QT_MIN_VERSION "5.6.0")
find_package(PkgConfig)
#########################################################################
set (QT_MIN_VERSION "5.9.0")
find_package(KF5Kirigami2 REQUIRED)
find_package(KF5 REQUIRED COMPONENTS
Package)
add_subdirectory(src)
kpackage_install_package(package org.kde.phone.camera genericqml)
install(FILES package/metadata.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} RENAME org.kde.phone.camera.desktop)
install(PROGRAMS org.kde.mobile.camera.desktop DESTINATION ${KDE_INSTALL_APPDIR})
install(FILES org.kde.mobile.camera.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
This diff is collapsed.
# call xgettext on all source files. If your sources have other filename
# extensions besides .cc, .cpp, and .h, just add them in the find call.
$XGETTEXT $(find . -name \*.cc -o -name \*.cpp -o -name \*.h -o -name \*.qml) -o $podir/plasma-camera.pot
This diff is collapsed.
[Desktop Entry]
Comment=
Encoding=UTF-8
Keywords=
Name=Camera
Name[ca]=Càmera
Name[ca@valencia]=Càmera
Name[cs]=Fotoaparát
Name[de]=Kamera
Name[el]=Κάμερα
Name[en_GB]=Camera
Name[es]=Cámara
Name[et]=Kaamera
Name[eu]=Kamera
Name[fi]=Kamera
Name[fr]=Appareil photo
Name[gl]=Cámara
Name[ia]=Camera
Name[it]=Camera
Name[ko]=카메라
Name[lt]=Kamera
Name[nl]=Camera
Name[nn]=Kamera
Name[pl]=Aparat
Name[pt]=Câmara
Name[pt_BR]=Câmera
Name[ru]=Камера
Name[sk]=Fotoaparát
Name[sv]=Kamera
Name[uk]=Фотоапарат
Name[x-test]=xxCameraxx
Name[zh_TW]=相機
GenericName=Mobile Photos
GenericName[ca]=Fotos del mòbil
GenericName[ca@valencia]=Fotos del mòbil
GenericName[cs]=Mobilní fotografie
GenericName[el]=Φωτογραφίες από κινητό
GenericName[en_GB]=Mobile Photos
GenericName[es]=Fotos del móvil
GenericName[et]=Mobiili fotod
GenericName[eu]=Mugikorreko argazkiak
GenericName[fi]=Mobiilikuvat
GenericName[fr]=Photos mobiles
GenericName[gl]=Fotos móbiles
GenericName[ia]=Photos de Mobile
GenericName[it]=Foto per mobile
GenericName[ko]=모바일 사진
GenericName[lt]=Mobiliosios nuotraukos
GenericName[nl]=Foto's op mobiel
GenericName[nn]=Mobilfoto
GenericName[pl]=Przenośne zdjęcia
GenericName[pt]=Fotografias do Telemóvel
GenericName[pt_BR]=Fotos do celular
GenericName[ru]=Мобильные фотографии
GenericName[sk]=Mobilné fotky
GenericName[sv]=Mobilfoton
GenericName[uk]=Фотографії з телефону
GenericName[x-test]=xxMobile Photosxx
GenericName[zh_TW]=行動照片
Type=Application
Icon=camera-photo
Exec=plasma-camera
Categories=Qt;KDE;AudioVideo;
{
"id": "org.kde.mobile.camera",
"runtime": "org.kde.Platform",
"runtime-version": "5.14",
"sdk": "org.kde.Sdk",
"command": "plasma-camera",
"tags": ["nightly"],
"desktop-file-name-suffix": " (Nightly)",
"finish-args": [
"--share=ipc",
"--share=network",
"--socket=x11",
"--socket=wayland",
"--device=all",
"--filesystem=home"
],
"separate-locales": false,
"modules": [
{
"name": "gst-plugins-bad",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"-Ddisable_gtkdoc=true"
],
"sources": [
{
"type": "archive",
"url": "https://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-1.16.1.tar.xz",
"sha256": "56481c95339b8985af13bac19b18bc8da7118c2a7d9440ed70e7dcd799c2adb5"
}
],
"cleanup": [
"/include",
"/lib/*.la",
"/lib/gstreamer-1.0/*.la",
"/lib/gstreamer-1.0/include",
"/lib/pkgconfig",
"/share/gtk-doc"
]
},
{
"name": "plasma-camera",
"buildsystem": "cmake-ninja",
"builddir": true,
"sources": [ { "type": "dir", "path": ".", "skip": [".git"] } ]
}
]
}
/* File generated by QtCreator */
import QmlProject 1.0
Project {
/* Include .qml, .js, and image files from current directory and subdirectories */
QmlFiles {
directory: "."
}
JavaScriptFiles {
directory: "."
}
ImageFiles {
directory: "."
}
/* List of plugin directories passed to QML runtime */
// importPaths: [ "../exampleplugin" ]
}
[Dolphin]
Timestamp=2015,7,15,15,36,31
Version=3
[Desktop Entry]
Comment=
Encoding=UTF-8
Keywords=
Name=Camera
Type=Application
Icon=camera-photo
Exec=kpackagelauncherqml -a org.kde.phone.camera
X-KDE-ParentApp=
X-KDE-PluginInfo-Author=Marco Martin
X-KDE-PluginInfo-Category=Miscellaneous
X-KDE-PluginInfo-Email=mart@kde.org
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Name=org.kde.phone.camera
X-KDE-PluginInfo-Version=
X-KDE-PluginInfo-Website=
X-KDE-ServiceTypes=KPackage/GenericQML
X-Plasma-MainScript=ui/main.qml
X-Plasma-RemoteLocation=
set(plasma-camera_SRCS
main.cpp
)
qt5_add_resources(RESOURCES resources.qrc)
add_executable(plasma-camera ${plasma-camera_SRCS} ${RESOURCES})
target_link_libraries(plasma-camera Qt5::Core Qt5::Qml Qt5::Quick Qt5::Svg KF5::CoreAddons KF5::I18n)
if(ANDROID)
target_link_libraries(plasma-camera Qt5::AndroidExtras Qt5::Svg KF5::Kirigami2)
kirigami_package_breeze_icons(ICONS
emblem-videos-symbolic
camera-photo-symbolic
dialog-error-symbolic
media-playback-start
media-playback-stop
alarm-symbolic
camera-photo
ratiocrop
whitebalance
clock
help-about
)
endif()
install(TARGETS plasma-camera ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2017-2018 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.1 as Controls
import org.kde.kirigami 2.6 as Kirigami
Kirigami.AboutPage {
aboutData: cameraAboutData
globalToolBarStyle: Kirigami.Settings.isMobile ? Kirigami.ApplicationHeaderStyle.Breadcrumb : Kirigami.ApplicationHeaderStyle.ToolBar
contextualActions: [
Kirigami.Action {
text: "Close"
onTriggered: pageStack.pop()
}
]
}
/****************************************************************************
**
** Copyright (C) 2018 Jonah Brüchert
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import org.kde.kirigami 2.0 as Kirigami
import QtQuick 2.7
import QtMultimedia 5.8
Kirigami.GlobalDrawer {
id: drawer
property var camera
Component {
id: devicesSubAction
Kirigami.Action {
property string value
checked: value === settings.cameraDeviceId
onTriggered: {
settings.cameraDeviceId = value
}
}
}
Component {
id: resolutionSubAction
Kirigami.Action {
property size value
checked: value === settings.resolution
onTriggered: {
settings.resolution = value
}
}
}
actions: [
Kirigami.Action {
id: devicesAction
text: i18n("Camera")
iconName: "camera-photo-symbolic"
Component.onCompleted: {
var cameras = QtMultimedia.availableCameras
var childrenList = []
for (var i in cameras) {
childrenList[i] = devicesSubAction.createObject(devicesAction, {
value: cameras[i].deviceId,
text: "%1".arg(cameras[i].displayName)
})
devicesAction.children = childrenList
}
}
},
Kirigami.Action {
id: resolutionAction
text: i18n("Resolution")
iconName: "ratiocrop"
Component.onCompleted: {
var resolutions = drawer.camera.imageCapture.supportedResolutions
var childrenList = []
for (var i in resolutions) {
var pixels = resolutions[i].width * resolutions[i].height
var megapixels = Math.round(pixels / 10000) / 100
childrenList[i] = resolutionSubAction.createObject(resolutionAction, {
value: resolutions[i],
text: "%1 x %2 (%3 MP)".arg(resolutions[i].width).arg(resolutions[i].height).arg(megapixels)
})
resolutionAction.children = childrenList
}
}
},
Kirigami.Action {
id: wbaction
text: i18n("White balance")
iconName: "whitebalance"
Kirigami.Action {
iconName: "qrc:///camera_auto_mode.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceAuto
text: i18n("Auto")
checked: settings.whiteBalanceMode === CameraImageProcessing.WhiteBalanceAuto
}
Kirigami.Action {
iconName: "qrc:///camera_white_balance_sunny.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceSunlight
text: i18n("Sunlight")
checked: settings.whiteBalanceMode === CameraImageProcessing.WhiteBalanceSunlight
}
Kirigami.Action {
iconName: "qrc:///camera_white_balance_cloudy.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceCloudy
text: i18n("Cloudy")
checked: settings.whiteBalanceMode === CameraImageProcessing.WhiteBalanceCloudy
}
Kirigami.Action {
iconName: "qrc:///camera_white_balance_incandescent.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceTungsten
text: i18n("Tungsten")
checked: settings.whiteBalanceMode === CameraImageProcessing.WhiteBalanceTungsten
}
Kirigami.Action {
iconName: "qrc:///camera_white_balance_flourescent.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceFluorescent
text: i18n("Fluorescent")
checked: settings.whiteBalanceMode === CameraImageProcessing.WhiteBalanceFluorescent
}
},
Kirigami.Action {
text: i18n("Self-timer")
iconName: "clock"
enabled: !camera.selfTimerRunning
Kirigami.Action {
text: i18n("Off")
onTriggered: camera.selfTimerDuration = 0
checked: camera.selfTimerDuration === 0
}
Kirigami.Action {
text: i18n("2 s")
onTriggered: camera.selfTimerDuration = 2
checked: camera.selfTimerDuration === 2
}
Kirigami.Action {
text: i18n("5 s")
onTriggered: camera.selfTimerDuration = 5
checked: camera.selfTimerDuration === 5
}
Kirigami.Action {
text: i18n("10 s")
onTriggered: camera.selfTimerDuration = 10
checked: camera.selfTimerDuration === 10
}
Kirigami.Action {
text: i18n("20 s")
onTriggered: camera.selfTimerDuration = 20
checked: camera.selfTimerDuration === 20
}
},
Kirigami.Action {
text: i18n("About")
iconName: "help-about"
onTriggered: {
while (pageStack.depth > 1)
pageStack.pop()
pageStack.push(aboutPage)
}
}
]
}
import QtQuick 2.7
import QtMultimedia 5.8
import QtQuick.Controls.Material 2.0
import QtQuick.Controls 2.0 as Controls
import org.kde.kirigami 2.4 as Kirigami
import QtGraphicalEffects 1.0
Rectangle {
id: preview
property var imageCapture
property var videoRecorder
property bool showVideoPreview: false // when set to true, the preview for the videoRecorder is shown, if false for the imageCapture
property bool videoThumbnailRequested: false
visible: ((imageCapture.capturedImagePath && !showVideoPreview) || (videoRecorder.actualLocation && showVideoPreview)) && !(videoRecorder.recorderStatus === CameraRecorder.RecordingStatus)
width: Kirigami.Units.gridUnit * 6
height: width
layer.enabled: preview.enabled
layer.effect: DropShadow {
color: Material.dropShadowColor
samples: 30
spread: 0.5
}
Component.onCompleted: {
videoRecorder.recorderStatusChanged.connect(createVideoThumbnail)
}
function setPhotoPreview() {
showVideoPreview = false
}
function setVideoPreview() {
videoThumbnailRequested = true
showVideoPreview = true
}
function createVideoThumbnail() {
if (videoThumbnailRequested && !(videoRecorder.recorderStatus === CameraRecorder.FinalizingStatus)) {
video.source = videoRecorder.actualLocation
video.play()
video.pause()
videoThumbnailRequested = false
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if (showVideoPreview) {
Qt.openUrlExternally(videoRecorder.actualLocation)
}
else {
Qt.openUrlExternally("file://" + imageCapture.capturedImagePath)
}
}
}
Image {
visible: !showVideoPreview
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
source: imageCapture.capturedImagePath ? "file://" + imageCapture.capturedImagePath : ""
}
Rectangle {
visible: showVideoPreview
anchors.fill: parent
color: "grey"
Video {
id: video
anchors.fill: parent
muted: true
fillMode: VideoOutput.PreserveAspectCrop
}
Controls.BusyIndicator {
id: thumbnailBusyIdicator
visible: (videoRecorder.recorderStatus === CameraRecorder.FinalizingStatus)
Kirigami.Theme.textColor: "white"
anchors.fill: parent
layer.enabled: thumbnailBusyIdicator.enabled
layer.effect: DropShadow {
color: Material.dropShadowColor
samples: 30
spread: 0.5
}
}
Kirigami.Icon {
id: playbackIcon
visible: !thumbnailBusyIdicator.visible
source: "media-playback-start"
color: "white"
width: parent.width * 0.75
height: width
anchors.centerIn: parent
layer.enabled: playbackIcon.enabled
layer.effect: DropShadow {
color: Material.dropShadowColor
samples: 30
spread: 0.5
}
}
}
}
/****************************************************************************
**
** Copyright (C) 2018 Jonah Brüchert
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
......@@ -37,75 +38,82 @@
**
****************************************************************************/
import QtQuick 2.0
import org.kde.kirigami 2.0 as Kirigami
import QtQuick 2.7
import QtQml.Models 2.2
import QtMultimedia 5.8
import QtMultimedia 5.0
Kirigami.GlobalDrawer {
actions: [
Kirigami.Action {
text: qsTr("Camera")
iconName: "camera-photo"
DelegateModel {
model: QtMultimedia.availableCameras
delegate: Kirigami.Action {
text: model.displayName
onTriggered: settings.cameraDeviceId = model.deviceId
}
}
},
Kirigami.Action {
text: qsTr("Video resolution")
iconName: "ratiocrop"
DelegateModel {
model: CameraRecorder.supportedResolutions
Item {
id : zoomControl
property real currentZoom: 1
property real maximumZoom: 1
signal zoomTo(real value)
delegate: Kirigami.Action {
text: model
onTriggered: settings.videoResolution = text;
}
}
},
Kirigami.Action {
text: qsTr("Photo resolution")
iconName: "ratiocrop"
DelegateModel {
model: CameraCapture.supportedResolutions
delegate: Kirigami.Action {
text: model
onTriggered: settings.photoResolution = text;
}
}
},
Kirigami.Action {
text: qsTr("White balance")
iconName: "whitebalance"
Kirigami.Action {
iconName: "images/camera_auto_mode.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceAuto
text: qsTr("Auto")
}
Kirigami.Action {
iconName: "images/camera_white_balance_sunny.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceSunlight
text: qsTr("Sunlight")
}
Kirigami.Action {
iconName: "images/camera_white_balance_cloudy.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceCloudy
text: qsTr("Cloudy")
}
Kirigami.Action {
iconName: "images/camera_white_balance_incandescent.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceTungsten
text: qsTr("Tungsten")
visible: zoomControl.maximumZoom > 1
MouseArea {
id : mouseArea
anchors.fill: parent
property real initialZoom: 0
property real initialPos: 0
onPressed: {
initialPos = mouseY
initialZoom = zoomControl.currentZoom
}
onPositionChanged: {
if (pressed) {
var target = initialZoom * Math.pow(5, (initialPos-mouseY)/zoomControl.height);
target = Math.max(1, Math.min(target, zoomControl.maximumZoom))
zoomControl.zoomTo(target)
}
Kirigami.Action {
iconName: "images/camera_white_balance_flourescent.png"
onTriggered: settings.whiteBalanceMode = CameraImageProcessing.WhiteBalanceFluorescent
text: qsTr("Fluorescent")
}
}
Item {
id : bar
x : 16
y : parent.height/4
width : 24
height : parent.height/2
Rectangle {
anchors.fill: parent
smooth: true
radius: 8
border.color: "white"
border.width: 2
color: "black"
opacity: 0.3
}
Rectangle {
id: groove
x : 0
y : parent.height * (1.0 - (zoomControl.currentZoom-1.0) / (zoomControl.maximumZoom-1.0))
width: parent.width
height: parent.height - y
smooth: true
radius: Kirigami.Units.gridUnit * 0.5
color: "white"
opacity: 0.5
}
Text {
id: zoomText
anchors {
right: bar.left
rightMargin: Kirigami.Units.gridUnit * 1
}
y: Math.min(parent.height - height, Math.max(0, groove.y - height / 2))
text: "x" + Math.round(zoomControl.currentZoom * 100) / 100
font.bold: true
color: "white"
style: Text.Raised; styleColor: "black"
opacity: 0.85
font.pixelSize: Kirigami.Units.gridUnit
}
]
}
}
......@@ -43,21 +43,62 @@ import Qt.labs.settings 1.0
import QtMultimedia 5.8
Kirigami.ApplicationWindow {
id: root
Settings {
id: settings
// Default settings
property size videoResolution: Qt.size(640, 480)
property size photoResolution
property int cameraDeviceId
property int whiteBalanceMode: CameraImageProcessing.WhiteBalanceAuto
property size resolution
property string cameraDeviceId
property int cameraPosition
property int whiteBalanceMode
}
Component {id: cameraPage; CameraPage {}}
Component {
id: cameraPage
id: root
title: qsTr("Camera")
globalDrawer: GlobalDrawer {}
CameraPage {
camera: mainCamera
}
}
Component {
id: aboutPage
AboutPage {}
}
Camera {
id: mainCamera
captureMode: Camera.CaptureStillImage
deviceId: settings.cameraDeviceId
imageProcessing.whiteBalanceMode: settings.whiteBalanceMode
property int selfTimerDuration: 0 // in seconds
property bool selfTimerRunning: false
imageCapture {
id: imageCapture
resolution: settings.resolution
}
videoRecorder {
id: videoRecorder
resolution: settings.resolution
// frameRate: 30 // a fixed frame rate is not set for now as it does not always get enforced anyway and can cause errors
}
onError: {
showPassiveNotification(i18n("An error occurred: \"%1\". Please consider restarting the application if it stopped working.", errorString))
}
}
title: i18n("Camera")
globalDrawer: GlobalDrawer {
camera: mainCamera
}
pageStack.initialPage: cameraPage
pageStack.globalToolBar.style: applicationWindow().headerStyle
}
// Qt includes
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QUrl>
#include <QIcon>
// KDE includes
#include <KAboutData>
#include <KLocalizedString>
#include <KLocalizedContext>
#ifdef Q_OS_ANDROID
#include <QtAndroid>
#endif
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QCoreApplication::setOrganizationName("KDE");
QCoreApplication::setOrganizationDomain("kde.org");
QCoreApplication::setApplicationName("plasma-camera");
QGuiApplication::setApplicationDisplayName("Plasma Camera");
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("camera-photo")));
// About Data
KAboutData about(app.applicationName(), app.applicationDisplayName(), app.applicationVersion(), QString(),
KAboutLicense::GPL, i18n("© Plasma Mobile Developers"), QString());
about.addAuthor(i18n("Marco Martin"), QString(), QStringLiteral("mart@kde.org"), QStringLiteral("https://notmart.org"));
about.addAuthor(i18n("Jonah Brüchert"), QString(), QStringLiteral("jbb@kaidan.im"), QStringLiteral("https://jbbgameich.github.io"));
about.setProgramLogo(app.windowIcon());
KAboutData::setApplicationData(about);
#ifdef Q_OS_ANDROID
QtAndroid::requestPermissionsSync({"android.permission.CAMERA"});
#endif
// QML Engine
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("cameraAboutData"),
QVariant::fromValue(KAboutData::applicationData()));
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}
<RCC>
<qresource prefix="/">
<file alias="main.qml">contents/ui/main.qml</file>
<file alias="GlobalDrawer.qml">contents/ui/GlobalDrawer.qml</file>
<file alias="CameraPage.qml">contents/ui/CameraPage.qml</file>
<file alias="AboutPage.qml">contents/ui/AboutPage.qml</file>
<file alias="ZoomControl.qml">contents/ui/ZoomControl.qml</file>
<file alias="camera_flash_off.png">contents/ui/images/camera_flash_off.png</file>
<file alias="camera_camera_setting.png">contents/ui/images/camera_camera_setting.png</file>
<file alias="camera_auto_mode.png">contents/ui/images/camera_auto_mode.png</file>
<file alias="camera_white_balance_sunny.png">contents/ui/images/camera_white_balance_sunny.png</file>
<file alias="camera_white_balance_incandescent.png">contents/ui/images/camera_white_balance_incandescent.png</file>
<file alias="camera_flash_auto.png">contents/ui/images/camera_flash_auto.png</file>
<file alias="camera_flash_redeye.png">contents/ui/images/camera_flash_redeye.png</file>
<file alias="camera_white_balance_cloudy.png">contents/ui/images/camera_white_balance_cloudy.png</file>
<file alias="camera_white_balance_flourescent.png">contents/ui/images/camera_white_balance_flourescent.png</file>
<file alias="camera_flash_fill.png">contents/ui/images/camera_flash_fill.png</file>
<file alias="PreviewArea.qml">contents/ui/PreviewArea.qml</file>
</qresource>
</RCC>