From 2ca774bd7e318ea853a975fcb5cb2b5fdcbaaeb5 Mon Sep 17 00:00:00 2001
From: Marco Matthies <71844+marcom@users.noreply.github.com>
Date: Thu, 23 May 2024 19:54:11 +0200
Subject: [PATCH] Untabify main.qml, config.qml

---
 src/config.qml | 452 ++++++++++++++++++++++++-------------------------
 src/main.qml   | 316 +++++++++++++++++-----------------
 2 files changed, 384 insertions(+), 384 deletions(-)

diff --git a/src/config.qml b/src/config.qml
index 713e4e0..3d8711f 100644
--- a/src/config.qml
+++ b/src/config.qml
@@ -18,237 +18,237 @@ ApplicationWindow {
     visible: true
 
     ColumnLayout {
-	id: generalSettings
-	anchors.top: parent.top
-	anchors.left: parent.left
-	anchors.leftMargin: 20
-	anchors.topMargin: 20
-	spacing: 8
-
-	Text {
-	    text: "General Settings:"
-	    horizontalAlignment: Text.AlignCenter
-	    font.bold: true
-	}
-
-	RowLayout {
-	    Label { text: "Configuration file:" }
-	    Label {
-		text: conf.userconfigfile
-		font.italic: true
-	    }
-	    Button {
-		text: "Select..."
-		onClicked: conffileChooser.open()
-	    }
-	    FileDialog {
-		id: conffileChooser
-		defaultSuffix: "toml"
-		fileMode: FileDialog.SaveFile
-		nameFilters: ["Configuration files (*.toml)"]
-		onAccepted: conf.userconfigfile = selectedFile
-	    }
-	}
-
-	RowLayout {
-	    Label { text: "Output folder:" }
-	    Label {
-		text: conf.outdir
-		font.italic: true
-	    }
-	    Button {
-		text: "Select..."
-		onClicked: outdirChooser.open()
-	    }
-	    FolderDialog {
-		id: outdirChooser
-		selectedFolder: conf.outdir
-		onAccepted: conf.outdir = selectedFolder
-	    }
-	}
-
-	//XXX Not all regions have data available!
-	// (currently, only Jena is fully configured)
-	RowLayout {
-	    Label { text: "Region:" }
-	    ComboBox {
-		currentIndex: 3
-		model: ["Bodensee", "Eichsfeld", "Hohenlohe", "Jena",
-			"Oberrhein", "Thüringer Becken"]
-		onCurrentIndexChanged: conf.region = currentText
-	    }
-	}
-
-	RowLayout {
-	    Label { text: "Crop model:" }
-	    ComboBox {
-		currentIndex: 0
-		model: ["ALMaSS", "AquaCrop"]
-		onCurrentIndexChanged: conf.cropmodel = currentText
-	    }
-	}
-
-	RowLayout { //TODO how can I enable multi-species selection?
-	    Label { text: "Species:" }
-	    ComboBox {
-		currentIndex: 0
-		model: ["Skylark", "Wolpertinger"]
-		onCurrentIndexChanged: conf.species = currentText
-	    }
-	}
-
-	//XXX For which years do I actually have data?
-	RowLayout {
-	    Label { text: "Start date:" }
-	    SpinBox {
-		Layout.maximumWidth: 100
-		from: 1
-		to: 31
-		value: conf.startdateday
-		editable: true
-		wrap: true
-		onValueModified: conf.startdateday = value
-	    }
-	    SpinBox {
-		Layout.maximumWidth: 100
-		from: 1
-		to: 12
-		value: conf.startdatemonth
-		editable: true
-		wrap: true
-		onValueModified: conf.startdatemonth = value
-	    }
-	    SpinBox {
-		Layout.maximumWidth: 100
-		from: 2000
-		to: 2050
-		value: conf.startdateyear
-		editable: true
-		wrap: true
-		textFromValue: function(value) { return Number(value).toString(); }
-		onValueModified: conf.startdateyear = value
-	    }				
-	}
-
-	RowLayout {
-	    Label { text: "End date:" }
-	    SpinBox {
-		Layout.maximumWidth: 100
-		from: 1
-		to: 31
-		value: conf.enddateday
-		editable: true
-		wrap: true
-		onValueModified: conf.enddateday = value
-	    }
-	    SpinBox {
-		Layout.maximumWidth: 100
-		from: 1
-		to: 12
-		value: conf.enddatemonth
-		editable: true
-		wrap: true
-		onValueModified: conf.enddatemonth = value
-	    }
-	    SpinBox {
-		Layout.maximumWidth: 100
-		from: 2000
-		to: 2050
-		value: conf.enddateyear
-		editable: true
-		wrap: true
-		textFromValue: function(value) { return Number(value).toString(); }
-		onValueModified: conf.enddateyear = value
-	    }				
-	}
+        id: generalSettings
+        anchors.top: parent.top
+        anchors.left: parent.left
+        anchors.leftMargin: 20
+        anchors.topMargin: 20
+        spacing: 8
+
+        Text {
+            text: "General Settings:"
+            horizontalAlignment: Text.AlignCenter
+            font.bold: true
+        }
+
+        RowLayout {
+            Label { text: "Configuration file:" }
+            Label {
+                text: conf.userconfigfile
+                font.italic: true
+            }
+            Button {
+                text: "Select..."
+                onClicked: conffileChooser.open()
+            }
+            FileDialog {
+                id: conffileChooser
+                defaultSuffix: "toml"
+                fileMode: FileDialog.SaveFile
+                nameFilters: ["Configuration files (*.toml)"]
+                onAccepted: conf.userconfigfile = selectedFile
+            }
+        }
+
+        RowLayout {
+            Label { text: "Output folder:" }
+            Label {
+                text: conf.outdir
+                font.italic: true
+            }
+            Button {
+                text: "Select..."
+                onClicked: outdirChooser.open()
+            }
+            FolderDialog {
+                id: outdirChooser
+                selectedFolder: conf.outdir
+                onAccepted: conf.outdir = selectedFolder
+            }
+        }
+
+        //XXX Not all regions have data available!
+        // (currently, only Jena is fully configured)
+        RowLayout {
+            Label { text: "Region:" }
+            ComboBox {
+                currentIndex: 3
+                model: ["Bodensee", "Eichsfeld", "Hohenlohe", "Jena",
+                        "Oberrhein", "Thüringer Becken"]
+                onCurrentIndexChanged: conf.region = currentText
+            }
+        }
+
+        RowLayout {
+            Label { text: "Crop model:" }
+            ComboBox {
+                currentIndex: 0
+                model: ["ALMaSS", "AquaCrop"]
+                onCurrentIndexChanged: conf.cropmodel = currentText
+            }
+        }
+
+        RowLayout { //TODO how can I enable multi-species selection?
+            Label { text: "Species:" }
+            ComboBox {
+                currentIndex: 0
+                model: ["Skylark", "Wolpertinger"]
+                onCurrentIndexChanged: conf.species = currentText
+            }
+        }
+
+        //XXX For which years do I actually have data?
+        RowLayout {
+            Label { text: "Start date:" }
+            SpinBox {
+                Layout.maximumWidth: 100
+                from: 1
+                to: 31
+                value: conf.startdateday
+                editable: true
+                wrap: true
+                onValueModified: conf.startdateday = value
+            }
+            SpinBox {
+                Layout.maximumWidth: 100
+                from: 1
+                to: 12
+                value: conf.startdatemonth
+                editable: true
+                wrap: true
+                onValueModified: conf.startdatemonth = value
+            }
+            SpinBox {
+                Layout.maximumWidth: 100
+                from: 2000
+                to: 2050
+                value: conf.startdateyear
+                editable: true
+                wrap: true
+                textFromValue: function(value) { return Number(value).toString(); }
+                onValueModified: conf.startdateyear = value
+            }                           
+        }
+
+        RowLayout {
+            Label { text: "End date:" }
+            SpinBox {
+                Layout.maximumWidth: 100
+                from: 1
+                to: 31
+                value: conf.enddateday
+                editable: true
+                wrap: true
+                onValueModified: conf.enddateday = value
+            }
+            SpinBox {
+                Layout.maximumWidth: 100
+                from: 1
+                to: 12
+                value: conf.enddatemonth
+                editable: true
+                wrap: true
+                onValueModified: conf.enddatemonth = value
+            }
+            SpinBox {
+                Layout.maximumWidth: 100
+                from: 2000
+                to: 2050
+                value: conf.enddateyear
+                editable: true
+                wrap: true
+                textFromValue: function(value) { return Number(value).toString(); }
+                onValueModified: conf.enddateyear = value
+            }                           
+        }
     }
 
     ColumnLayout {
-	id: advancedSettings
-	anchors.top: parent.top
-	anchors.right: parent.right
-	anchors.left: generalSettings.right
-	anchors.rightMargin: 20
-	anchors.topMargin: 20
-	anchors.leftMargin: 20
-	spacing: 8
-
-	Text {
-	    text: "Advanced Settings:"
-	    horizontalAlignment: Text.AlignCenter
-	    font.bold: true
-	}
-
-	RowLayout {
-	    Label { text: "Random seed:" }
-	    SpinBox {
-		from: 0
-		to: 2147483647
-		value: 2
-		editable: true
-		onValueModified: conf.seed = value
-	    }
-	}
-
-	RowLayout {
-	    Label { text: "Log level:" }
-	    ComboBox {
-		currentIndex: 2
-		model: ["debug", "info", "warn"]
-		onCurrentIndexChanged: conf.loglevel = currentText
-	    }
-	}
-
-	RowLayout {
-	    Label { text: "Processors:" }
-	    SpinBox {
-		from: 1
-		to: 8
-		value: conf.processors
-		editable: true
-		onValueModified: conf.processors = value
-	    }
-	}
-
-	CheckBox {
-	    checked: conf.csvoutput
-	    text: "Write CSV output"
-	    onClicked: conf.csvoutput = checked
-	}
-
-	//TODO add config options for:
-	// farmmodel
-	// targetspecies
-	// insectmodel
+        id: advancedSettings
+        anchors.top: parent.top
+        anchors.right: parent.right
+        anchors.left: generalSettings.right
+        anchors.rightMargin: 20
+        anchors.topMargin: 20
+        anchors.leftMargin: 20
+        spacing: 8
+
+        Text {
+            text: "Advanced Settings:"
+            horizontalAlignment: Text.AlignCenter
+            font.bold: true
+        }
+
+        RowLayout {
+            Label { text: "Random seed:" }
+            SpinBox {
+                from: 0
+                to: 2147483647
+                value: 2
+                editable: true
+                onValueModified: conf.seed = value
+            }
+        }
+
+        RowLayout {
+            Label { text: "Log level:" }
+            ComboBox {
+                currentIndex: 2
+                model: ["debug", "info", "warn"]
+                onCurrentIndexChanged: conf.loglevel = currentText
+            }
+        }
+
+        RowLayout {
+            Label { text: "Processors:" }
+            SpinBox {
+                from: 1
+                to: 8
+                value: conf.processors
+                editable: true
+                onValueModified: conf.processors = value
+            }
+        }
+
+        CheckBox {
+            checked: conf.csvoutput
+            text: "Write CSV output"
+            onClicked: conf.csvoutput = checked
+        }
+
+        //TODO add config options for:
+        // farmmodel
+        // targetspecies
+        // insectmodel
     }
 
     footer: ToolBar {
-	RowLayout {
-	    anchors.right: parent.right
-	    layoutDirection: Qt.RightToLeft
-
-	    Button {
-		text: "Start new simulation"
-		onClicked: {
-		    //TODO show splash
-		    Julia.writeconfig()
-		    Julia.newsimulation()
-		    configWindow.close()
-		}
-	    }
-
-	    Button {
-		text: "Save configuration"
-		onClicked: {
-		    Julia.writeconfig()
-		    configWindow.close()
-		}
-	    }
-
-	    Button {
-		text: "Cancel"
-		onClicked: configWindow.close()
-	    }
-	}
+        RowLayout {
+            anchors.right: parent.right
+            layoutDirection: Qt.RightToLeft
+
+            Button {
+                text: "Start new simulation"
+                onClicked: {
+                    //TODO show splash
+                    Julia.writeconfig()
+                    Julia.newsimulation()
+                    configWindow.close()
+                }
+            }
+
+            Button {
+                text: "Save configuration"
+                onClicked: {
+                    Julia.writeconfig()
+                    configWindow.close()
+                }
+            }
+
+            Button {
+                text: "Cancel"
+                onClicked: configWindow.close()
+            }
+        }
     }
 }
