Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion io.github.saeugetier.photobooth.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"--share=network",
"--device=all",
"--filesystem=home",
"--filesystem=host:removable",
"--socket=fallback-x11",
"--socket=wayland"
],
Expand Down Expand Up @@ -159,4 +160,4 @@
]
}
]
}
}
1 change: 1 addition & 0 deletions qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,6 @@
<file>shaders/previewshader.frag.qsb</file>
<file>models/coco.names</file>
<file>images/backgrounds/Stripes.png</file>
<file>qml/content/CustomFolderDialog.qml</file>
</qresource>
</RCC>
2 changes: 1 addition & 1 deletion qml/Application.qml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ ApplicationWindow {
{
id: applicationSettings
category: "Application"
property url foldername: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
property url foldername: StandardPaths.writableLocation(StandardPaths.PicturesLocation) + "/photobooth"
property bool printEnable: true
property string password: "0815"
property string language: "en"
Expand Down
48 changes: 48 additions & 0 deletions qml/SettingsMenu.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import QtQuick
import QtMultimedia
import QtQuick.Controls
import QtQuick.Dialogs
import Qt.labs.platform
import QtQml
import "content"

SettingsMenuForm {
id: form
Expand Down Expand Up @@ -74,6 +78,50 @@ SettingsMenuForm {
console.log("index: " + Number(index).toString())
}

function delay(delayTime, cb) {
timer = new Timer();
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}

CustomFolderDialog {
id: pictureFolderDialog
title: qsTr("Select Pictures Folder")
anchors.centerIn: parent
width: parent.width - 100
height: parent.height - 100

Timer
{
id: folderCheckTimer
interval: 1000
running: false
repeat: false
onTriggered: function() {
filesystem.checkImageFolders()
console.log("Checked folder: " + applicationSettings.foldername)
}
}

onAccepted: function()
{
console.log("Selected folder: " + pictureFolderDialog.currentFolder)
applicationSettings.foldername = pictureFolderDialog.currentFolder
applicationSettings.sync()

folderCheckTimer.start()
}
}

buttonSelectPhotoDirectory.onClicked:
{
pictureFolderDialog.currentFolder = applicationSettings.foldername
console.log("selecting pictures folder: " + pictureFolderDialog.currentFolder)
pictureFolderDialog.open()
}

buttonClose.onClicked:
{
exitSettings()
Expand Down
20 changes: 20 additions & 0 deletions qml/SettingsMenuForm.ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Item {
property alias versionText: labelVersionText.text
property alias comboBoxCameraOrientation: comboBoxCameraOrientation
property alias comboBoxNeuralNetworkRuntime: comboBoxNeuralNetworkRuntime
property alias buttonSelectPhotoDirectory: buttonSelectPhotoDirectory

ColumnLayout {
anchors.fill: parent
Expand Down Expand Up @@ -92,6 +93,25 @@ Item {
anchors.topMargin: 20
spacing: 20

RowLayout {
spacing: 10
Label {
text: qsTr("Photo Directory: ")
}
Label {
id: labelPhotoDirectory
Layout.fillWidth: true
text: applicationSettings.foldername
}
Item {
Layout.fillWidth: true
}
Button {
id: buttonSelectPhotoDirectory
text: qsTr("Browse")
}
}

Button {
id: buttonCopyPhotos
text: qsTr("Copy photos to removable disk")
Expand Down
224 changes: 224 additions & 0 deletions qml/content/CustomFolderDialog.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// CustomFolderDialog.qml
import QtQuick 6.5
import QtQuick.Controls 6.5
import QtQuick.Layouts 6.5
import Qt.labs.folderlistmodel 2.2
import QtQuick.VirtualKeyboard 6.5
import QtCore

Dialog {
id: root
modal: true
width: 800
height: 600
standardButtons: Dialog.NoButton

property url currentFolder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)

signal canceled()

property bool createMode: false

Rectangle {
anchors.fill: parent
color: Material.background
border.color: Material.foreground
radius: 8

ColumnLayout {
anchors.fill: parent
spacing: 10

Text {
text: qsTr("Select Folder")
font.pixelSize: 20
Layout.alignment: Qt.AlignHCenter
}

RowLayout {
id: breadcrumbBar
Layout.fillWidth: true
spacing: 4

// Root Button "/"
Button {
text: "/"
font.pixelSize: 14
onClicked: {
root.currentFolder = "file:///"
folderModel.folder = root.currentFolder
}
}

Repeater {
model:{
var path = root.currentFolder.toString().replace("file://", "")
var segments = path.split("/").filter(s => s.length > 0)
return segments
}

delegate: RowLayout {
spacing: 2

Button {
text: modelData === "/" ? "/" : modelData
font.pixelSize: 14
onClicked: {
let segments = root.currentFolder.toString().replace("file://", "").split("/").filter(s => s.length > 0)
let newPath = "/" + segments.slice(0, index + 1).join("/")
root.currentFolder = "file://" + newPath
folderModel.folder = root.currentFolder

}
}

Text {
text: index < breadcrumbBarRepeater.count - 1 ? " / " : ""
font.pixelSize: 14
color: Material.foreground
}
}

id: breadcrumbBarRepeater
}

Item {
Layout.fillWidth: true
}

Button {
text: createMode ? qsTr("Cancel") : qsTr("New Folder")
onClicked: {
createMode = !createMode
if (!createMode)
newFolderNameField.text = ""
}
}
}

RowLayout {
ToolSeparator {
Layout.fillWidth: true
orientation: Qt.Horizontal
}
}

// Inline New Folder Creation
RowLayout {
visible: createMode
Layout.fillWidth: true
spacing: 10

TextField {
id: newFolderNameField
placeholderText: "New folder name"
Layout.fillWidth: true
inputMethodHints: Qt.ImhNoPredictiveText
focus: createMode
onActiveFocusChanged: {
if (activeFocus && createMode) {
Qt.inputMethod.show()
} else {
Qt.inputMethod.hide()
}
}
}

Button {
text: "Create"
Button {
text: "Create"
onClicked: {
const name = newFolderNameField.text.trim()
if (name.length > 0) {
var basePath = currentFolder.toString().replace("file://", "")
var newPath = basePath + "/" + name
var success = filesystem.createFolder(newPath)
console.log("Folder created:", success, newPath)

if (success) {
createMode = false
newFolderNameField.text = ""
Qt.inputMethod.hide()
}
}
}
}
}
}

ListView {
id: folderList
Layout.fillWidth: true
Layout.fillHeight: true
clip: true

ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AlwaysOn
}

model: FolderListModel {
id: folderModel
folder: currentFolder
showDirs: true
showFiles: false
sortField: FolderListModel.Name
}

delegate: Rectangle {
width: folderList.width
height: 48
color: model.fileURL === currentFolder ? "#ddeeff" : "transparent"

Text {
text: fileName
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 12
font.pixelSize: 16
color: Material.foreground
}

MouseArea {
anchors.fill: parent
onClicked: {
root.currentFolder = model.fileURL
folderModel.folder = model.fileURL
}
}
}
}

RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: 20

Button {
text: "Select"
onClicked: {
root.accepted()
root.close()
}
}

Button {
text: "Cancel"
onClicked: {
root.close()
root.canceled()
}
}
}
}

// Virtual Keyboard - only visible if TextField is active & createMode is on
InputPanel {
id: inputPanel
y: parent.height - height
width: parent.width > 600 ? 600 : parent.width
visible: Qt.inputMethod.visible && createMode
anchors.horizontalCenter: parent.horizontalCenter
z: 100
}
}
}
30 changes: 30 additions & 0 deletions src/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,42 @@ QUrl FileSystem::findFile(QString filename, QList<QUrl> searchPaths, bool search
QString FileSystem::getImagePath()
{
QSettings settings("saeugetier", "qtbooth");
settings.sync();
if(settings.contains("Application/foldername"))
return settings.value("Application/foldername").value<QString>();
else
return "file://" + QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
}

bool FileSystem::createFolder(const QString &path)
{
if(path.length() == 0)
{
qDebug() << "Filesystem Error: path is empty!";
return false;
}

QDir dir(path);
if(!dir.exists())
{
if(dir.mkpath("."))
{
qDebug() << "Created folder: " << path;
return true;
}
else
{
qDebug() << "Filesystem Error: Could not create folder: " << path;
return false;
}
}
else
{
qDebug() << "Folder already exists: " << path;
return true;
}
}

void FileSystem::checkImageFolders()
{
QString imagePath = getImagePath();
Expand Down
Loading