Show reading progress.
authorAkos Polster <polster@marzipan.pipacs.com>
Sun, 8 Aug 2010 01:18:22 +0000 (03:18 +0200)
committerAkos Polster <polster@marzipan.pipacs.com>
Sun, 8 Aug 2010 01:18:22 +0000 (03:18 +0200)
13 files changed:
bookmarkinfodialog.cpp
bookmarksdialog.cpp
bookview.cpp
bookview.h
dorian.pro
mainwindow.cpp
mainwindow.h
model/book.cpp
model/book.h
pkg/changelog
widgets/progress.cpp [new file with mode: 0644]
widgets/progress.h [new file with mode: 0644]
widgets/translucentbutton.h

index f3a9d5d..42544fd 100644 (file)
@@ -11,7 +11,7 @@ BookmarkInfoDialog::BookmarkInfoDialog(Book *b, int i, QWidget *parent):
     setWindowTitle(tr("Bookmark Details"));
 
     Book::Bookmark bookmark = book->bookmarks()[index];
-    QString contentId = book->toc[bookmark.part];
+    QString contentId = book->parts[bookmark.part];
     QString contentTitle = book->content[contentId].name;
     QLabel *info = new QLabel(contentTitle + "\nAt " +
         QString::number((int)(bookmark.pos*100)) + "%", this);
index 498ec07..38f39a8 100644 (file)
@@ -20,7 +20,7 @@ BookmarksDialog::BookmarksDialog(Book *book_, QWidget *parent):
     list = new QListWidget(this);
     list->setSelectionMode(QAbstractItemView::SingleSelection);
     foreach (Book::Bookmark bookmark, book_->bookmarks()) {
-        QString contentId = book_->toc[bookmark.part];
+        QString contentId = book_->parts[bookmark.part];
         QString contentTitle = book_->content[contentId].name;
         (void)new QListWidgetItem(QIcon(":icons/bookmark.png"), contentTitle +
             "\nAt " + QString::number((int)(bookmark.pos*100)) + "%", list);
index 3dd9e24..39870b5 100644 (file)
@@ -10,6 +10,7 @@
 #include "library.h"
 #include "settings.h"
 #include "trace.h"
+#include "progress.h"
 
 #ifdef Q_WS_MAC
 #   define ICON_PREFIX ":/icons/mac/"
@@ -196,6 +197,7 @@ void BookView::onLoadFinished(bool ok)
     addNavigationBar();
     onSettingsChanged("scheme");
     emit partLoadEnd(contentIndex);
+    showProgress();
 }
 
 void BookView::onSettingsChanged(const QString &key)
@@ -257,6 +259,18 @@ void BookView::mousePressEvent(QMouseEvent *e)
     e->ignore();
 }
 
+void BookView::mouseReleaseEvent(QMouseEvent *e)
+{
+    QWebView::mouseReleaseEvent(e);
+    showProgress();
+}
+
+void BookView::wheelEvent(QWheelEvent *e)
+{
+    QWebView::wheelEvent(e);
+    showProgress();
+}
+
 void BookView::addBookmark()
 {
     Trace t("BookView::addBookmark");
@@ -351,6 +365,7 @@ bool BookView::eventFilter(QObject *o, QEvent *e)
         mousePressed = true;
         break;
     case QEvent::MouseButtonRelease:
+        showProgress();
         mousePressed = false;
         break;
     case QEvent::MouseMove:
@@ -409,3 +424,12 @@ void BookView::goToPosition(qreal position)
     Trace::trace(QString("BookView::goToPosition: To %1 (%2%, height %3)").
             arg(scrollPos).arg(position * 100).arg(contentsHeight));
 }
+
+void BookView::showProgress()
+{
+    if (mBook) {
+        qreal pos = (qreal)(page()->mainFrame()->scrollPosition().y()) /
+                    (qreal)contentsHeight;
+        emit progress(mBook->getProgress(contentIndex, pos));
+    }
+}
index ee7cfc2..944ba00 100644 (file)
@@ -10,6 +10,7 @@
 #include "book.h"
 
 class QModelIndex;
+class Progress;
 
 /** Visual representation of a book. */
 class BookView: public QWebView
@@ -33,6 +34,9 @@ signals:
     /** Signal button press when the real event has been suppressed. */
     void suppressedMouseButtonPress();
 
+    /** Signal progress in reading the book. */
+    void progress(qreal p);
+
 public slots:
     void goPrevious();
     void goNext();
@@ -46,11 +50,13 @@ public slots:
     void onContentsSizeChanged(const QSize &size);
 
 protected:
-    virtual void paintEvent(QPaintEvent *e);
-    virtual void mousePressEvent(QMouseEvent *e);
+    void paintEvent(QPaintEvent *e);
+    void mousePressEvent(QMouseEvent *e);
+    void mouseReleaseEvent(QMouseEvent *e);
+    void wheelEvent(QWheelEvent *);
     bool eventFilter(QObject *o, QEvent *e);
