0.7.10: cambio lingua in due mosse + diagnosi lingua nel /layout

Misurato in container: la ricarica della radice ri-traduce, il catalogo si trova
anche con it_IT. La ricarica ora scarica la radice prima di ricaricarla, cosi'
non dipende da un comportamento di setSource che cambia fra versioni di Qt.
This commit is contained in:
Carlo
2026-10-11 19:01:07 +02:00
parent 78eb283c9b
commit e9527f66bb
8 changed files with 115 additions and 54 deletions
+26 -1
View File
@@ -600,7 +600,32 @@ la domanda "cos'è la striscia bianca sotto l'acqua calda?").
Regola: un indicatore permanente che resta sempre allo stesso valore è rumore. Regola: un indicatore permanente che resta sempre allo stesso valore è rumore.
Se un giorno servisse, va ancorato a qualcosa che cambia davvero. Se un giorno servisse, va ancorato a qualcosa che cambia davvero.
## 21. Conseguenze dell'uso reale (0.7.0) ## 22. Il cambio lingua — v0.7.10
Carlo: *"Tutto perfetto. Solo il cambio lingua non sembra funzionare"*.
Misurato invece che dedotto, con un banco vero in container (Qt 5.15, non 5.6:
differenza che conta). Esiti:
1. installare il traduttore **non** ri-traduce le stringhe gia' a schermo
(conferma: Qt 5.6 non ha `retranslate()`);
2. `setSource()` con la **stessa** url **ri-traduce** (House -> Casa): la
tecnica dell'app e' quella giusta;
3. il catalogo si trova **anche** con locale `it_IT`: `load()` ripiega sul nome
accorciato `it`; e nel pacchetto sta in
`/usr/share/harbour-aira/translations/harbour-aira-it.qm`, la cartella che
l'app cerca.
Restava un'unica differenza fra banco e telefono: la versione di Qt. La
ricarica si affidava a un comportamento di `setSource(stessa url)` che cambia
fra versioni, quindi ora si fa in due mosse — radice scaricata con url vuota,
poi ricaricata: cosi' il componente **deve** essere ricreato, su qualunque Qt.
E per non indovinare piu': la Home manda al `/layout` anche `lingua`, `locale` e
`catalogo`, cosi' il registro del bridge dice cosa sta usando davvero il
telefono.
## 23. Conseguenze dell'uso reale (0.7.0)
Deciso con l'uso, non in anticipo: Deciso con l'uso, non in anticipo:
+6 -1
View File
@@ -400,7 +400,12 @@ Page {
"versione": appVersion, "versione": appVersion,
"schermo": Math.round(height), "schermo": Math.round(height),
"contenuto": Math.round(flick.contentHeight), "contenuto": Math.round(flick.contentHeight),
"righe": righe "righe": righe,
// Diagnostica della lingua: con che scelta, che locale e che
// catalogo sta girando l'app in questo momento.
"lingua": translator.language === "" ? "sistema" : translator.language,
"locale": translator.localeName,
"catalogo": translator.catalogLoaded
}) })
} }
} }
+7 -1
View File
@@ -1,6 +1,6 @@
Name: harbour-aira Name: harbour-aira
Summary: Control your Aira heat pump through a local bridge Summary: Control your Aira heat pump through a local bridge
Version: 0.7.9 Version: 0.7.10
Release: 1 Release: 1
Group: Qt/Qt Group: Qt/Qt
License: MIT License: MIT
@@ -37,6 +37,12 @@ Address and token of the bridge live in the app settings (AppConfigLocation);
no personal data is stored in the binary. no personal data is stored in the binary.
%changelog %changelog
* Sun Oct 11 2026 Carlo <carlo@carlobaratto.it> - 0.7.10-1
- cambio lingua: la ricarica della radice QML ora e' in due mosse (url vuota,
poi ricarica), cosi' il componente viene ricreato su qualunque versione di Qt
invece di affidarsi a un comportamento che cambia fra versioni.
- diagnosi: la Home manda al /layout anche lingua, locale e catalogo, perche'
un difetto di lingua sul telefono si possa leggere invece che indovinare.
* Sun Oct 11 2026 Carlo <carlo@carlobaratto.it> - 0.7.9-1 * Sun Oct 11 2026 Carlo <carlo@carlobaratto.it> - 0.7.9-1
- via la barra di avanzamento sotto l'acqua calda: partiva da 10 °C e stava - via la barra di avanzamento sotto l'acqua calda: partiva da 10 °C e stava
sempre al 99%, quindi non diceva niente. Tolta dal componente ReadingCell sempre al 99%, quindi non diceva niente. Tolta dal componente ReadingCell
+9 -7
View File
@@ -21,7 +21,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
app->setOrganizationName(QStringLiteral("harbour")); app->setOrganizationName(QStringLiteral("harbour"));
app->setApplicationName(QStringLiteral("aira")); app->setApplicationName(QStringLiteral("aira"));
app->setApplicationVersion(QStringLiteral("0.7.9")); app->setApplicationVersion(QStringLiteral("0.7.10"));
Settings settings; Settings settings;
ApiClient api(&settings); ApiClient api(&settings);
@@ -36,7 +36,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
// Prima riga del log: dice subito se il device sta girando la build nuova // Prima riga del log: dice subito se il device sta girando la build nuova
// o una stale (trappola nota del build engine). // o una stale (trappola nota del build engine).
qDebug() << "harbour-aira v0.7.9 build" << __DATE__ << __TIME__; qDebug() << "harbour-aira v0.7.10 build" << __DATE__ << __TIME__;
view->rootContext()->setContextProperty(QStringLiteral("appSettings"), &settings); view->rootContext()->setContextProperty(QStringLiteral("appSettings"), &settings);
view->rootContext()->setContextProperty(QStringLiteral("api"), &api); view->rootContext()->setContextProperty(QStringLiteral("api"), &api);
@@ -52,12 +52,14 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
// scelta nelle impostazioni si applica ricaricando la radice QML. Conseguenza // scelta nelle impostazioni si applica ricaricando la radice QML. Conseguenza
// voluta e attesa: si torna alla home, nella lingua nuova. // voluta e attesa: si torna alla home, nella lingua nuova.
// //
// setSource() con la STESSA url ricrea davvero il componente: in Qt 5.6 // La ricarica si fa in DUE mosse: prima si scarica la radice (url vuota), poi
// QQuickViewPrivate::execute() cancella root e component e ne costruisce uno // si ricarica. Una sola setSource con la STESSA url e' un comportamento che
// nuovo (documentato: "the QML component being instantiated, even if the URL // cambia fra le versioni di Qt (misurato su Qt 5.15: ricrea; su 5.6 non e'
// is unchanged"), quindi ogni qsTr() viene rivalutato. Non serve // garantito) e il telefono non e' la macchina su cui si prova. Con l'url vuota
// clearComponentCache(): i valori delle stringhe non stanno nella cache. // il componente e' per forza ricreato, quindi ogni qsTr() viene rivalutato.
// Non serve clearComponentCache(): le stringhe non stanno nella cache.
QObject::connect(&translator, &Translator::languageChanged, view, [view]() { QObject::connect(&translator, &Translator::languageChanged, view, [view]() {
view->setSource(QUrl());
view->setSource(SailfishApp::pathTo(QStringLiteral("qml/harbour-aira.qml"))); view->setSource(SailfishApp::pathTo(QStringLiteral("qml/harbour-aira.qml")));
}); });
+13
View File
@@ -40,6 +40,16 @@ void Translator::applySaved()
apply(language()); apply(language());
} }
bool Translator::catalogLoaded() const
{
return m_catalogLoaded;
}
QString Translator::localeName() const
{
return m_localeName;
}
void Translator::apply(const QString &value) void Translator::apply(const QString &value)
{ {
if (m_translator) { if (m_translator) {
@@ -67,6 +77,9 @@ void Translator::apply(const QString &value)
delete translator; delete translator;
} }
m_localeName = locale.name();
m_catalogLoaded = !m_translator.isNull();
qDebug() << "Translator: richiesta [" qDebug() << "Translator: richiesta ["
<< (value.isEmpty() ? QStringLiteral("sistema") : value) << (value.isEmpty() ? QStringLiteral("sistema") : value)
<< "] locale" << locale.name() << "] locale" << locale.name()
+10
View File
@@ -27,6 +27,11 @@ class Translator : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged) Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
// Diagnostica: quali valori sono in vigore davvero. Finiscono nel /layout che
// la Home manda al bridge, cosi' un problema di lingua sul telefono si legge
// invece di indovinarlo.
Q_PROPERTY(bool catalogLoaded READ catalogLoaded)
Q_PROPERTY(QString localeName READ localeName)
public: public:
explicit Translator(Settings *settings, QObject *parent = 0); explicit Translator(Settings *settings, QObject *parent = 0);
@@ -35,6 +40,9 @@ public:
void setLanguage(const QString &value); // salva nelle impostazioni e applica void setLanguage(const QString &value); // salva nelle impostazioni e applica
void applySaved(); // all'avvio, PRIMA di creare la view void applySaved(); // all'avvio, PRIMA di creare la view
bool catalogLoaded() const; // catalogo installato?
QString localeName() const; // locale in vigore (es. it_IT)
signals: signals:
void languageChanged(); void languageChanged();
@@ -43,6 +51,8 @@ private:
Settings *m_settings; Settings *m_settings;
QPointer<QTranslator> m_translator; QPointer<QTranslator> m_translator;
QString m_localeName;
bool m_catalogLoaded = false;
}; };
#endif // TRANSLATOR_H #endif // TRANSLATOR_H
+22 -22
View File
@@ -521,104 +521,104 @@
<context> <context>
<name>MainPage</name> <name>MainPage</name>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="62"/> <location filename="../qml/pages/MainPage.qml" line="53"/>
<source>No data yet</source> <source>No data yet</source>
<translation>Nessun dato</translation> <translation>Nessun dato</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="64"/> <location filename="../qml/pages/MainPage.qml" line="55"/>
<source>Not updated · last %1</source> <source>Not updated · last %1</source>
<translation>Non aggiornato · ultimo %1</translation> <translation>Non aggiornato · ultimo %1</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="67"/> <location filename="../qml/pages/MainPage.qml" line="58"/>
<source>Updated at %1</source> <source>Updated at %1</source>
<translation>Aggiornato alle %1</translation> <translation>Aggiornato alle %1</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="112"/> <location filename="../qml/pages/MainPage.qml" line="103"/>
<source>Refresh</source> <source>Refresh</source>
<translation>Aggiorna</translation> <translation>Aggiorna</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="124"/> <location filename="../qml/pages/MainPage.qml" line="115"/>
<location filename="../qml/pages/MainPage.qml" line="153"/> <location filename="../qml/pages/MainPage.qml" line="144"/>
<source>Settings</source> <source>Settings</source>
<translation>Impostazioni</translation> <translation>Impostazioni</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="210"/> <location filename="../qml/pages/MainPage.qml" line="201"/>
<source>House</source> <source>House</source>
<translation>Casa</translation> <translation>Casa</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="212"/> <location filename="../qml/pages/MainPage.qml" line="203"/>
<location filename="../qml/pages/MainPage.qml" line="222"/> <location filename="../qml/pages/MainPage.qml" line="213"/>
<source>target %1 °C</source> <source>target %1 °C</source>
<translation>obiettivo %1 °C</translation> <translation>obiettivo %1 °C</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="220"/> <location filename="../qml/pages/MainPage.qml" line="211"/>
<source>Hot water</source> <source>Hot water</source>
<translation>Acqua calda</translation> <translation>Acqua calda</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="248"/> <location filename="../qml/pages/MainPage.qml" line="237"/>
<source>Boost · %1</source> <source>Boost · %1</source>
<translation>Boost · %1</translation> <translation>Boost · %1</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="259"/> <location filename="../qml/pages/MainPage.qml" line="248"/>
<source>Tap a value to adjust it</source> <source>Tap a value to adjust it</source>
<translation>Tocca un valore per regolarlo</translation> <translation>Tocca un valore per regolarlo</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="268"/> <location filename="../qml/pages/MainPage.qml" line="257"/>
<source>Quick actions</source> <source>Quick actions</source>
<translation>Azioni rapide</translation> <translation>Azioni rapide</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="292"/> <location filename="../qml/pages/MainPage.qml" line="281"/>
<source>Boost</source> <source>Boost</source>
<translation>Boost</translation> <translation>Boost</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="292"/> <location filename="../qml/pages/MainPage.qml" line="281"/>
<source>Stop</source> <source>Stop</source>
<translation>Stop</translation> <translation>Stop</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="312"/> <location filename="../qml/pages/MainPage.qml" line="301"/>
<source>Home</source> <source>Home</source>
<translation>Torna</translation> <translation>Torna</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="312"/> <location filename="../qml/pages/MainPage.qml" line="301"/>
<source>Away</source> <source>Away</source>
<translation>Assenza</translation> <translation>Assenza</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="339"/> <location filename="../qml/pages/MainPage.qml" line="328"/>
<source>More</source> <source>More</source>
<translation>Altro</translation> <translation>Altro</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="362"/> <location filename="../qml/pages/MainPage.qml" line="351"/>
<source>Outside %1 °C · Thermostat %2 °C · Zones %3</source> <source>Outside %1 °C · Thermostat %2 °C · Zones %3</source>
<translation>Esterno %1 °C · Termostato %2 °C · Zone %3</translation> <translation>Esterno %1 °C · Termostato %2 °C · Zone %3</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="116"/> <location filename="../qml/pages/MainPage.qml" line="107"/>
<source>Data</source> <source>Data</source>
<translation>Dati</translation> <translation>Dati</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="144"/> <location filename="../qml/pages/MainPage.qml" line="135"/>
<source>Bridge not configured. Open the settings and enter the server address and the token.</source> <source>Bridge not configured. Open the settings and enter the server address and the token.</source>
<translation>Bridge non configurato. Apri le impostazioni e inserisci l&apos;indirizzo del server e il token.</translation> <translation>Bridge non configurato. Apri le impostazioni e inserisci l&apos;indirizzo del server e il token.</translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="120"/> <location filename="../qml/pages/MainPage.qml" line="111"/>
<source>Plant</source> <source>Plant</source>
<translation>Impianto</translation> <translation>Impianto</translation>
</message> </message>
+22 -22
View File
@@ -521,104 +521,104 @@
<context> <context>
<name>MainPage</name> <name>MainPage</name>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="62"/> <location filename="../qml/pages/MainPage.qml" line="53"/>
<source>No data yet</source> <source>No data yet</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="64"/> <location filename="../qml/pages/MainPage.qml" line="55"/>
<source>Not updated · last %1</source> <source>Not updated · last %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="67"/> <location filename="../qml/pages/MainPage.qml" line="58"/>
<source>Updated at %1</source> <source>Updated at %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="112"/> <location filename="../qml/pages/MainPage.qml" line="103"/>
<source>Refresh</source> <source>Refresh</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="116"/> <location filename="../qml/pages/MainPage.qml" line="107"/>
<source>Data</source> <source>Data</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="120"/> <location filename="../qml/pages/MainPage.qml" line="111"/>
<source>Plant</source> <source>Plant</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="124"/> <location filename="../qml/pages/MainPage.qml" line="115"/>
<location filename="../qml/pages/MainPage.qml" line="153"/> <location filename="../qml/pages/MainPage.qml" line="144"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="144"/> <location filename="../qml/pages/MainPage.qml" line="135"/>
<source>Bridge not configured. Open the settings and enter the server address and the token.</source> <source>Bridge not configured. Open the settings and enter the server address and the token.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="210"/> <location filename="../qml/pages/MainPage.qml" line="201"/>
<source>House</source> <source>House</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="212"/> <location filename="../qml/pages/MainPage.qml" line="203"/>
<location filename="../qml/pages/MainPage.qml" line="222"/> <location filename="../qml/pages/MainPage.qml" line="213"/>
<source>target %1 °C</source> <source>target %1 °C</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="220"/> <location filename="../qml/pages/MainPage.qml" line="211"/>
<source>Hot water</source> <source>Hot water</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="248"/> <location filename="../qml/pages/MainPage.qml" line="237"/>
<source>Boost · %1</source> <source>Boost · %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="259"/> <location filename="../qml/pages/MainPage.qml" line="248"/>
<source>Tap a value to adjust it</source> <source>Tap a value to adjust it</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="268"/> <location filename="../qml/pages/MainPage.qml" line="257"/>
<source>Quick actions</source> <source>Quick actions</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="292"/> <location filename="../qml/pages/MainPage.qml" line="281"/>
<source>Boost</source> <source>Boost</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="292"/> <location filename="../qml/pages/MainPage.qml" line="281"/>
<source>Stop</source> <source>Stop</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="312"/> <location filename="../qml/pages/MainPage.qml" line="301"/>
<source>Home</source> <source>Home</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="312"/> <location filename="../qml/pages/MainPage.qml" line="301"/>
<source>Away</source> <source>Away</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="339"/> <location filename="../qml/pages/MainPage.qml" line="328"/>
<source>More</source> <source>More</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/pages/MainPage.qml" line="362"/> <location filename="../qml/pages/MainPage.qml" line="351"/>
<source>Outside %1 °C · Thermostat %2 °C · Zones %3</source> <source>Outside %1 °C · Thermostat %2 °C · Zones %3</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>