diff --git a/src/main.qml b/src/main.qml
index 81d00d2..c047a52 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -18,201 +18,201 @@ ApplicationWindow {
     visible: true
 
     menuBar: MenuBar {
-	Menu {
-	    title: "&Simulation"
-	    Action {
-		text: "&New Simulation"
-		onTriggered: { vars.launching = true } //TODO select config file
-	    }
-	    Action {
-		text: "&Configure Simulation"
-		onTriggered: { Julia.configwindow() }
-	    }
-	    Action {
-		text: "&Load Saved State"
-		onTriggered: { loadFileChooser.open() }
-	    }
-	    Action {
-		text: "&Save Current State"
-		onTriggered: { saveFileChooser.open() }
-	    }
-	    MenuSeparator { }
-	    Action {
-		text: "&Quit"
-		onTriggered: { mainWindow.close() }
-	    }
-	}
-	Menu {
-	    title: "&Data"
-	    Action {
-		text: "Show &Population Graph"
-		onTriggered: { populationGraph.visible = true }
-	    }
-	    Action {
-		text: "Save &Simulation Output"
-		onTriggered: { Julia.saveoutput() }
-	    }
-	}
-	Menu {
-	    title: "&Help"
-	    Action {
-		text: "&Documentation"
-		onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/documentation") }
-	    }
-	    Action {
-		text: "&Website"
-		onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/") }
-	    }
-	    Action {
-		text: "&About"
-		onTriggered: { aboutDialog.open() }
-	    }
-	}
+        Menu {
+            title: "&Simulation"
+            Action {
+                text: "&New Simulation"
+                onTriggered: { vars.launching = true } //TODO select config file
+            }
+            Action {
+                text: "&Configure Simulation"
+                onTriggered: { Julia.configwindow() }
+            }
+            Action {
+                text: "&Load Saved State"
+                onTriggered: { loadFileChooser.open() }
+            }
+            Action {
+                text: "&Save Current State"
+                onTriggered: { saveFileChooser.open() }
+            }
+            MenuSeparator { }
+            Action {
+                text: "&Quit"
+                onTriggered: { mainWindow.close() }
+            }
+        }
+        Menu {
+            title: "&Data"
+            Action {
+                text: "Show &Population Graph"
+                onTriggered: { populationGraph.visible = true }
+            }
+            Action {
+                text: "Save &Simulation Output"
+                onTriggered: { Julia.saveoutput() }
+            }
+        }
+        Menu {
+            title: "&Help"
+            Action {
+                text: "&Documentation"
+                onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/documentation") }
+            }
+            Action {
+                text: "&Website"
+                onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/") }
+            }
+            Action {
+                text: "&About"
+                onTriggered: { aboutDialog.open() }
+            }
+        }
     }
 
     // visualise the model map and the locations of animals
     MakieViewport {
-	id: mapviewport
-	anchors.fill: parent
-	renderFunction: render_map_callback
+        id: mapviewport
+        anchors.fill: parent
+        renderFunction: render_map_callback
     }
 
     // the main control bar, with pause/step/run buttons, the progress
     // bar and a speed slider
     footer: ToolBar {
-	RowLayout {
-	    //TODO change button texts to icons
-	    // (https://doc.qt.io/qt-6/qtquickcontrols-icons.html)
-	    id: controlBar
-	    anchors.fill: parent
-	    Layout.alignment: Qt.AlignVCenter
-	    Layout.fillWidth: true
-	    // anchors.topMargin: 5 //FIXME
-	    // anchors.bottomMargin: 5
-	    Button {
-		id: backButton
-		text: "<"
-		ToolTip.text: "Back"
-		ToolTip.visible: hovered
-		onClicked: { Julia.previousstep() }
-	    }
-	    Button {
-		id: stepButton
-		text: ">"
-		ToolTip.text: "Step"
-		ToolTip.visible: hovered
-		onClicked: { Julia.nextstep() }
-	    }
-	    Button {
-		id: runButton
-		text: vars.runbuttontext
-		ToolTip.text: vars.runbuttontip
-		ToolTip.visible: hovered
-		onClicked: { vars.running = !vars.running }
-	    }
-	    ProgressBar {
-		id: progressBar
-		value: vars.progress
-		Layout.fillWidth: true
-		ToolTip.text: "Simulation progress"
-		ToolTip.visible: hovered
-	    }
-	    Slider {
-		id: speedSlider
-		from: 0.0
-		to: 2.0
-		value: vars.delay
-		stepSize: 0.1
-		snapMode: Slider.SnapAlways
-		ToolTip.text: "Time delay between updates"
-		ToolTip.visible: hovered
-		onValueChanged: vars.delay = value
-	    }
-	    Text {
-		id: dateText
-		text: Julia.datestring()
-		//width:  //TODO
-	    }
-	}
+        RowLayout {
+            //TODO change button texts to icons
+            // (https://doc.qt.io/qt-6/qtquickcontrols-icons.html)
+            id: controlBar
+            anchors.fill: parent
+            Layout.alignment: Qt.AlignVCenter
+            Layout.fillWidth: true
+            // anchors.topMargin: 5 //FIXME
+            // anchors.bottomMargin: 5
+            Button {
+                id: backButton
+                text: "<"
+                ToolTip.text: "Back"
+                ToolTip.visible: hovered
+                onClicked: { Julia.previousstep() }
+            }
+            Button {
+                id: stepButton
+                text: ">"
+                ToolTip.text: "Step"
+                ToolTip.visible: hovered
+                onClicked: { Julia.nextstep() }
+            }
+            Button {
+                id: runButton
+                text: vars.runbuttontext
+                ToolTip.text: vars.runbuttontip
+                ToolTip.visible: hovered
+                onClicked: { vars.running = !vars.running }
+            }
+            ProgressBar {
+                id: progressBar
+                value: vars.progress
+                Layout.fillWidth: true
+                ToolTip.text: "Simulation progress"
+                ToolTip.visible: hovered
+            }
+            Slider {
+                id: speedSlider
+                from: 0.0
+                to: 2.0
+                value: vars.delay
+                stepSize: 0.1
+                snapMode: Slider.SnapAlways
+                ToolTip.text: "Time delay between updates"
+                ToolTip.visible: hovered
+                onValueChanged: vars.delay = value
+            }
+            Text {
+                id: dateText
+                text: Julia.datestring()
+                //width:  //TODO
+            }
+        }
     }
 
     // extra windows
     MessageDialog {
-	id: aboutDialog
-	text: "Persefone.jl Desktop"
-	informativeText: "A mechanistic model of agricultural landscapes \
+        id: aboutDialog
+        text: "Persefone.jl Desktop"
+        informativeText: "A mechanistic model of agricultural landscapes \
 and ecosystems in Europe.\n\n\
 © 2023 Daniel Vedder, Lea Kolb, Guy Pe'er\n\
 Distributed under the MIT license."
     }
 
     FileDialog {
-	id: loadFileChooser
-	defaultSuffix: "dat"
-	nameFilters: ["Save files (*.dat)"]
-	onAccepted: { Julia.loadsimulation(selectedFile.toString()) }
+        id: loadFileChooser
+        defaultSuffix: "dat"
+        nameFilters: ["Save files (*.dat)"]
+        onAccepted: { Julia.loadsimulation(selectedFile.toString()) }
     }
 
     FileDialog {
-	id: saveFileChooser
-	defaultSuffix: "dat"
-	fileMode: FileDialog.SaveFile
-	nameFilters: ["Save files (*.dat)"]
-	onAccepted: { Julia.savesimulation(selectedFile.toString()) }
+        id: saveFileChooser
+        defaultSuffix: "dat"
+        fileMode: FileDialog.SaveFile
+        nameFilters: ["Save files (*.dat)"]
+        onAccepted: { Julia.savesimulation(selectedFile.toString()) }
     }
 
     Window {
-	id: populationGraph
-	title: "Population Graph"
-	width: 512
-	height: 512
-	visible: false
+        id: populationGraph
+        title: "Population Graph"
+        width: 512
+        height: 512
+        visible: false
 
-	MakieViewport {
-	    id: plotviewport
-	    anchors.fill: parent
-	    renderFunction: render_plot_callback
-	}
+        MakieViewport {
+            id: plotviewport
+            anchors.fill: parent
+            renderFunction: render_plot_callback
+        }
     }
 
     Popup {
-	id: splashPopup
-	parent: Overlay.overlay
-	closePolicy: Popup.NoAutoClose
-	modal: true
-	padding: 0
+        id: splashPopup
+        parent: Overlay.overlay
+        closePolicy: Popup.NoAutoClose
+        modal: true
+        padding: 0
 
-	width: 600
-	height: 250
-	x: Math.round((parent.width - width) / 2)
-	y: Math.round((parent.height - height) / 2)
+        width: 600
+        height: 250
+        x: Math.round((parent.width - width) / 2)
+        y: Math.round((parent.height - height) / 2)
 
-	Image {
-	    anchors.fill: parent
-	    source: "persefonejl_logo_v3_splash.png"
-	}
+        Image {
+            anchors.fill: parent
+            source: "persefonejl_logo_v3_splash.png"
+        }
     }
 
     // set up connections and signals to update the simulation and the display
     Connections {
-	target: timer
-	function onTimeout() { vars.ticks += 1 }
+        target: timer
+        function onTimeout() { vars.ticks += 1 }
     }
 
     JuliaSignals {
-	signal updateMakie()
-	onUpdateMakie: {
-	    dateText.text = Julia.datestring();
-	    mapviewport.update();
-	    plotviewport.update();
-	}
-	signal showSplash()
-	onShowSplash: {
-	    splashPopup.open()
-	}
-	signal closeSplash()
-	onCloseSplash: {
-	    splashPopup.close()
-	}
+        signal updateMakie()
+        onUpdateMakie: {
+            dateText.text = Julia.datestring();
+            mapviewport.update();
+            plotviewport.update();
+        }
+        signal showSplash()
+        onShowSplash: {
+            splashPopup.open()
+        }
+        signal closeSplash()
+        onCloseSplash: {
+            splashPopup.close()
+        }
     }
 }
-- 
GitLab