Don't lose pages. Handle fragments in chapter URLs.
authorAkos Polster <polster@marzipan.pipacs.com>
Fri, 6 Aug 2010 21:09:47 +0000 (23:09 +0200)
committerAkos Polster <polster@marzipan.pipacs.com>
Fri, 6 Aug 2010 21:09:47 +0000 (23:09 +0200)
chaptersdialog.cpp
mainwindow.cpp
model/book.cpp
model/book.h
model/ncxhandler.h
model/opshandler.h
pkg/changelog

index 9ff0ab8..0b972d7 100644 (file)
@@ -10,7 +10,7 @@ ChaptersDialog::ChaptersDialog(Book *book, QWidget *parent): ListWindow(parent)
     list = new QListWidget(this);
     list->setSelectionMode(QAbstractItemView::SingleSelection);
     if (book) {
-        foreach (QString id, book->toc) {
+        foreach (QString id, book->chapters) {
             QString contentTitle = book->content[id].name;
             (void)new QListWidgetItem(contentTitle, list);
         }
index 9a18493..b8956da 100755 (executable)
@@ -213,29 +213,24 @@ QAction *MainWindow::addToolBarAction(const QObject *receiver,
 
 void MainWindow::showLibrary()
 {
-    LibraryDialog *dialog = new LibraryDialog(this);
-    dialog->show();
+    (new LibraryDialog(this))->show();
 }
 
 void MainWindow::showSettings()
 {
-    SettingsWindow *settings = new SettingsWindow(this);
-    settings->show();
+    (new SettingsWindow(this))->show();
 }
 
 void MainWindow::showInfo()
 {
     if (mCurrent.isValid()) {
-        InfoDialog *info =
-            new InfoDialog(Library::instance()->book(mCurrent), this);
-        info->exec();
+        (new InfoDialog(Library::instance()->book(mCurrent), this))->exec();
     }
 }
 
 void MainWindow::showDevTools()
 {
-    DevTools *devTools = new DevTools();
-    devTools->exec();
+    (new DevTools())->exec();
 }
 
 void MainWindow::showBookmarks()
@@ -347,7 +342,48 @@ void MainWindow::showChapters()
 
 void MainWindow::onGoToChapter(int index)
 {
-    view->goToBookmark(Book::Bookmark(index, 0));
+    Trace t("MainWindow::onGoToChapter");
+
+    Book *book = Library::instance()->book(mCurrent);
+    if (!book) {
+        t.trace("No current book?");
+        return;
+    }
+
+    QString id = book->chapters[index];
+    QString href = book->content[id].href;
+    QString baseRef(href);
+    QUrl url(QString("file://") + href);
+    if (url.hasFragment()) {
+        QString fragment = url.fragment();
+        baseRef.chop(fragment.length() + 1);
+    }
+
+    // Swipe through all content items to find the one matching the chapter href
+    // FIXME: Do we need to index content items by href, too?
+    QString contentKey;
+    bool found = false;
+    foreach (contentKey, book->content.keys()) {
+        if (contentKey == id) {
+            continue;
+        }
+        if (book->content[contentKey].href == baseRef) {
+            found = true;
+            t.trace(QString("Key for %1 is %2").arg(baseRef).arg(contentKey));
+            break;
+        }
+    }
+    if (!found) {
+        t.trace("Could not find key for " + baseRef);
+        return;
+    }
+
+    int tocIndex = book->toc.indexOf(contentKey);
+    if (tocIndex != -1) {
+        view->goToBookmark(Book::Bookmark(tocIndex, 0));
+    } else {
+        qCritical() << "Could not find toc index of chapter" << id;
+    }
 }
 
 void MainWindow::timerEvent(QTimerEvent *event)
index b4a5022..7c6f400 100644 (file)
@@ -135,6 +135,10 @@ bool Book::parse()
     delete opsHandler;
     delete source;
 
+    // Initially, put all content items in the chapter list.
+    // This can be refined by parsing the NCX file later
+    chapters = toc;
+
     // Load cover image
     QStringList coverKeys;
     coverKeys << "cover-image" << "img-cover-jpeg" << "cover";
index 367b2a2..ddf1403 100644 (file)
@@ -108,6 +108,7 @@ public:
     QString rights;                         //< Rights.
     QString tocPath;                        //< Path to toc ncx.
     QString coverPath;                      //< Path to cover html.
+    QStringList chapters;                   //< Main navigation items from EPUB.
 
 signals:
     /** Emitted if @see open() succeeds. */
index 0f808cb..4afcb35 100644 (file)
@@ -4,6 +4,7 @@
 #include <QXmlContentHandler>
 
 #include "book.h"
+#include "trace.h"
 
 /** XML content handler for NCX format. */
 class NcxHandler: public QXmlContentHandler
@@ -19,37 +20,38 @@ public:
     bool startDocument() {return true;}
     bool startPrefixMapping(const QString &, const QString &) {return true;}
 
-    NcxHandler(Book &b): book(b)
-    {
-        book.toc.clear();
+    NcxHandler(Book &b): book(b) {
+        book.chapters.clear();
     }
 
-    bool characters(const QString &ch)
-    {
+    bool characters(const QString &ch) {
         currentText += ch;
         return true;
     }
 
     bool endElement(const QString &namespaceUri, const QString &name,
-                    const QString &qName)
-    {
+                    const QString &qName) {
+        Trace t("NcxHandler::endElement" + name);
         (void)namespaceUri;
         (void)qName;
         if (name == "text") {
+            t.trace(currentText);
             contentTitle = currentText;
         } else if (name == "navPoint") {
+            t.trace(QString("url: ") + contentUrl);
+            t.trace(QString("title: ") + contentTitle);
+            t.trace(QString("id:") + contentId);
             Book::ContentItem item;
             item.href = book.rootPath() + "/" + contentUrl;
             item.name = contentTitle;
             book.content[contentId] = item;
-            book.toc.append(contentId);
+            book.chapters.append(contentId);
         }
         return true;
     }
 
     bool startElement(const QString &namespaceUri, const QString &name,
-                      const QString &qName, const QXmlAttributes &attrs)
-    {
+                      const QString &qName, const QXmlAttributes &attrs) {
         (void)namespaceUri;
         (void)qName;
         currentText = "";
index 9b42c23..e27f766 100644 (file)
@@ -4,6 +4,7 @@
 #include <QXmlContentHandler>
 
 #include "book.h"
+#include "trace.h"
 
 /** XML content handler for OPS format. */
 class OpsHandler: public QXmlContentHandler
@@ -22,34 +23,27 @@ public:
     bool startDocument() {return true;}
     bool startPrefixMapping(const QString &, const QString &) {return true;}
 
-    bool characters(const QString &ch)
-    {
+    bool characters(const QString &ch) {
         currentText += ch;
         return true;
     }
 
     bool endElement(const QString &namespaceUri, const QString &name,
-                    const QString &qName)
-    {
+                    const QString &qName) {
         (void)namespaceUri;
         (void)qName;
         if (currentText != "") {
             if (name == "title") {
                 book.title = currentText;
-            }
-            else if (name == "creator") {
+            } else if (name == "creator") {
                 book.creators.append(currentText);
-            }
-            else if (name == "publisher") {
+            } else if (name == "publisher") {
                 book.publisher = currentText;
-            }
-            else if (name == "subject") {
+            } else if (name == "subject") {
                 book.subject = currentText;
-            }
-            else if (name == "source") {
+            } else if (name == "source") {
                 book.source = currentText;
-            }
-            else if (name == "rights") {
+            } else if (name == "rights") {
                 book.rights = currentText;
             }
         }
@@ -57,8 +51,8 @@ public:
     }
 
     bool startElement(const QString &namespaceUri, const QString &name,
-                      const QString &qName, const QXmlAttributes &attrs)
-    {
+                      const QString &qName, const QXmlAttributes &attrs) {
+        Trace t("OpsHandler::startElement" + name);
         (void)namespaceUri;
         (void)qName;
         currentText = "";
@@ -70,8 +64,12 @@ public:
             QString key = attrs.value("id");
             book.content[key] = item;
             partCount++;
+            t.trace(QString("name: ") + item.name);
+            t.trace(QString("href: ") + attrs.value("href"));
+            t.trace(QString("id: ") + key);
         }
         else if (name == "itemref") {
+            t.trace(QString("id: ") + attrs.value("idref"));
             book.toc.append(attrs.value("idref"));
         }
         return true;
index 250a4d0..2f34297 100644 (file)
@@ -1,6 +1,8 @@
 dorian (0.1.1-1) unstable; urgency=low
 
   * Improve chances to find cover image
+  * Don't lose pages
+  * Handle fragments in chapter URLs
 
  -- Akos Polster <akos@pipacs.com>  Fri,  6 Aug 2010 20:00:00 +0200