-    virtual void leaveEvent(QEvent *);
-    virtual void enterEvent(QEvent *);
+    void leaveEvent(QEvent *e);
+    void enterEvent(QEvent *e);
 
 private:
     /** Save navigation icons from resource to the file system. */
@@ -71,6 +77,9 @@ private:
     /** Go to a given (relative) position in current part. */
     void goToPosition(qreal position);
 
+    /** Show progress. */
+    void showProgress();
+
     int contentIndex;   /**< Current part in book. */
     Book *mBook;        /**< Book to show. */
     bool restorePositionAfterLoad;
index 9d2c08f..7918b14 100644 (file)
@@ -29,7 +29,8 @@ SOURCES += \
     widgets/toolbuttonbox.cpp \
     model/bookfinder.cpp \
     widgets/listwindow.cpp \
-    foldersdialog.cpp
+    foldersdialog.cpp \
+    widgets/progress.cpp
 
 HEADERS += \
     mainwindow.h \
@@ -59,7 +60,8 @@ HEADERS += \
     widgets/toolbuttonbox.h \
     model/bookfinder.h \
     widgets/listwindow.h \
-    foldersdialog.h
+    foldersdialog.h \
+    widgets/progress.h
 
 RESOURCES += \
     dorian.qrc
index 47319f1..b7ebb8e 100755 (executable)
@@ -26,6 +26,7 @@
 #include "fullscreenwindow.h"
 #include "trace.h"
 #include "bookfinder.h"
+#include "progress.h"
 
 #ifdef DORIAN_TEST_MODEL
 #include "modeltest.h"
@@ -37,6 +38,8 @@
 #   define ICON_PREFIX ":/icons/"
 #endif
 
+const int PROGRESS_HEIGHT = 17;
+
 MainWindow::MainWindow(QWidget *parent):
     QMainWindow(parent), view(0), preventBlankingTimer(-1)
 {
@@ -59,6 +62,9 @@ MainWindow::MainWindow(QWidget *parent):
     view->show();
     layout->addWidget(view);
 
+    // Progress
+    progress = new Progress(central);
+
     // Tool bar
     setUnifiedTitleAndToolBarOnMac(true);
     settings = new QDialog(this);
@@ -139,6 +145,9 @@ MainWindow::MainWindow(QWidget *parent):
     connect(view, SIGNAL(chapterLoadEnd(int)),
             this, SLOT(onChapterLoadEnd(int)));
 
+    // Handle progress
+    connect(view, SIGNAL(progress(qreal)), progress, SLOT(setProgress(qreal)));
+
     // Shadow window for full screen
     fullScreenWindow = new FullScreenWindow(this);
     connect(fullScreenWindow, SIGNAL(restore()), this, SLOT(showRegular()));
@@ -152,15 +161,6 @@ MainWindow::MainWindow(QWidget *parent):
     bookFinder->moveToThread(&bookFinderThread);
     bookFinderThread.start();
 
-#if 0
-    bool ret = QMetaObject::invokeMethod(
-        bookFinder,
-        "find",
-        Q_ARG(QStringList, QStringList(QString("/Users/polster/Books"))),
-        Q_ARG(QStringList, library->bookPaths()));
-    t.trace(QString("Invoking BookFinder::find ") + (ret?"succeeded":"failed"));
-#endif
-
 #ifdef DORIAN_TEST_MODEL
     (void)new ModelTest(Library::instance(), this);
 #endif
@@ -184,15 +184,22 @@ void MainWindow::showRegular()
     fullScreenWindow->hide();
     fullScreenWindow->leaveChild();
     view->setParent(centralWidget());
+    progress->setParent(centralWidget());
+    progress->setGeometry(0, 0, geometry().width(), PROGRESS_HEIGHT);
     centralWidget()->layout()->addWidget(view);
+    progress->flash();
 }
 
 void MainWindow::showBig()
 {
     Trace t("MainWindow::showBig");
     centralWidget()->layout()->removeWidget(view);
+    progress->setParent(fullScreenWindow);
+    progress->setGeometry(0, 0, QApplication::desktop()->screenGeometry().width(),
+                          PROGRESS_HEIGHT);
     fullScreenWindow->takeChild(view);
     fullScreenWindow->showFullScreen();
+    progress->flash();
 }
 
 void MainWindow::setCurrentBook(const QModelIndex &current)
@@ -364,3 +371,9 @@ void MainWindow::timerEvent(QTimerEvent *event)
         Trace::trace("MainWindow::timerEvent: Prevent display blanking");
     }
 }
+
+void MainWindow::resizeEvent(QResizeEvent *e)
+{
+    progress->setGeometry(QRect(0, 0, e->size().width(), PROGRESS_HEIGHT));
+    QMainWindow::resizeEvent(e);
+}
index 53cb276..1f1557d 100755 (executable)
@@ -10,6 +10,7 @@ class DevTools;
 class BookView;
 class Book;
 class FullScreenWindow;
