LogarithmPlotter/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml
2022-03-05 18:19:20 +01:00

276 lines
8.9 KiB
QML

/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2022 Ad5001
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQml.Models 2.12
/*!
\qmltype ListSetting
\inqmlmodule eu.ad5001.LogarithmPlotter.Setting
\brief Setting to create and edit lists and dictionaries.
\sa EditorDialog, Settings, Icon
*/
Column {
id: control
/*!
\qmlsignal ListSetting::changed()
Emitted when an entry of the setting has been changed.
The corresponding handler is \c onChanged.
*/
signal changed()
/*!
\qmlproperty string ListSetting::label
Label of the setting.
*/
property string label: ''
/*!
\qmlproperty string ListSetting::icon
Icon path of the setting.
*/
property string icon: ''
/*!
\qmlproperty bool ListSetting::dictionaryMode
true to set the export mode to dictionary, false for list.
*/
property bool dictionaryMode: false
/*!
\qmlproperty string ListSetting::keyType
Type for keys for dictionary, can be either "string" or "number".
*/
property string keyType: "string"
/*!
\qmlproperty string ListSetting::keyType
Type for values of the dictionary or list, can be either "string" or "number".
*/
property string valueType: "string"
/*!
\qmlproperty string ListSetting::preKeyLabel
Text to be put before the key for each entry.
*/
property string preKeyLabel: ""
/*!
\qmlproperty string ListSetting::postKeyLabel
Text to be put after the key for each entry. Only for dictionaries.
*/
property string postKeyLabel: ": "
/*!
\qmlproperty var ListSetting::keyRegexp
Regular expression used in the validator for keys. Only for dictionaries.
*/
property var keyRegexp: /^.+$/
/*!
\qmlproperty var ListSetting::valueRegexp
Regular expression used in the validator for values.
*/
property var valueRegexp: /^.+$/
/*!
\qmlproperty bool ListSetting::forbidAdding
If true, prevents the user from adding or removing new entries.
*/
property bool forbidAdding: false
/*!
\qmlproperty bool ListSetting::model
Model of the list/dictionnary, in the form of [{key: < key >, val: < value > }].
Use the \a importModel method to set the model.
*/
property alias model: repeater.model
Row {
height: 30
width: parent.width;
Icon {
id: iconLabel
anchors.top: parent.top
anchors.topMargin: icon == "" ? 0 : 3
source: control.visible ? "../icons/" + control.icon : ""
width: height
height: icon == "" || !visible ? 0 : 24
color: sysPalette.windowText
}
Label {
id: labelItem
height: 30
verticalAlignment: TextInput.AlignVCenter
text: qsTranslate("control", "%1: ").arg(control.label)
}
}
Repeater {
id: repeater
width: control.width
model: ListModel {}
Row {
id: defRow
height: addEntryBtn.height
width: parent.width
Text {
id: preKeyText
height: parent.height
verticalAlignment: TextInput.AlignVCenter
color: sysPalette.windowText
text: control.preKeyLabel
}
TextField {
id: keyInput
visible: control.dictionaryMode
height: parent.height
width: visible ? 50 : 0
validator: RegExpValidator {
regExp: control.keyRegexp
}
verticalAlignment: TextInput.AlignVCenter
horizontalAlignment: TextInput.AlignHCenter
color: sysPalette.windowText
text: visible ? control.model.get(index).key : false
selectByMouse: true
onEditingFinished: {
var value = text
if(control.keyType == 'int') {
value = parseInt(value)
if(value.toString()=="NaN")
value = ""
}
if(control.keyType == 'double') {
value = parseFloat(value)
if(value.toString()=="NaN")
value = ""
}
if(value !== "" && valueInput.acceptableInput) {
control.model.setProperty(index, 'key', value)
control.changed()
}
}
}
Text {
id: postKeyText
visible: control.dictionaryMode
height: parent.height
verticalAlignment: TextInput.AlignVCenter
color: sysPalette.windowText
text: control.postKeyLabel
}
TextField {
id: valueInput
height: parent.height
width: parent.width - x - deleteButton.width - 5
validator: RegExpValidator {
regExp: control.valueRegexp
}
verticalAlignment: TextInput.AlignVCenter
horizontalAlignment: TextInput.AlignHCenter
color: sysPalette.windowText
text: visible ? control.model.get(index).val : false
selectByMouse: true
onEditingFinished: {
var value = text
if(control.valueType == 'int') {
value = parseInt(value)
if(value.toString()=="NaN")
value = ""
}
if(control.valueType == 'double') {
value = parseFloat(value)
if(value.toString()=="NaN")
value = ""
}
if(value !== "" && keyInput.acceptableInput) {
control.model.setProperty(index, 'val', value)
control.changed()
}
}
}
Item {
width: 5
height: parent.height
}
Button {
id: deleteButton
width: visible ? parent.height : 0
height: width
icon.source: './icons/common/delete.svg'
icon.name: 'delete'
visible: !control.forbidAdding
onClicked: {
control.model.remove(index)
}
}
}
}
Button {
id: addEntryBtn
visible: !control.forbidAdding
text: qsTr('+ Add Entry')
width: control.width
onClicked: {
control.model.append({
key: control.keyType == 'string' ? '' : model.count,
val: control.valueType == 'string' ? '' : 0
})
}
}
/*!
\qmlmethod void ListSetting::importModel(var importer)
Imports either a list or a dictionnary in the model.
*/
function importModel(importer) {
model.clear()
for(var key in importer)
model.append({
key: control.keyType == 'string' ? key.toString() : parseFloat(key),
val: control.valueType == 'string' ? importer[key].toString() : parseFloat(importer[key])
})
}
/*!
\qmlmethod void ListSetting::exportModel()
Exports the model either a list or a dictionnary in the model depending on \a dictionaryMode.
*/
function exportModel() {
if(dictionaryMode) {
var ret = {}
for(var i = 0; i < model.count; i++)
ret[model.get(i).key] = model.get(i).val
return ret
} else {
var ret = []
for(var i = 0; i < model.count; i++)
ret.push(model.get(i).val)
return ret
}
}
}