diff options
| author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-07-21 04:30:08 +0000 |
|---|---|---|
| committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-07-21 04:30:08 +0000 |
| commit | a3570c360e8884f2bbf60b89e4d9531321ae01ad (patch) | |
| tree | a6bc829daca69956b99be4dfa3939ff14193ec54 /src/bookwidget.cpp | |
| download | kbookreader-a3570c360e8884f2bbf60b89e4d9531321ae01ad.tar.gz kbookreader-a3570c360e8884f2bbf60b89e4d9531321ae01ad.zip | |
Initial import of kbookreader
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kbookreader@1242482 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/bookwidget.cpp')
| -rw-r--r-- | src/bookwidget.cpp | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/src/bookwidget.cpp b/src/bookwidget.cpp new file mode 100644 index 0000000..8eec9df --- /dev/null +++ b/src/bookwidget.cpp @@ -0,0 +1,473 @@ +/*************************************************************************** +* Copyright (C) 2005 by Alexander Nemish * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#include <qpainter.h> +#include <qevent.h> +#include <qimage.h> +#include <kdebug.h> +#include <kprogress.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qtextcodec.h> +#include <qstring.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include "bookwidget.h" +#include "theme.h" +#include "settings.h" +#include "renderer.h" +//#include "ktextprogressdlg.h" + +class QStringList; +class QRect; +class QPixmap; + +BookWidget::BookWidget(QWidget *parent, const char *name) + : QWidget(parent, name), + m_modified(true), + m_currentPage(0), + m_left_margin(0), + m_right_margin(0), + m_top_margin(0), + m_bottom_margin(0), + m_middle_margin(0), + m_encoding(0), + m_renderer(new Renderer) +{ + //setupPageSize(); + //setupSlots(); + m_left_margin = 30; + m_right_margin = 30; + m_top_margin = 20; + m_bottom_margin = 15; + m_middle_margin = 20; + + setFont(Settings::font()); + + Theme::self()->loadTheme("default"); + + setWFlags(Qt::WNoAutoErase); + setFocusPolicy(QWidget::StrongFocus); + + connect(&m_timer, SIGNAL(timeout()), this, SLOT(loadLine())); + connect(m_renderer.get(), SIGNAL(renderingFinished()), this, SLOT(renderingFinished())); +} + + +BookWidget::~BookWidget() +{ +} + +void BookWidget::openURL(const KURL & url) +{ + m_url = url; + m_file.setName(m_url.path()); + if (! m_file.open(IO_ReadOnly)) return; + + ///@todo Write encoding detection + m_stream.reset(new QTextStream(&m_file)); + m_textLines.reset(new QStringList); + QString name(encoding()); + QTextCodec *codec = QTextCodec::codecForName(encoding()); // get the codec + if (codec) + m_stream->setCodec(codec); + //show progress dialog + m_progressDlg.reset(new KProgressDialog(this, "progressDlg", "Loading...", + "Loading file ", true)); + m_progressDlg->setLabel("Loading file " + m_url.path()); + m_progressDlg->setAllowCancel(true); + m_progressDlg->progressBar()->setTotalSteps(0); + connect(m_progressDlg.get(), SIGNAL(cancelClicked()), SLOT(cancelLoading())); + KDialog::centerOnScreen(m_progressDlg.get()); + m_progressDlg->show(); + //start timer for processing gui events + m_timer.start(0, false); + //load bookmark for the book + loadBookmarks(); + // just for fun, set the status bar + emit signalChangeStatusbar(m_url.prettyURL()); +} + +QString BookWidget::currentURL() +{ + return m_url.path(); +} + +void BookWidget::drawContent(QPainter& paint) +{ + const QRect lrect (rectLeftPage()); + const QRect rrect(rectRightPage()); + const unsigned int curPage = currentPage(); + //draw pages + m_renderer->drawPage(paint, lrect, curPage); + m_renderer->drawPage(paint, rrect, curPage + 1); +} + +void BookWidget::drawPageNumbers(QPainter & paint) +{ + if (m_renderer->isEmpty()) + return; + const QRect lrect (rectLeftPage()); + const QRect rrect(rectRightPage()); + const QString number = QString::number(currentPage() + 2); + // setup font + QFont pageFont(font()); + int pointSize = 10; + pageFont.setPointSize(pointSize); + pageFont.setBold(false); + pageFont.setItalic(false); + pageFont.setUnderline(false); + paint.setFont(pageFont); + const QFontMetrics fm(pageFont); + const int width = fm.width(number); + //paint page numbers + const int offset = 8; + paint.drawText(lrect.left(), QWidget::height() - offset, + QString::number(currentPage() + 1)); + paint.drawText(rrect.left() + rrect.width() - width, + QWidget::height() - offset, number); +} + +void BookWidget::drawBookmark(QPainter & paint, Bookmark const& bm) +{ + const QRect lrect (rectLeftPage()); + const QRect rrect(rectRightPage()); + const QPixmap & bookmarkImage = Theme::self()->bookmarkPixmap(); + const int width = bookmarkImage.width(); + paint.drawPixmap(QWidget::width()/2 - width/2, 0, bookmarkImage); + if (!bm.name().isEmpty()) + { + paint.save(); + paint.translate(QWidget::width()/2., 20.); + paint.rotate(90.); + const QString text = bm.name() + " (" + bm.dateTime().toString(Qt::LocalDate) + ")"; + paint.drawText(0, 0, text); + paint.restore(); + } +} + +void BookWidget::paintEvent(QPaintEvent* event) +{ + // use cached page pixmap if the page wasn't modified + if (!modified()) + { + QRect rect(event->rect()); + bitBlt(this, rect.x(), rect.y(), &m_cachePixmap, rect.x(), rect.y(), rect.width(), rect.height()); + return; + } + // do full painting otherwise + setupPageSize(); + const QRect lrect (rectLeftPage()); + const QRect rrect(rectRightPage()); + const unsigned int curPage = currentPage(); + QPixmap pm(size()); + QPainter paint(&pm); + //draw background image + const QPixmap & image = Theme::self()->bgPixmap(QWidget::size()); + paint.drawPixmap(0, 0, image); + if (m_renderer->busy()) + { + QFont f(font()); + f.setPointSize(20); + paint.setFont(f); + const QFontMetrics fm(f); + QString text = tr("Rendering..."); + const int w = fm.width(text); + const int h = fm.height(); + const int dx = (lrect.width() - w) / 2; + const int dy = (lrect.height() - h) / 2; + paint.drawText(lrect.x() + dx, lrect.y() + dy, text); + paint.drawText(rrect.x() + dx, rrect.y() + dy, text); + } + else + { + paint.setFont(font()); + //draw pages + drawContent(paint); + drawPageNumbers(paint); + //draw bookmark if it is + typedef Bookmarks::const_iterator IT; + IT it = std::lower_bound(m_bookmarks.begin(), m_bookmarks.end(), curPage); + if (it != m_bookmarks.end() && (*it).page() == curPage) + drawBookmark(paint, *it); + } + paint.end(); + bitBlt(this, 0, 0, &pm); + // store painted pixmap as cache + m_cachePixmap = pm; + m_modified = false; +} + +void BookWidget::setupPageSize() +{ + QSize size((width() - m_left_margin - m_right_margin - 2 * m_middle_margin) / 2, + (height() - m_top_margin - m_bottom_margin)); + m_renderer->setPageSize(size); +} + +void BookWidget::mousePressEvent(QMouseEvent * event) +{ + if (event->button() == LeftButton) + { + if (rectLeftPage().contains(event->pos())) + { + prevPage(); + } + else if (rectRightPage().contains(event->pos())) + { + nextPage(); + } + } + QWidget::mousePressEvent(event); +} + +const QRect BookWidget::rectLeftPage() const +{ + return QRect(m_left_margin, m_top_margin, + m_renderer->pageSize().width(), + m_renderer->pageSize().height()); +} + +const QRect BookWidget::rectRightPage() const +{ + return QRect(m_left_margin + 2 * m_middle_margin + m_renderer->pageSize().width(), + m_top_margin, + m_renderer->pageSize().width(), + m_renderer->pageSize().height()); +} + +void BookWidget::clearAll() +{ + setCurrentPage(0); +} + + +void BookWidget::prevPage() +{ + setCurrentPage(currentPage() - 2); +} + +void BookWidget::nextPage() +{ + setCurrentPage(currentPage() + 2); +} + +void BookWidget::firstPage() +{ + setCurrentPage(0); +} + +void BookWidget::lastPage() +{ + setCurrentPage(m_renderer->pageCount() - 1); +} + +void BookWidget::wheelEvent(QWheelEvent * e) +{ + e->accept(); + if (e->delta() > 0) + prevPage(); + else nextPage(); +} + +void BookWidget::resizeEvent(QResizeEvent * e) +{ + m_modified = true; + setupPageSize(); + m_renderer->render(); +// //if size become lower recalc current page +// if (currentPage() > m_renderer->pageCount()) +// lastPage(); + QWidget::resizeEvent(e); +} + +QSize BookWidget::minimumSizeHint() const +{ + return QSize(400, 300); +} + +void BookWidget::setFont(const QFont & font) +{ + m_modified = true; + QWidget::setFont(font); + m_renderer->setFont(font); + update(); +} + +void BookWidget::setCurrentPage(int number) +{ + // do nothing while renderer is working + if (m_renderer->busy()) + return; + if (number >= m_renderer->pageCount()) + number = m_renderer->pageCount() - 1; + if (number < 0) number = 0; + //only even page numbers allowed + int newPage = (number % 2) ? number - 1 : number; + if (newPage != m_currentPage) + m_modified = true; + m_currentPage = newPage; + update(); +} + +void BookWidget::keyPressEvent(QKeyEvent * e) +{ + if (e->key() == Qt::Key_Right || e->key() == Qt::Key_Down + || e->key() == Qt::Key_Space) + { + nextPage(); + } + else if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Up) + { + prevPage(); + } + else if (e->key() == Qt::Key_Home) + { + firstPage(); + } + else if (e->key() == Qt::Key_End) + { + lastPage(); + } + + QWidget::keyPressEvent(e); +} + +void BookWidget::loadLine() +{ + static int lineCount = 0; + if (!m_stream->eof()) + { + *m_textLines << m_stream->readLine(); + //progress update after every 50 lines + if (!(++lineCount % 50)) + m_progressDlg->progressBar()->setProgress( + m_progressDlg->progressBar()->progress() + 1); + return; + } + m_timer.stop(); + //render + m_renderer->load(*m_textLines); + //setup and show + firstPage(); + //clean up + m_progressDlg.reset(0); + m_stream.reset(0); + m_textLines.reset(0); + m_file.close(); + m_modified = true; + emit loadingFinished(); +} + +void BookWidget::cancelLoading() +{ + m_timer.stop(); + if (parentWidget()) + parentWidget()->setCaption(""); + //clean up + m_progressDlg->hide(); + m_stream.reset(0); + m_textLines.reset(0); + m_file.close(); + //setup and show + m_renderer->clear(); + firstPage(); +} + +void BookWidget::setParaOffset(int offset) +{ + m_modified = true; + m_renderer->setParaOffset(offset); + update(); +} + +void BookWidget::setEncoding(int a_encoding) +{ + m_encoding = a_encoding; +} + +void BookWidget::setEncodings(const QStringList & a_encodings) +{ + m_encodings = a_encodings; +} + +void BookWidget::setEncoding(const QString & a_encoding) +{ + m_encoding = (m_encodings.findIndex(a_encoding)); +} + +void BookWidget::addBookmark(const QString& name) +{ + m_bookmarks.push_back(Bookmark(currentPage(), name)); + std::sort(m_bookmarks.begin(), m_bookmarks.end()); + +// KAction menu = new KAction() + + saveBookmarks(); +} + +void BookWidget::saveBookmarks( ) +{ + const QString fileName = "bookreader/" + m_url.fileName(); + QFile::remove(KGlobal::dirs()->findResource("appdata", m_url.fileName())); + KConfig config(fileName, false, false, "data"); + for (Bookmarks::size_type i = 0; i < m_bookmarks.size(); ++i) + { + const Bookmark & bm = m_bookmarks[i]; + config.setGroup(tr("Bookmark %1").arg(i)); + config.writeEntry("page", bm.page()); + config.writeEntry("name", bm.name()); + config.writeEntry("dateTime", bm.dateTime()); + } +} + +void BookWidget::loadBookmarks() +{ + m_bookmarks.clear(); + const QString fileName = "bookreader/" + m_url.fileName(); + KConfig config(fileName, true, false, "data"); + QStringList groups = config.groupList(); + typedef QStringList::const_iterator IT; + for (IT it = groups.constBegin(); it != groups.constEnd(); ++it) + { + config.setGroup(*it); + const QString name = config.readEntry("name"); + const unsigned int page = config.readUnsignedNumEntry("page"); + const QDateTime dateTime = config.readDateTimeEntry("dateTime"); + const Bookmark bm(page, name, dateTime); + m_bookmarks.push_back(bm); + } + std::sort(m_bookmarks.begin(), m_bookmarks.end()); +} + +void BookWidget::setBookmarks(const Bookmarks & bms) +{ + m_bookmarks.clear(); + m_bookmarks = bms; + std::sort(m_bookmarks.begin(), m_bookmarks.end()); + saveBookmarks(); +} + +void BookWidget::renderingFinished() +{ + m_modified = true; + setCurrentPage(currentPage()); + update(); +} + +#include "bookwidget.moc" |
