- Bookmark cw:v2:<offset assoluto caratteri> invece di capitolo+frazione; migrazione automatica delle chiavi v1 (parseBookmarkKey) - Lunghezze testo per capitolo in C++ (text node del DOM, entità decodificate, body-only) per mappare offset assoluto -> capitolo - Paginazione: stile iniettato height:auto/overflow:visible + unlock JS dei contenitori hidden — il CSS di molti EPUB bloccava lo scroll e ogni tap saltava al capitolo successivo - prevPage dall'inizio capitolo -> ultima pagina del capitolo precedente - Cambio font mantiene la posizione (restore per carattere) - Label menu: pagina corrente/totale del capitolo; max su documentElement+body - Test: harness C++ (Qt) e test JS con DOM mock
78 lines
2.6 KiB
C++
78 lines
2.6 KiB
C++
#ifndef EPUB_H
|
|
#define EPUB_H
|
|
|
|
#include <QList>
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QVariantList>
|
|
|
|
struct EpubChapter
|
|
{
|
|
QString id;
|
|
QString path; // path assoluto del file HTML estratto
|
|
QString title;
|
|
};
|
|
|
|
class EpubBook : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
Q_PROPERTY(QString title READ title NOTIFY changed)
|
|
Q_PROPERTY(QString author READ author NOTIFY changed)
|
|
Q_PROPERTY(int chapterCount READ chapterCount NOTIFY changed)
|
|
|
|
public:
|
|
explicit EpubBook(QObject *parent = 0);
|
|
~EpubBook();
|
|
|
|
Q_INVOKABLE bool open(const QString &epubPath);
|
|
Q_INVOKABLE void close();
|
|
|
|
QString title() const { return m_title; }
|
|
QString author() const { return m_author; }
|
|
int chapterCount() const { return m_chapters.size(); }
|
|
|
|
Q_INVOKABLE QString chapterFilePath(int index) const;
|
|
Q_INVOKABLE QString chapterTitle(int index) const;
|
|
// elenco [{index, title}] per la lista capitoli
|
|
Q_INVOKABLE QVariantList chapterList() const;
|
|
// lunghezza in caratteri del testo VISIBILE del capitolo (entità decodificate,
|
|
// head/script/style esclusi) — stesso criterio del conteggio JS nel lettore
|
|
Q_INVOKABLE int chapterTextLength(int index) const;
|
|
// caratteri di testo complessivi prima dell'inizio del capitolo index
|
|
Q_INVOKABLE qint64 chapterStartChar(int index) const;
|
|
// HTML del capitolo con lo stile di reflow iniettato (font-size e margini in px)
|
|
Q_INVOKABLE QString chapterHtml(int index, int fontSizePx, int marginPx, int marginVerticalPx) const;
|
|
// base URL (file://) per risolvere immagini/CSS relativi del capitolo
|
|
Q_INVOKABLE QString chapterBaseUrl(int index) const;
|
|
|
|
// chiave segno locale v2, es. "cw:v2:12345" (posizione = carattere assoluto
|
|
// nel libro, indipendente da font, margini e reflow)
|
|
Q_INVOKABLE QString makeBookmarkKey(int chapterIndex, qint64 charOffset) const;
|
|
// restituisce {chapter, charOffset} con charOffset NEL capitolo; accetta
|
|
// chiavi v2 ("cw:v2:<assoluto>") e v1 ("cw:v1:<cap>:<frac>", migrazione)
|
|
Q_INVOKABLE QVariantMap parseBookmarkKey(const QString &key) const;
|
|
|
|
signals:
|
|
void changed();
|
|
|
|
private:
|
|
bool extractZip(const QString &epubPath);
|
|
bool parseContainer();
|
|
bool parseOpf();
|
|
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();
|
|
|
|
QString m_baseDir;
|
|
QString m_opfDir;
|
|
QString m_title;
|
|
QString m_author;
|
|
QList<EpubChapter> m_chapters;
|
|
QList<int> m_textLengths;
|
|
};
|
|
|
|
#endif // EPUB_H
|