- datastore: export/import JSON con le chiavi camelCase dell'app Android (breedSettings/reservations/customers), scorte e ultimo aggiornamento preservati al ripristino - settings: flag 'introduzione vista' - desktop: permesso Documents (dove finisce il backup) - nuovi controlli: tools/check_qml.py (chiavi di traduzione, simboli JS, pagine, componenti) e qmllint nella suite - versione 0.2.0
207 lines
6.4 KiB
QML
207 lines
6.4 KiB
QML
import QtQuick 2.2
|
|
import Sailfish.Silica 1.0
|
|
import "../js/i18n.js" as I18N
|
|
import "../js/catalog.js" as Catalog
|
|
|
|
// "Razze disponibili" (prima scheda del SettingsPage dell'app Flutter):
|
|
// il catalogo completo con l'interruttore di attivazione. Attivare una razza
|
|
// crea l'allevamento (senza galline), disattivarla lo elimina dopo conferma.
|
|
Page {
|
|
id: page
|
|
allowedOrientations: Orientation.All
|
|
|
|
property string lang: "en"
|
|
property bool ready: false
|
|
// razze attive (id) ricostruite dal livello dati
|
|
property var enabledIds: []
|
|
|
|
function tr(key, arg) { return I18N.t(key, arg, page.lang) }
|
|
|
|
ListModel { id: breedModel }
|
|
|
|
function isEnabled(breedId) {
|
|
return page.enabledIds.indexOf(breedId) >= 0
|
|
}
|
|
|
|
function henCount(breedId) {
|
|
var settings = appData.breedSettings()
|
|
for (var i = 0; i < settings.length; i++) {
|
|
if (settings[i].breedId === breedId) {
|
|
var hens = settings[i].hens
|
|
return hens ? hens.length : 0
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
function reload() {
|
|
page.lang = I18N.langFor(appSettings.language, Qt.locale().name)
|
|
|
|
var settings = appData.breedSettings()
|
|
var ids = []
|
|
for (var i = 0; i < settings.length; i++)
|
|
ids.push(settings[i].breedId)
|
|
page.enabledIds = ids
|
|
|
|
breedModel.clear()
|
|
for (var j = 0; j < Catalog.HF_BREEDS.length; j++) {
|
|
var b = Catalog.HF_BREEDS[j]
|
|
breedModel.append({
|
|
"n": j,
|
|
"name": page.tr(b.name),
|
|
"description": page.tr(b.description),
|
|
"eggColor": page.tr("egg_color") + ": " + page.tr(b.eggColor),
|
|
"production": b.eggsPerHenPerDay.toFixed(1) + " " + page.tr("eggs_per_g"),
|
|
"enabled": page.isEnabled(b.id),
|
|
"hens": page.henCount(b.id)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Attivazione immediata; disattivazione con conferma (come l'originale,
|
|
// che avverte perche' si perdono le galline registrate).
|
|
function toggleBreed(index) {
|
|
var breed = Catalog.HF_BREEDS[index]
|
|
if (!breed)
|
|
return
|
|
if (page.isEnabled(breed.id)) {
|
|
confirmDialog.pendingId = breed.id
|
|
confirmDialog.open()
|
|
} else {
|
|
var settings = appData.breedSettings()
|
|
settings.push({ "breedId": breed.id, "hens": [] })
|
|
appData.saveBreedSettings(settings)
|
|
page.reload()
|
|
}
|
|
}
|
|
|
|
function removeBreed(breedId) {
|
|
var settings = appData.breedSettings()
|
|
var out = []
|
|
for (var i = 0; i < settings.length; i++) {
|
|
if (settings[i].breedId !== breedId)
|
|
out.push(settings[i])
|
|
}
|
|
appData.saveBreedSettings(out)
|
|
page.reload()
|
|
}
|
|
|
|
Component.onCompleted: page.reload()
|
|
|
|
onStatusChanged: {
|
|
if (status !== PageStatus.Active)
|
|
return
|
|
if (page.ready)
|
|
page.reload()
|
|
page.ready = true
|
|
}
|
|
|
|
SilicaListView {
|
|
id: listView
|
|
anchors.fill: parent
|
|
|
|
header: Column {
|
|
width: listView.width
|
|
|
|
PageHeader { title: page.tr("available_breeds") }
|
|
}
|
|
|
|
model: breedModel
|
|
|
|
delegate: ListItem {
|
|
id: breedItem
|
|
contentHeight: photo.height + Theme.paddingMedium
|
|
|
|
Image {
|
|
id: photo
|
|
x: Theme.horizontalPageMargin
|
|
y: Theme.paddingMedium
|
|
width: Theme.itemSizeLarge
|
|
height: Theme.itemSizeLarge
|
|
source: "file://" + Catalog.HF_BREEDS[model.n].asset
|
|
fillMode: Image.PreserveAspectCrop
|
|
asynchronous: true
|
|
}
|
|
|
|
Column {
|
|
x: photo.x + photo.width + Theme.paddingMedium
|
|
y: Theme.paddingMedium
|
|
width: parent.width - x - switchControl.width - 2 * Theme.horizontalPageMargin
|
|
spacing: Theme.paddingSmall
|
|
|
|
Label {
|
|
width: parent.width
|
|
text: model.name
|
|
color: breedItem.highlighted ? Theme.highlightColor : Theme.primaryColor
|
|
truncationMode: TruncationMode.Fade
|
|
}
|
|
|
|
Label {
|
|
width: parent.width
|
|
text: model.description
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
wrapMode: Text.Wrap
|
|
maximumLineCount: 2
|
|
truncationMode: TruncationMode.Elide
|
|
}
|
|
|
|
Label {
|
|
width: parent.width
|
|
text: model.eggColor
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
truncationMode: TruncationMode.Fade
|
|
}
|
|
|
|
Label {
|
|
width: parent.width
|
|
text: model.hens > 0 ? (model.production + " · " + model.hens + " " + page.tr("hens"))
|
|
: model.production
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
truncationMode: TruncationMode.Fade
|
|
}
|
|
}
|
|
|
|
Switch {
|
|
id: switchControl
|
|
anchors {
|
|
right: parent.right
|
|
rightMargin: Theme.horizontalPageMargin
|
|
verticalCenter: photo.verticalCenter
|
|
}
|
|
checked: model.enabled
|
|
onClicked: page.toggleBreed(model.n)
|
|
}
|
|
}
|
|
|
|
VerticalScrollDecorator {}
|
|
}
|
|
|
|
Dialog {
|
|
id: confirmDialog
|
|
property string pendingId: ""
|
|
|
|
Column {
|
|
width: parent.width
|
|
|
|
DialogHeader {
|
|
title: page.tr("confirm_deactivation")
|
|
acceptText: page.tr("deactivate")
|
|
}
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: page.tr("delete_msg")
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
wrapMode: Text.Wrap
|
|
}
|
|
}
|
|
|
|
onAccepted: page.removeBreed(confirmDialog.pendingId)
|
|
}
|
|
}
|