schermate di configurazione complete: razze disponibili, mio pollaio, registro galline, clienti, backup/ripristino nel formato dell'app Android, lingua a runtime, introduzione e informazioni
- 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
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
import QtQuick 2.2
|
||||
import Sailfish.Silica 1.0
|
||||
import "../js/henflow.js" as HF
|
||||
import "../js/i18n.js" as I18N
|
||||
import "../js/catalog.js" as Catalog
|
||||
|
||||
// Nuova gallina / modifica di una gallina: nome, data di nascita e stato di
|
||||
// deposizione. La data si sceglie con tre selettori (giorno, mese, anno):
|
||||
// la combinazione viene mostrata e controllata subito (niente date impossibili).
|
||||
// Come nell'app Flutter, alla scelta della data lo stato si adegua da solo:
|
||||
// sotto i 6 mesi la gallina non e' in deposizione.
|
||||
Page {
|
||||
id: page
|
||||
allowedOrientations: Orientation.All
|
||||
|
||||
property string breedId: ""
|
||||
property var hen: null // null = nuova gallina
|
||||
property string lang: "en"
|
||||
|
||||
property int year: 0
|
||||
property int month: 1
|
||||
property int day: 1
|
||||
property int daysInMonth: 31
|
||||
property bool laying: true
|
||||
property string errorMsg: ""
|
||||
|
||||
readonly property int firstYear: 2010
|
||||
|
||||
function tr(key, arg) { return I18N.t(key, arg, page.lang) }
|
||||
|
||||
function monthLength(y, m) {
|
||||
// giorni del mese: il 31 c'e' solo dove esiste davvero
|
||||
if (m === 2)
|
||||
return (y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0)) ? 29 : 28
|
||||
if (m === 4 || m === 6 || m === 9 || m === 11)
|
||||
return 30
|
||||
return 31
|
||||
}
|
||||
|
||||
function isoOfSelection() {
|
||||
return HF.isoDay(new Date(page.year, page.month - 1, page.day))
|
||||
+ "T00:00:00.000"
|
||||
}
|
||||
|
||||
function monthsOfSelection() {
|
||||
return HF.ageInMonths(new Date(page.year, page.month - 1, page.day), HF.todayMidnight())
|
||||
}
|
||||
|
||||
function refreshSelection() {
|
||||
page.daysInMonth = page.monthLength(page.year, page.month)
|
||||
if (page.day > page.daysInMonth)
|
||||
page.day = page.daysInMonth
|
||||
}
|
||||
|
||||
function applyDefaultDate() {
|
||||
// Come l'originale: si parte da 180 giorni fa (una gallina in deposizione)
|
||||
var d = HF.addDays(HF.todayMidnight(), -180)
|
||||
page.year = d.getFullYear()
|
||||
page.month = d.getMonth() + 1
|
||||
page.day = d.getDate()
|
||||
page.refreshSelection()
|
||||
}
|
||||
|
||||
function reload() {
|
||||
page.lang = I18N.langFor(appSettings.language, Qt.locale().name)
|
||||
|
||||
if (page.hen) {
|
||||
var birth = HF.parseIso(page.hen.birthDate)
|
||||
if (birth) {
|
||||
page.year = birth.getFullYear()
|
||||
page.month = birth.getMonth() + 1
|
||||
page.day = birth.getDate()
|
||||
} else {
|
||||
page.applyDefaultDate()
|
||||
}
|
||||
page.laying = page.hen.isLaying
|
||||
nameField.text = page.hen.name
|
||||
} else {
|
||||
page.applyDefaultDate()
|
||||
page.laying = page.monthsOfSelection() >= 6
|
||||
}
|
||||
page.refreshSelection()
|
||||
}
|
||||
|
||||
function save() {
|
||||
var name = nameField.text.trim()
|
||||
if (name.length === 0) {
|
||||
page.errorMsg = page.tr("hen_name")
|
||||
return
|
||||
}
|
||||
|
||||
var settings = appData.breedSettings()
|
||||
var target = null
|
||||
for (var i = 0; i < settings.length; i++) {
|
||||
if (settings[i].breedId === page.breedId)
|
||||
target = settings[i]
|
||||
}
|
||||
if (!target) {
|
||||
page.errorMsg = page.tr("config_breed_first")
|
||||
return
|
||||
}
|
||||
if (!target.hens)
|
||||
target.hens = []
|
||||
|
||||
var record = {
|
||||
"id": page.hen ? page.hen.id : HF.newId(),
|
||||
"name": name,
|
||||
"birthDate": page.isoOfSelection(),
|
||||
"isLaying": page.laying
|
||||
}
|
||||
|
||||
if (page.hen) {
|
||||
for (var j = 0; j < target.hens.length; j++) {
|
||||
if (target.hens[j].id === record.id)
|
||||
target.hens[j] = record
|
||||
}
|
||||
} else {
|
||||
target.hens.push(record)
|
||||
}
|
||||
|
||||
appData.saveBreedSettings(settings)
|
||||
pageStack.pop()
|
||||
}
|
||||
|
||||
Component.onCompleted: page.reload()
|
||||
|
||||
SilicaFlickable {
|
||||
anchors.fill: parent
|
||||
contentHeight: form.height
|
||||
|
||||
Column {
|
||||
id: form
|
||||
width: parent.width
|
||||
spacing: Theme.paddingMedium
|
||||
|
||||
PageHeader { title: page.tr("new_hen") }
|
||||
|
||||
TextField {
|
||||
id: nameField
|
||||
width: parent.width
|
||||
label: page.tr("hen_name")
|
||||
placeholderText: page.tr("hen_name")
|
||||
EnterKey.enabled: true
|
||||
EnterKey.onClicked: page.save()
|
||||
}
|
||||
|
||||
SectionHeader { text: page.tr("birth_date") }
|
||||
|
||||
Row {
|
||||
x: Theme.horizontalPageMargin
|
||||
width: parent.width - 2 * Theme.horizontalPageMargin
|
||||
spacing: Theme.paddingSmall
|
||||
|
||||
ComboBox {
|
||||
id: dayBox
|
||||
width: (parent.width - 2 * parent.spacing) / 3
|
||||
label: "DD"
|
||||
menu: ContextMenu {
|
||||
Repeater {
|
||||
model: page.daysInMonth
|
||||
delegate: MenuItem {
|
||||
text: String(index + 1)
|
||||
onClicked: {
|
||||
page.day = index + 1
|
||||
dayBox.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: monthBox
|
||||
width: (parent.width - 2 * parent.spacing) / 3
|
||||
label: "MM"
|
||||
menu: ContextMenu {
|
||||
Repeater {
|
||||
model: 12
|
||||
delegate: MenuItem {
|
||||
text: String(index + 1)
|
||||
onClicked: {
|
||||
page.month = index + 1
|
||||
page.refreshSelection()
|
||||
monthBox.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: yearBox
|
||||
width: (parent.width - 2 * parent.spacing) / 3
|
||||
label: "YYYY"
|
||||
menu: ContextMenu {
|
||||
Repeater {
|
||||
model: HF.todayMidnight().getFullYear() - page.firstYear + 1
|
||||
delegate: MenuItem {
|
||||
text: String(page.firstYear + index)
|
||||
onClicked: {
|
||||
page.year = page.firstYear + index
|
||||
page.refreshSelection()
|
||||
yearBox.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
x: Theme.horizontalPageMargin
|
||||
width: parent.width - 2 * Theme.horizontalPageMargin
|
||||
spacing: Theme.paddingSmall
|
||||
|
||||
Label {
|
||||
width: parent.width
|
||||
text: page.tr("birth") + ": " + HF.formatDay(page.isoOfSelection())
|
||||
color: Theme.primaryColor
|
||||
truncationMode: TruncationMode.Fade
|
||||
}
|
||||
|
||||
Label {
|
||||
width: parent.width
|
||||
text: page.tr("age_months", page.monthsOfSelection())
|
||||
+ " · " + (page.monthsOfSelection() >= 6 ? page.tr("laying_6_months") : page.tr("status_young"))
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
truncationMode: TruncationMode.Fade
|
||||
}
|
||||
}
|
||||
|
||||
TextSwitch {
|
||||
id: layingSwitch
|
||||
text: page.tr("in_laying")
|
||||
checked: page.laying
|
||||
onClicked: page.laying = !page.laying
|
||||
}
|
||||
|
||||
Label {
|
||||
x: Theme.horizontalPageMargin
|
||||
width: parent.width - 2 * Theme.horizontalPageMargin
|
||||
text: page.errorMsg
|
||||
color: Theme.errorColor
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
wrapMode: Text.Wrap
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: page.tr("save")
|
||||
onClicked: page.save()
|
||||
}
|
||||
|
||||
Item { width: parent.width; height: Theme.paddingLarge }
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user