+class Progress;
 
 class MainWindow: public QMainWindow
 {
@@ -37,8 +38,9 @@ public slots:
     void onGoToChapter(int index);
 
 protected:
-    virtual void closeEvent(QCloseEvent *event);
-    virtual void timerEvent(QTimerEvent *event);
+    void closeEvent(QCloseEvent *event);
+    void timerEvent(QTimerEvent *event);
+    void resizeEvent(QResizeEvent *event);
 
 private:
     void setCurrentBook(const QModelIndex &current);
@@ -64,6 +66,7 @@ private:
     int preventBlankingTimer;
     BookFinder *bookFinder;
     BookFinderThread bookFinderThread;
+    Progress *progress;
 };
 
 #endif // MAINWINDOW_H
index fdf8ccb..38242ca 100644 (file)
@@ -171,9 +171,11 @@ bool Book::parse()
     }
 
     // Calculate book part sizes
+    size = 0;
     foreach (QString part, parts) {
         QFileInfo info(content[part].href);
         content[part].size = info.size();
+        size += content[part].size;
         t.trace(QString("Size of part %1: %2").arg(part).arg(content[part].size));
     }
 
@@ -424,3 +426,17 @@ int Book::partFromChapter(int index)
     }
     return partIndex;
 }
+
+qreal Book::getProgress(int part, qreal position)
+{
+    Q_ASSERT(part < parts.size());
+    QString key;
+    qreal partSize = 0;
+    for (int i = 0; i < part; i++) {
+        key = parts[i];
+        partSize += content[key].size;
+    }
+    key = parts[part];
+    partSize += content[key].size * position;
+    return partSize / (qreal)size;
+}
index e6a13c1..c60ae1c 100644 (file)
@@ -98,6 +98,9 @@ public:
     /** Get part index from chapter index. */
     int partFromChapter(int index);
 
+    /** Get progress (0..1) corresponding to part index and part position. */
+    qreal getProgress(int part, qreal position);
+
     QString title;                          //< Book title from EPUB.
     QStringList parts;                      //< EPUB part list.
     QHash<QString, ContentItem> content;    //< Content items from EPUB.
@@ -112,6 +115,7 @@ public:
     QString tocPath;                        //< Path to toc ncx.
     QString coverPath;                      //< Path to cover html.
     QStringList chapters;                   //< Main navigation items from EPUB.
+    qint64 size;                            //< Size of all parts.
 
 signals:
     /** Emitted if @see open() succeeds. */
index b13d588..d5598ee 100644 (file)
@@ -2,6 +2,7 @@ dorian (0.1.2-1) unstable; urgency=low
 
   * Improve cover image display
   * Fix naming: book parts vs. chapters
+  * Show reading progress
 
  -- Akos Polster <akos@pipacs.com>  Sat,  7 Aug 2010 20:00:00 +0200
 
diff --git a/widgets/progress.cpp b/widgets/progress.cpp
new file mode 100644 (file)
index 0000000..fa0d41d
--- /dev/null
@@ -0,0 +1,46 @@
+#include <QtGui>
+
+#include "progress.h"
+#include "trace.h"
+
+Progress::Progress(QWidget *parent): QLabel(parent), progress(0), timer(-1)
+{
+    hide();
+}
+
+void Progress::setProgress(qreal p)
+{
+    if (progress != p) {
+        progress = p;
+        flash();
+        update();
+    }
+}
+
+void Progress::paintEvent(QPaintEvent *e)
+{
+    Q_UNUSED(e);
+    QPainter painter(this);
+    painter.setBrush(QBrush(QColor(100, 100, 100, 177)));
+    painter.setPen(Qt::NoPen);
+    int w = int(width() * progress);
+    int h = height();
+    painter.drawRect(0, 0, w, h);
+    painter.setBrush(QBrush(QColor(100, 100, 100, 50)));
+    painter.drawRect(w, 0, width(), h);
+}
+
+void Progress::flash()
+{
+    killTimer(timer);
+    show();
+    timer = startTimer(400);
+}
+
+void Progress::timerEvent(QTimerEvent *e)
+{
+    if (e->timerId() == timer) {
+        killTimer(timer);
+        hide();
+    }
+}
diff --git a/widgets/progress.h b/widgets/progress.h
new file mode 100644 (file)
index 0000000..4cb5bd9
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef PROGRESS_H
+#define PROGRESS_H
+
+#include <QWidget>
+#include <QLabel>
+
+class Progress: public QLabel
+{
+    Q_OBJECT
+
+public:
+    explicit Progress(QWidget *parent = 0);
+
+signals:
+
+public slots:
+    void setProgress(qreal p);
+    void flash();
+
+protected:
+    void paintEvent(QPaintEvent *e);
+    void timerEvent(QTimerEvent *e);
+    qreal progress;
+    int timer;
+};
+
+#endif // PROGRESS_H
index 7160d12..6e61eba 100644 (file)
@@ -19,8 +19,6 @@ public slots:
 
 protected:
     virtual void paintEvent(QPaintEvent *);
-
-private:
     QString name;
     qreal mOpacity;
 };