Audit best practice 0.4.8: orientazioni per pagina (reader in landscape), licenza nel pacchetto, EPUB lazy lengths, cover dinamica (ReaderState), flush config senza sync per tasto, pulizia chapterFraction/commenti
This commit is contained in:
@@ -10,14 +10,16 @@ SOURCES += \
|
||||
src/apiclient.cpp \
|
||||
src/downloader.cpp \
|
||||
src/opdsparser.cpp \
|
||||
src/epub.cpp
|
||||
src/epub.cpp \
|
||||
src/readerstate.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/settings.h \
|
||||
src/apiclient.h \
|
||||
src/downloader.h \
|
||||
src/opdsparser.h \
|
||||
src/epub.h
|
||||
src/epub.h \
|
||||
src/readerstate.h
|
||||
|
||||
LIBS += -lz
|
||||
|
||||
@@ -33,8 +35,9 @@ DISTFILES += $$OTHER_FILES
|
||||
|
||||
# Translations are NOT handled by the sailfishapp_i18n template on the 5.1 kit
|
||||
# (the .qm is never generated/installed reliably). The spec builds the .qm
|
||||
# with lrelease and installs it into /usr/share/translations directly;
|
||||
# libsailfishapp loads harbour-calibreweb_<locale>.qm automatically.
|
||||
# with lrelease and installs it into the app data dir
|
||||
# (/usr/share/harbour-calibreweb/translations — the RPM validator rejects
|
||||
# /usr/share/translations); main.cpp loads it explicitly (see language block).
|
||||
# Source strings are ENGLISH (default language); harbour-calibreweb_it.ts
|
||||
# provides the Italian catalogue.
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
// Cover: se un libro è aperto (readerState attivo dal ReaderPage) mostra
|
||||
// titolo e posizione di lettura, altrimenti icona e nome dell'app.
|
||||
CoverBackground {
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - 2 * Theme.paddingLarge
|
||||
spacing: Theme.paddingMedium
|
||||
visible: !readerState.active
|
||||
|
||||
Image {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
@@ -20,4 +24,29 @@ CoverBackground {
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - 2 * Theme.paddingLarge
|
||||
spacing: Theme.paddingSmall
|
||||
visible: readerState.active
|
||||
|
||||
Label {
|
||||
width: parent.width
|
||||
text: readerState.title
|
||||
color: Theme.primaryColor
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
truncationMode: TruncationMode.Elide
|
||||
}
|
||||
|
||||
Label {
|
||||
width: parent.width
|
||||
text: readerState.subtitle
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
truncationMode: TruncationMode.Elide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ ApplicationWindow {
|
||||
initialPage: Component { MainPage {} }
|
||||
cover: Component { CoverPage {} }
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
_defaultPageOrientations: Orientation.Portrait
|
||||
// Niente vincoli a livello window: ogni pagina dichiara le proprie
|
||||
// orientazioni (il lettore ruota in landscape, le pagine di lista
|
||||
// restano in portrait). _defaultPageOrientations è API privata.
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import Sailfish.Silica 1.0
|
||||
Page {
|
||||
id: page
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
|
||||
property var bookData: ({})
|
||||
property string coverSource: ""
|
||||
property bool downloading: false
|
||||
|
||||
@@ -4,6 +4,8 @@ import Sailfish.Silica 1.0
|
||||
Page {
|
||||
id: page
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
|
||||
property string feedUrl
|
||||
property string pageTitle
|
||||
property string nextUrl: ""
|
||||
|
||||
@@ -4,6 +4,8 @@ import Sailfish.Silica 1.0
|
||||
Page {
|
||||
id: page
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
|
||||
property bool loading: false
|
||||
property string errorMessage: ""
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ Page {
|
||||
property string bookFormat: "epub"
|
||||
|
||||
property int currentChapter: 0
|
||||
property double chapterFraction: 0.0
|
||||
// posizione di lettura nel capitolo corrente, stimata in caratteri di testo
|
||||
// dalla frazione di scroll (stabile col reflow del font)
|
||||
property int charOffset: 0
|
||||
@@ -276,11 +275,11 @@ Page {
|
||||
var max = Math.max(0, innerFlick.contentHeight - innerFlick.height)
|
||||
var y = Math.max(0, Math.min(max, innerFlick.contentY))
|
||||
var len = book.chapterTextLength(page.currentChapter)
|
||||
page.chapterFraction = max > 0 ? y / max : 0
|
||||
// posizione per caratteri (stima dalla frazione: stabile col reflow)
|
||||
page.charOffset = Math.round(page.chapterFraction * len)
|
||||
page.charOffset = Math.round((max > 0 ? y / max : 0) * len)
|
||||
page.pageIndex = Math.floor(y / step) + 1
|
||||
page.pageCount = Math.max(1, Math.ceil(max / step) + 1)
|
||||
updateCoverState()
|
||||
maybeSave(false)
|
||||
}
|
||||
|
||||
@@ -308,7 +307,6 @@ Page {
|
||||
return
|
||||
if (index !== page.currentChapter) {
|
||||
maybeSave(true)
|
||||
page.chapterFraction = 0
|
||||
page.charOffset = 0
|
||||
page.lastSavedAbs = -1
|
||||
}
|
||||
@@ -368,7 +366,6 @@ Page {
|
||||
} else if (page.currentChapter > 0) {
|
||||
maybeSave(true)
|
||||
page.currentChapter -= 1
|
||||
page.chapterFraction = 0
|
||||
page.charOffset = 0
|
||||
page.lastSavedAbs = -1
|
||||
// sentinella "fine capitolo": va oltre la lunghezza, così
|
||||
@@ -383,6 +380,17 @@ Page {
|
||||
return Math.round(16 * page.fontScale * 100) / 100
|
||||
}
|
||||
|
||||
// aggiorna lo stato per la cover (titolo + capitolo + percentuale)
|
||||
function updateCoverState() {
|
||||
if (book.chapterCount <= 0)
|
||||
return
|
||||
var pct = Math.round(page.overallProgress() * 100)
|
||||
readerState.setReading(book.title(),
|
||||
(page.currentChapter + 1) + "/" + book.chapterCount
|
||||
+ " · " + book.chapterTitle(page.currentChapter)
|
||||
+ " · " + pct + "%")
|
||||
}
|
||||
|
||||
function showChapterList() {
|
||||
var dialog = pageStack.push(Qt.resolvedUrl("ChapterListDialog.qml"),
|
||||
{ model: book.chapterList() })
|
||||
@@ -424,11 +432,17 @@ Page {
|
||||
page.currentChapter = ch
|
||||
page.pendingRestore = true
|
||||
page.restoreFrac = off >= 0 ? offsetToFrac(off, ch) : 0.0
|
||||
updateCoverState()
|
||||
restoreTimer.start()
|
||||
}
|
||||
|
||||
Component.onDestruction: readerState.clearReading()
|
||||
|
||||
onStatusChanged: {
|
||||
if (status === PageStatus.Inactive) {
|
||||
if (status === PageStatus.Active) {
|
||||
if (page.ready && book.chapterCount > 0)
|
||||
updateCoverState()
|
||||
} else if (status === PageStatus.Inactive) {
|
||||
maybeSave(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import Sailfish.Silica 1.0
|
||||
Page {
|
||||
id: page
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
|
||||
SilicaFlickable {
|
||||
anchors.fill: parent
|
||||
contentHeight: column.height
|
||||
|
||||
@@ -4,6 +4,8 @@ import Sailfish.Silica 1.0
|
||||
Page {
|
||||
id: page
|
||||
|
||||
allowedOrientations: Orientation.Portrait
|
||||
|
||||
property string testResult: ""
|
||||
property bool testOk: false
|
||||
property bool testing: false
|
||||
@@ -171,11 +173,18 @@ Page {
|
||||
if (base.indexOf("http://") !== 0 && base.indexOf("https://") !== 0)
|
||||
base = "https://" + base
|
||||
appSettings.serverUrl = base
|
||||
appSettings.flush() // i campi di testo scrivono senza sync a ogni tasto
|
||||
page.testing = true
|
||||
page.testResult = qsTr("Testing…")
|
||||
apiClient.getFeed(base + "/opds")
|
||||
}
|
||||
|
||||
// uscita dalla pagina: scrivi su disco le modifiche in sospeso
|
||||
onStatusChanged: {
|
||||
if (status === PageStatus.Inactive)
|
||||
appSettings.flush()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: apiClient
|
||||
onFeedReady: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: harbour-calibreweb
|
||||
Summary: Client OPDS per Calibre Web
|
||||
Version: 0.4.7
|
||||
Version: 0.4.8
|
||||
Release: 1
|
||||
Group: Qt/Qt
|
||||
License: MIT
|
||||
@@ -24,6 +24,20 @@ reflow del testo, margini configurabili e posizione salvata
|
||||
in locale.
|
||||
|
||||
%changelog
|
||||
* Fri Aug 21 2026 Carlo Baratto <carlo@carlobaratto.it> - 0.4.8-1
|
||||
- Best practice audit: orientazioni per pagina (finestra senza vincoli, il
|
||||
lettore ora ruota davvero in landscape; pagine di lista in portrait;
|
||||
rimossa la proprieta' privata _defaultPageOrientations)
|
||||
- Licenza MIT installata nel pacchetto (/usr/share/licenses/harbour-calibreweb)
|
||||
- EPUB: lunghezze testo LAZY per capitolo (l'apertura non parse piu' tutto il
|
||||
libro: niente freeze sui libri grossi; cache al primo accesso)
|
||||
- Cover dinamica: con un libro aperto mostra titolo e posizione di lettura
|
||||
(ReaderState esposto come context property, aggiornato dal ReaderPage)
|
||||
- Impostazioni: niente sync su disco a ogni tasto nei campi di testo
|
||||
(flush() all'uscita della pagina e prima del test connessione)
|
||||
- Pulizia: rimossa proprieta' morta chapterFraction, commenti obsoleti
|
||||
aggiornati (settings.h, .pro)
|
||||
|
||||
* Fri Aug 21 2026 Carlo Baratto <carlo@carlobaratto.it> - 0.4.7-1
|
||||
- Fix margini lettore: il passo di pagina era la viewport intera, quindi il
|
||||
testo scorreva a filo dei bordi e i margini verticali si vedevano solo
|
||||
@@ -199,6 +213,19 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop || tr
|
||||
mkdir -p %{buildroot}%{_datadir}/%{name}/translations
|
||||
install -m 0644 %{_builddir}/%{name}_it.qm %{buildroot}%{_datadir}/%{name}/translations/
|
||||
|
||||
# MIT license: installed in the package (Harbour best practice).
|
||||
mkdir -p %{buildroot}%{_datadir}/licenses/%{name}
|
||||
if [ -f %{_builddir}/../%{name}-%{version}/LICENSE ]; then
|
||||
install -m 0644 %{_builddir}/../%{name}-%{version}/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/
|
||||
elif [ -f %{_builddir}/%{name}-%{version}/LICENSE ]; then
|
||||
install -m 0644 %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/
|
||||
elif [ -f %{_builddir}/LICENSE ]; then
|
||||
install -m 0644 %{_builddir}/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/
|
||||
else
|
||||
echo "ERROR: LICENSE not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%{_bindir}/%{name}
|
||||
@@ -209,3 +236,4 @@ install -m 0644 %{_builddir}/%{name}_it.qm %{buildroot}%{_datadir}/%{name}/trans
|
||||
%{_datadir}/icons/hicolor/172x172/apps/%{name}.png
|
||||
%{_datadir}/%{name}/qml
|
||||
%{_datadir}/%{name}/translations/%{name}*.qm
|
||||
%{_datadir}/licenses/%{name}/LICENSE
|
||||
|
||||
+23
-13
@@ -490,8 +490,14 @@ bool EpubBook::open(const QString &epubPath)
|
||||
if (!parseOpf())
|
||||
return false;
|
||||
const bool ok = !m_chapters.isEmpty();
|
||||
if (ok)
|
||||
computeTextLengths();
|
||||
if (ok) {
|
||||
// lunghezze testo LAZY: -1 = da calcolare al primo accesso. L'apertura
|
||||
// resta veloce anche per libri grossi (niente parse di tutti i capitoli).
|
||||
m_textLengths.clear();
|
||||
m_textLengths.reserve(m_chapters.size());
|
||||
for (int i = 0; i < m_chapters.size(); ++i)
|
||||
m_textLengths.append(-1);
|
||||
}
|
||||
emit changed();
|
||||
return ok;
|
||||
}
|
||||
@@ -763,24 +769,26 @@ QString EpubBook::chapterRichText(int index) const
|
||||
return htmlToRichText(html);
|
||||
}
|
||||
|
||||
void EpubBook::computeTextLengths()
|
||||
// calcola (e cache) la lunghezza del capitolo index se non ancora nota
|
||||
void EpubBook::ensureTextLength(int index) const
|
||||
{
|
||||
m_textLengths.clear();
|
||||
for (const EpubChapter &c : m_chapters) {
|
||||
QFile f(c.path);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
m_textLengths.append(0);
|
||||
continue;
|
||||
}
|
||||
const QString html = QString::fromUtf8(f.readAll());
|
||||
m_textLengths.append(plainTextLength(html));
|
||||
if (index < 0 || index >= m_textLengths.size() || m_textLengths.at(index) >= 0)
|
||||
return;
|
||||
const EpubChapter &c = m_chapters.at(index);
|
||||
QFile f(c.path);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
m_textLengths[index] = 0;
|
||||
return;
|
||||
}
|
||||
const QString html = QString::fromUtf8(f.readAll());
|
||||
m_textLengths[index] = plainTextLength(html);
|
||||
}
|
||||
|
||||
int EpubBook::chapterTextLength(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_textLengths.size())
|
||||
return 0;
|
||||
ensureTextLength(index);
|
||||
return m_textLengths.at(index);
|
||||
}
|
||||
|
||||
@@ -788,8 +796,10 @@ qint64 EpubBook::chapterStartChar(int index) const
|
||||
{
|
||||
qint64 start = 0;
|
||||
const int end = qMin(index, m_textLengths.size());
|
||||
for (int i = 0; i < end; ++i)
|
||||
for (int i = 0; i < end; ++i) {
|
||||
ensureTextLength(i);
|
||||
start += m_textLengths.at(i);
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -66,15 +66,17 @@ private:
|
||||
void parseTocEpub3(const QString &navPath);
|
||||
void parseTocEpub2(const QString &ncxPath);
|
||||
QString absolutePath(const QString &relativeToOpfDir) const;
|
||||
// lunghezze in caratteri del testo visibile, calcolate all'open
|
||||
void computeTextLengths();
|
||||
// calcola (e cache) la lunghezza in caratteri del capitolo al primo accesso
|
||||
void ensureTextLength(int index) const;
|
||||
|
||||
QString m_baseDir;
|
||||
QString m_opfDir;
|
||||
QString m_title;
|
||||
QString m_author;
|
||||
QList<EpubChapter> m_chapters;
|
||||
QList<int> m_textLengths;
|
||||
// lunghezze testo per capitolo, calcolate LAZY al primo accesso
|
||||
// (-1 = non ancora calcolata); mutable per la cache da metodi const
|
||||
mutable QList<int> m_textLengths;
|
||||
};
|
||||
|
||||
#endif // EPUB_H
|
||||
|
||||
+6
-2
@@ -10,6 +10,7 @@
|
||||
#include "apiclient.h"
|
||||
#include "downloader.h"
|
||||
#include "epub.h"
|
||||
#include "readerstate.h"
|
||||
#include "settings.h"
|
||||
|
||||
Q_DECL_EXPORT int main(int argc, char *argv[])
|
||||
@@ -22,7 +23,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
|
||||
app->setOrganizationName(QStringLiteral("harbour"));
|
||||
app->setApplicationName(QStringLiteral("calibreweb"));
|
||||
// versione mostrata nelle impostazioni (tenere allineata allo spec)
|
||||
app->setApplicationVersion(QStringLiteral("0.4.7"));
|
||||
app->setApplicationVersion(QStringLiteral("0.4.8"));
|
||||
|
||||
Settings settings;
|
||||
|
||||
@@ -56,16 +57,19 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
|
||||
|
||||
QQuickView *view = SailfishApp::createView();
|
||||
|
||||
qDebug() << "harbour-calibreweb v0.4.7 build" << __DATE__ << __TIME__;
|
||||
qDebug() << "harbour-calibreweb v0.4.8 build" << __DATE__ << __TIME__;
|
||||
|
||||
qmlRegisterType<EpubBook>("harbour.calibreweb", 1, 0, "EpubBook");
|
||||
|
||||
ApiClient apiClient(&settings);
|
||||
Downloader downloader(&settings);
|
||||
// stato di lettura corrente (per la cover quando l'app va in background)
|
||||
ReaderState readerState(&settings);
|
||||
|
||||
view->rootContext()->setContextProperty(QStringLiteral("appSettings"), &settings);
|
||||
view->rootContext()->setContextProperty(QStringLiteral("apiClient"), &apiClient);
|
||||
view->rootContext()->setContextProperty(QStringLiteral("downloader"), &downloader);
|
||||
view->rootContext()->setContextProperty(QStringLiteral("readerState"), &readerState);
|
||||
view->rootContext()->setContextProperty(QStringLiteral("appVersion"),
|
||||
QCoreApplication::applicationVersion());
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "readerstate.h"
|
||||
|
||||
ReaderState::ReaderState(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_active(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ReaderState::setReading(const QString &title, const QString &subtitle)
|
||||
{
|
||||
if (m_active && m_title == title && m_subtitle == subtitle)
|
||||
return;
|
||||
m_active = true;
|
||||
m_title = title;
|
||||
m_subtitle = subtitle;
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void ReaderState::clearReading()
|
||||
{
|
||||
if (!m_active)
|
||||
return;
|
||||
m_active = false;
|
||||
m_title.clear();
|
||||
m_subtitle.clear();
|
||||
emit changed();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef READERSTATE_H
|
||||
#define READERSTATE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
// Stato di lettura corrente, esposto come context property "readerState":
|
||||
// la cover mostra il libro aperto (titolo + posizione) invece dell'icona fissa.
|
||||
class ReaderState : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool active READ active NOTIFY changed)
|
||||
Q_PROPERTY(QString title READ title NOTIFY changed)
|
||||
Q_PROPERTY(QString subtitle READ subtitle NOTIFY changed)
|
||||
|
||||
public:
|
||||
explicit ReaderState(QObject *parent = 0);
|
||||
|
||||
bool active() const { return m_active; }
|
||||
QString title() const { return m_title; }
|
||||
QString subtitle() const { return m_subtitle; }
|
||||
|
||||
// aggiorna lo stato quando il lettore mostra un libro (chiamata dal QML)
|
||||
Q_INVOKABLE void setReading(const QString &title, const QString &subtitle);
|
||||
// il libro è stato chiuso: la cover torna all'icona predefinita
|
||||
Q_INVOKABLE void clearReading();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
bool m_active;
|
||||
QString m_title;
|
||||
QString m_subtitle;
|
||||
};
|
||||
|
||||
#endif // READERSTATE_H
|
||||
+7
-5
@@ -115,9 +115,9 @@ void Settings::setServerUrl(const QString &value)
|
||||
{
|
||||
if (value == serverUrl())
|
||||
return;
|
||||
// niente sync a ogni tasto (flash wear): il flush avviene all'uscita
|
||||
// dalle impostazioni o prima delle richieste di rete (vedi flush())
|
||||
m_settings.setValue(QStringLiteral("serverUrl"), value);
|
||||
m_settings.sync(); // scrivi subito su disco: l'app può crashare alla chiusura (WebView)
|
||||
openPermissions();
|
||||
emit serverUrlChanged();
|
||||
emit baseUrlChanged();
|
||||
}
|
||||
@@ -132,8 +132,6 @@ void Settings::setUsername(const QString &value)
|
||||
if (value == username())
|
||||
return;
|
||||
m_settings.setValue(QStringLiteral("username"), value);
|
||||
m_settings.sync();
|
||||
openPermissions();
|
||||
emit usernameChanged();
|
||||
}
|
||||
|
||||
@@ -147,9 +145,13 @@ void Settings::setPassword(const QString &value)
|
||||
if (value == password())
|
||||
return;
|
||||
m_settings.setValue(QStringLiteral("password"), value);
|
||||
emit passwordChanged();
|
||||
}
|
||||
|
||||
void Settings::flush()
|
||||
{
|
||||
m_settings.sync();
|
||||
openPermissions();
|
||||
emit passwordChanged();
|
||||
}
|
||||
|
||||
bool Settings::ignoreSslErrors() const
|
||||
|
||||
+14
-9
@@ -55,6 +55,10 @@ public:
|
||||
|
||||
QString downloadDir() const;
|
||||
|
||||
// scrive subito su disco le modifiche in sospeso (i setter di testo non
|
||||
// fanno sync a ogni tasto: chiamare questo all'uscita dalle impostazioni)
|
||||
Q_INVOKABLE void flush();
|
||||
|
||||
// Header "Authorization: Basic ..." pronto da usare, vuoto se utente non impostato
|
||||
QString authHeader() const;
|
||||
|
||||
@@ -80,17 +84,18 @@ signals:
|
||||
void baseUrlChanged();
|
||||
|
||||
private:
|
||||
// Path fisso condiviso: l'app deve leggere/scrivere SEMPRE lo stesso file,
|
||||
// sia avviata dal launcher (utente nemo) sia da SSH di debug (defaultuser).
|
||||
// Con QSettings("harbour","calibreweb") il file dipende dalla HOME
|
||||
// dell'utente che avvia -> configurazione invisibile dall'altro utente.
|
||||
// Path canonico per la sandbox SailJail (Sailfish 4.4+/5.x): con org/app
|
||||
// impostati (harbour/calibreweb, vedi main.cpp e X-Sailjail nel desktop
|
||||
// file), AppConfigLocation = ~/.config/harbour/calibreweb, l'unica zona
|
||||
// config PERSISTENTE della sandbox (senza profilo la sandbox la nasconde).
|
||||
static QString configPath();
|
||||
// Importa i valori dalla vecchia config per-utente (~/.config/harbour/...) se
|
||||
// il file condiviso e' vuoto: copre la configurazione fatta prima del fix.
|
||||
// Importa i valori dal vecchio file per-utente (~/.config/harbour/...) se
|
||||
// il file canonico e' vuoto: copre la configurazione fatta prima del fix.
|
||||
void migrateIfNeeded();
|
||||
// Apre i permessi della catena /home/nemo/.config/harbour e del file:
|
||||
// il launcher gira come nemo (home 700), il debug SSH come defaultuser —
|
||||
// entrambi devono poter leggere/scrivere lo stesso file di configurazione.
|
||||
// Apre i permessi della catena di directory del file di configurazione:
|
||||
// l'avvio dal launcher e quello da SSH (defaultuser) devono poter
|
||||
// leggere/scrivere lo stesso file. Efficace quando l'app gira come
|
||||
// owner della home (dal launcher).
|
||||
void openPermissions();
|
||||
|
||||
QSettings m_settings;
|
||||
|
||||
Reference in New Issue
Block a user