Selettore lingua (System/EN/IT) nelle impostazioni con QTranslator in main.cpp (pattern quill); fix 'Close book' con pop fino alla prima pagina

This commit is contained in:
2026-08-19 16:27:36 +02:00
parent e3ba9b5e87
commit d8584f2de4
7 changed files with 176 additions and 71 deletions
+4 -1
View File
@@ -57,7 +57,10 @@ Page {
text: qsTr("Close book")
onClicked: {
page.maybeSave(true)
pageStack.popTo(null)
// torna alla prima pagina dello stack (MainPage):
// popTo(null) non è affidabile su questa Silica
while (pageStack.depth > 1)
pageStack.pop()
}
}
}
+38
View File
@@ -7,6 +7,7 @@ Page {
property string testResult: ""
property bool testOk: false
property bool testing: false
property string languageNotice: ""
SilicaFlickable {
anchors.fill: parent
@@ -111,6 +112,43 @@ Page {
visible: text.length > 0
}
SectionHeader { text: qsTr("Language") }
ComboBox {
id: langBox
width: parent.width
label: qsTr("Language")
currentIndex: appSettings.language === "it" ? 2 : (appSettings.language === "en" ? 1 : 0)
menu: ContextMenu {
MenuItem { text: qsTr("System (default)") }
MenuItem { text: "English" }
MenuItem { text: "Italiano" }
}
onCurrentIndexChanged: {
var v = currentIndex === 2 ? "it" : (currentIndex === 1 ? "en" : "system")
if (v !== appSettings.language) {
appSettings.language = v
page.languageNotice = qsTr("Language will be applied after restarting the app")
langNoticeTimer.restart()
}
}
}
Label {
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: page.languageNotice
color: Theme.highlightColor
wrapMode: Text.Wrap
visible: text.length > 0
}
Timer {
id: langNoticeTimer
interval: 4000
onTriggered: page.languageNotice = ""
}
Item { width: 1; height: Theme.paddingLarge }
}
}
+3
View File
@@ -25,6 +25,9 @@ in locale.
%changelog
* Wed Aug 19 2026 Carlo Baratto <carlo@carlobaratto.it> - 0.2.0-1
- Selettore lingua nelle impostazioni (System/English/Italiano, applicata al
riavvio; QTranslator in main.cpp, pattern quill)
- Fix 'Close book': pop fino alla prima pagina (popTo(null) non affidabile)
- Localizzazione: lingua di default inglese (qsTr ovunque), catalogo
italiano harbour-calibreweb_it.ts/.qm installato in /usr/share/translations
- Fix configurazione persa: file di configurazione unico e fisso
+25 -1
View File
@@ -2,6 +2,7 @@
#include <QGuiApplication>
#include <QQuickView>
#include <QQmlContext>
#include <QTranslator>
#include <sailfishapp.h>
#include "apiclient.h"
@@ -12,13 +13,36 @@
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QGuiApplication *app = SailfishApp::application(argc, argv);
Settings settings;
// User-chosen language (Settings -> Language). "system" = Sailfish UI
// language (libsailfishapp already installed its translator). "en" =
// force English (remove all translators). "it" = force Italian.
const QString lang = settings.language();
if (lang == "en" || lang == "it") {
const QList<QTranslator *> trs = app->findChildren<QTranslator *>();
foreach (QTranslator *t, trs) {
app->removeTranslator(t);
t->deleteLater();
}
if (lang == "it") {
QTranslator *translator = new QTranslator(app);
if (translator->load(QStringLiteral("harbour-calibreweb_it"),
QStringLiteral("/usr/share/translations"))) {
app->installTranslator(translator);
} else {
qWarning() << "harbour-calibreweb: cannot load harbour-calibreweb_it.qm";
}
}
}
QQuickView *view = SailfishApp::createView();
qDebug() << "harbour-calibreweb v0.2.0 build" << __DATE__ << __TIME__;
qmlRegisterType<EpubBook>("harbour.calibreweb", 1, 0, "EpubBook");
Settings settings;
ApiClient apiClient(&settings);
Downloader downloader(&settings);
+14
View File
@@ -152,6 +152,20 @@ void Settings::setReaderMarginV(int value)
emit readerMarginVChanged();
}
QString Settings::language() const
{
return m_settings.value(QStringLiteral("language"), QStringLiteral("system")).toString();
}
void Settings::setLanguage(const QString &value)
{
if (value == language())
return;
m_settings.setValue(QStringLiteral("language"), value);
m_settings.sync();
emit languageChanged();
}
QString Settings::downloadDir() const
{
QString dir = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+7
View File
@@ -14,6 +14,8 @@ class Settings : public QObject
Q_PROPERTY(bool ignoreSslErrors READ ignoreSslErrors WRITE setIgnoreSslErrors NOTIFY ignoreSslErrorsChanged)
Q_PROPERTY(int readerMargin READ readerMargin WRITE setReaderMargin NOTIFY readerMarginChanged)
Q_PROPERTY(int readerMarginV READ readerMarginV WRITE setReaderMarginV NOTIFY readerMarginVChanged)
// lingua scelta dall'utente: "system" (predefinita, lingua UI Sailfish), "en", "it"
Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
Q_PROPERTY(QString downloadDir READ downloadDir CONSTANT)
// derivata da serverUrl (senza slash finale): accesso QML come appSettings.baseUrl
Q_PROPERTY(QString baseUrl READ baseUrl NOTIFY baseUrlChanged)
@@ -41,6 +43,10 @@ public:
int readerMarginV() const;
void setReaderMarginV(int value);
// lingua dell'interfaccia: "system" (default) | "en" | "it"
QString language() const;
void setLanguage(const QString &value);
QString downloadDir() const;
// Header "Authorization: Basic ..." pronto da usare, vuoto se utente non impostato
@@ -63,6 +69,7 @@ signals:
void ignoreSslErrorsChanged();
void readerMarginChanged();
void readerMarginVChanged();
void languageChanged();
void baseUrlChanged();
private:
+85 -69
View File
@@ -5,27 +5,27 @@
<message>
<location filename="../qml/pages/BookDetailPage.qml" line="36" />
<source>Read (EPUB)</source>
<translation type="finished">Leggi (EPUB)</translation>
<translation>Leggi (EPUB)</translation>
</message>
<message>
<location filename="../qml/pages/BookDetailPage.qml" line="60" />
<source>Formats</source>
<translation type="finished">Formati</translation>
<translation>Formati</translation>
</message>
<message>
<location filename="../qml/pages/BookDetailPage.qml" line="112" />
<source>Downloading</source>
<translation type="finished">Download in corso</translation>
<translation>Download in corso</translation>
</message>
<message>
<location filename="../qml/pages/BookDetailPage.qml" line="261" />
<source>Saved to </source>
<translation type="finished">Salvato in </translation>
<translation>Salvato in </translation>
</message>
<message>
<location filename="../qml/pages/BookDetailPage.qml" line="266" />
<source>Error: </source>
<translation type="finished">Errore: </translation>
<translation>Errore: </translation>
</message>
</context>
<context>
@@ -33,12 +33,12 @@
<message>
<location filename="../qml/pages/ChapterListDialog.qml" line="12" />
<source>Table of contents</source>
<translation type="finished">Indice capitoli</translation>
<translation>Indice capitoli</translation>
</message>
<message>
<location filename="../qml/pages/ChapterListDialog.qml" line="38" />
<source>No chapters</source>
<translation type="finished">Nessun capitolo</translation>
<translation>Nessun capitolo</translation>
</message>
</context>
<context>
@@ -46,7 +46,7 @@
<message>
<location filename="../qml/cover/CoverPage.qml" line="18" />
<source>Calibre Web</source>
<translation type="finished">Calibre Web</translation>
<translation>Calibre Web</translation>
</message>
</context>
<context>
@@ -54,18 +54,18 @@
<message>
<location filename="../qml/pages/FeedPage.qml" line="91" />
<source>Refresh</source>
<translation type="finished">Aggiorna</translation>
<translation>Aggiorna</translation>
</message>
<message>
<location filename="../qml/pages/FeedPage.qml" line="95" />
<source>Settings</source>
<translation type="finished">Impostazioni</translation>
<translation>Impostazioni</translation>
</message>
<message>
<location filename="../qml/pages/FeedPage.qml" line="102" />
<location filename="../qml/pages/FeedPage.qml" line="171" />
<source>No results</source>
<translation type="finished">Nessun risultato</translation>
<translation>Nessun risultato</translation>
</message>
</context>
<context>
@@ -73,37 +73,37 @@
<message>
<location filename="../qml/pages/MainPage.qml" line="13" />
<source>Calibre Web</source>
<translation type="finished">Calibre Web</translation>
<translation>Calibre Web</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="43" />
<source>Search</source>
<translation type="finished">Cerca</translation>
<translation>Cerca</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="47" />
<source>Settings</source>
<translation type="finished">Impostazioni</translation>
<translation>Impostazioni</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="51" />
<source>Refresh</source>
<translation type="finished">Aggiorna</translation>
<translation>Aggiorna</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="60" />
<source>Open the settings and enter your Calibre Web address</source>
<translation type="finished">Apri le impostazioni e inserisci l'indirizzo del tuo Calibre Web</translation>
<translation>Apri le impostazioni e inserisci l'indirizzo del tuo Calibre Web</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="77" />
<source>Server not configured</source>
<translation type="finished">Server non configurato</translation>
<translation>Server non configurato</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="100" />
<source>No sections found in the OPDS feed</source>
<translation type="finished">Nessuna sezione trovata nel feed OPDS</translation>
<translation>Nessuna sezione trovata nel feed OPDS</translation>
</message>
</context>
<context>
@@ -111,27 +111,27 @@
<message>
<location filename="../qml/pages/MarginDialog.qml" line="25" />
<source>Text margins</source>
<translation type="finished">Margini del testo</translation>
<translation>Margini del testo</translation>
</message>
<message>
<location filename="../qml/pages/MarginDialog.qml" line="26" />
<source>Apply</source>
<translation type="finished">Applica</translation>
<translation>Applica</translation>
</message>
<message>
<location filename="../qml/pages/MarginDialog.qml" line="32" />
<source>Side margins</source>
<translation type="finished">Margini laterali</translation>
<translation>Margini laterali</translation>
</message>
<message>
<location filename="../qml/pages/MarginDialog.qml" line="47" />
<source>Top and bottom</source>
<translation type="finished">Alto e basso</translation>
<translation>Alto e basso</translation>
</message>
<message>
<location filename="../qml/pages/MarginDialog.qml" line="62" />
<source>Changes apply immediately. Confirm to save them for all books.</source>
<translation type="finished">Le modifiche si applicano subito al testo. Conferma per salvarle per tutti i libri.</translation>
<translation>Le modifiche si applicano subito al testo. Conferma per salvarle per tutti i libri.</translation>
</message>
</context>
<context>
@@ -139,37 +139,37 @@
<message>
<location filename="../qml/pages/ReaderPage.qml" line="35" />
<source>Table of contents</source>
<translation type="finished">Indice capitoli</translation>
<translation>Indice capitoli</translation>
</message>
<message>
<location filename="../qml/pages/ReaderPage.qml" line="39" />
<source>Text margins</source>
<translation type="finished">Margini del testo</translation>
<translation>Margini del testo</translation>
</message>
<message>
<location filename="../qml/pages/ReaderPage.qml" line="53" />
<source>Settings</source>
<translation type="finished">Impostazioni</translation>
<translation>Impostazioni</translation>
</message>
<message>
<location filename="../qml/pages/ReaderPage.qml" line="57" />
<source>Close book</source>
<translation type="finished">Chiudi libro</translation>
<translation>Chiudi libro</translation>
</message>
<message>
<location filename="../qml/pages/ReaderPage.qml" line="167" />
<location filename="../qml/pages/ReaderPage.qml" line="170" />
<source>The reader is not responding (WebView). The EPUB file may be damaged.</source>
<translation type="finished">Il lettore non risponde (WebView). Il file EPUB potrebbe essere danneggiato.</translation>
<translation>Il lettore non risponde (WebView). Il file EPUB potrebbe essere danneggiato.</translation>
</message>
<message>
<location filename="../qml/pages/ReaderPage.qml" line="290" />
<location filename="../qml/pages/ReaderPage.qml" line="293" />
<source>Chapter unreadable</source>
<translation type="finished">Capitolo non leggibile</translation>
<translation>Capitolo non leggibile</translation>
</message>
<message>
<location filename="../qml/pages/ReaderPage.qml" line="339" />
<location filename="../qml/pages/ReaderPage.qml" line="342" />
<source>Unable to open the EPUB file</source>
<translation type="finished">Impossibile aprire il libro EPUB</translation>
<translation>Impossibile aprire il libro EPUB</translation>
</message>
</context>
<context>
@@ -178,100 +178,116 @@
<location filename="../qml/pages/SearchPage.qml" line="15" />
<location filename="../qml/pages/SearchPage.qml" line="27" />
<source>Search</source>
<translation type="finished">Cerca</translation>
<translation>Cerca</translation>
</message>
<message>
<location filename="../qml/pages/SearchPage.qml" line="20" />
<source>Title or author…</source>
<translation type="finished">Titolo o autore…</translation>
<translation>Titolo o autore…</translation>
</message>
<message>
<location filename="../qml/pages/SearchPage.qml" line="35" />
<source>Search uses the server engine (OPDS search).</source>
<translation type="finished">La ricerca usa il motore del server (OPDS search).</translation>
<translation>La ricerca usa il motore del server (OPDS search).</translation>
</message>
<message>
<location filename="../qml/pages/SearchPage.qml" line="50" />
<source>Results: </source>
<translation type="finished">Risultati: </translation>
<translation>Risultati: </translation>
</message>
</context>
<context>
<name>SettingsPage</name>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="19" />
<location filename="../qml/pages/SettingsPage.qml" line="20" />
<source>Settings</source>
<translation type="finished">Impostazioni</translation>
<translation>Impostazioni</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="21" />
<location filename="../qml/pages/SettingsPage.qml" line="22" />
<source>Server</source>
<translation type="finished">Server</translation>
<translation>Server</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="27" />
<location filename="../qml/pages/SettingsPage.qml" line="28" />
<source>Calibre Web address</source>
<translation type="finished">Indirizzo Calibre Web</translation>
<translation>Indirizzo Calibre Web</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="38" />
<location filename="../qml/pages/SettingsPage.qml" line="39" />
<source>User (empty = anonymous access)</source>
<translation type="finished">Utente (vuoto = accesso anonimo)</translation>
<translation>Utente (vuoto = accesso anonimo)</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="47" />
<location filename="../qml/pages/SettingsPage.qml" line="48" />
<source>Password</source>
<translation type="finished">Password</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="54" />
<source>Ignore SSL certificate errors</source>
<translation type="finished">Ignora errori certificato SSL</translation>
<translation>Password</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="55" />
<source>Ignore SSL certificate errors</source>
<translation>Ignora errori certificato SSL</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="56" />
<source>Enable if the server uses a self-signed certificate</source>
<translation type="finished">Da attivare se il server usa un certificato autofirmato</translation>
<translation>Da attivare se il server usa un certificato autofirmato</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="60" />
<location filename="../qml/pages/SettingsPage.qml" line="61" />
<source>Reader</source>
<translation type="finished">Lettore</translation>
<translation>Lettore</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="65" />
<location filename="../qml/pages/SettingsPage.qml" line="66" />
<source>Side margins</source>
<translation type="finished">Margini laterali</translation>
<translation>Margini laterali</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="77" />
<location filename="../qml/pages/SettingsPage.qml" line="78" />
<source>Top and bottom margin</source>
<translation type="finished">Margine alto e basso</translation>
<translation>Margine alto e basso</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="86" />
<location filename="../qml/pages/SettingsPage.qml" line="87" />
<source>Connection</source>
<translation type="finished">Connessione</translation>
<translation>Connessione</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="90" />
<location filename="../qml/pages/SettingsPage.qml" line="91" />
<source>Test connection</source>
<translation type="finished">Prova connessione</translation>
<translation>Prova connessione</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="121" />
<location filename="../qml/pages/SettingsPage.qml" line="115" />
<location filename="../qml/pages/SettingsPage.qml" line="120" />
<source>Language</source>
<translation type="finished">Lingua</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="123" />
<source>System (default)</source>
<translation type="finished">Sistema (predefinita)</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="131" />
<source>Language will be applied after restarting the app</source>
<translation type="finished">La lingua verrà applicata al riavvio dell'app</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="159" />
<source>Enter the server address</source>
<translation type="finished">Inserisci l'indirizzo del server</translation>
<translation>Inserisci l'indirizzo del server</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="130" />
<location filename="../qml/pages/SettingsPage.qml" line="168" />
<source>Testing</source>
<translation type="finished">Verifica in corso</translation>
<translation>Verifica in corso</translation>
</message>
<message>
<location filename="../qml/pages/SettingsPage.qml" line="141" />
<location filename="../qml/pages/SettingsPage.qml" line="179" />
<source>Connection OK: %1 sections found</source>
<translation type="finished">Connessione OK: %1 sezioni trovate</translation>
<translation>Connessione OK: %1 sezioni trovate</translation>
</message>
</context>
</TS>