4 #include <QApplication>
11 # include <QtMaemo5/QMaemo5InformationBox>
13 # include <QtGui/QX11Info>
14 # include <X11/Xlib.h>
15 # include <X11/Xatom.h>
16 # include <mce/mode-names.h>
17 # include <mce/dbus-names.h>
18 #endif // Q_WS_MAEMO_5
23 #include "infodialog.h"
24 #include "librarydialog.h"
26 #include "mainwindow.h"
27 #include "settingswindow.h"
28 #include "bookmarksdialog.h"
30 #include "chaptersdialog.h"
31 #include "fullscreenwindow.h"
33 #include "bookfinder.h"
36 #include "translucentbutton.h"
38 #ifdef DORIAN_TEST_MODEL
39 # include "modeltest.h"
42 const int PROGRESS_HEIGHT = 17;
43 static const char *DORIAN_VERSION =
44 #include "pkg/version.txt"
47 MainWindow::MainWindow(QWidget *parent):
48 AdopterWindow(parent), view(0), preventBlankingTimer(-1)
50 Trace t("MainWindow::MainWindow");
52 setAttribute(Qt::WA_Maemo5StackedWindow, true);
54 setWindowTitle("Dorian");
56 // Central widget. Must be an intermediate, because the book view widget
57 // can be re-parented later
58 QFrame *central = new QFrame(this);
59 QVBoxLayout *layout = new QVBoxLayout(central);
61 central->setLayout(layout);
62 setCentralWidget(central);
65 view = new BookView(central);
67 layout->addWidget(view);
70 progress = new Progress(central);
73 settings = new QDialog(this);
77 chaptersAction = addToolBarAction(this, SLOT(showChapters()),
78 "chapters", tr("Chapters"));
79 bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()),
80 "bookmarks", tr("Bookmarks"));
81 infoAction = addToolBarAction(this, SLOT(showInfo()),
82 "info", tr("Book info"));
83 libraryAction = addToolBarAction(this, SLOT(showLibrary()),
84 "library", tr("Library"));
87 settingsAction = menuBar()->addAction(tr("Settings"));
88 connect(settingsAction, SIGNAL(triggered()), this, SLOT(showSettings()));
89 devToolsAction = menuBar()->addAction(tr("Developer"));
90 connect(devToolsAction, SIGNAL(triggered()), this, SLOT(showDevTools()));
91 QAction *aboutAction = menuBar()->addAction(tr("About"));
92 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
94 settingsAction = addToolBarAction(this, SLOT(showSettings()),
95 "preferences-system", tr("Settings"));
96 devToolsAction = addToolBarAction(this, SLOT(showDevTools()),
97 "developer", tr("Developer"));
98 addToolBarAction(this, SLOT(about()), "about", tr("About"));
99 #endif // Q_WS_MAEMO_5
102 fullScreenAction = addToolBarAction(this, SLOT(showBig()),
103 "view-fullscreen", tr("Full screen"));
105 // Buttons on top of the book view
106 previousButton = new TranslucentButton("back", this);
107 nextButton = new TranslucentButton("forward", this);
109 // Handle model changes
110 connect(Library::instance(), SIGNAL(nowReadingChanged()),
111 this, SLOT(onCurrentBookChanged()));
113 // Load library, upgrade it if needed
114 upgradeProgress = new QProgressDialog(tr("Upgrading library"), "", 0, 0, this);
115 upgradeProgress->reset();
116 upgradeProgress->setMinimumDuration(0);
117 upgradeProgress->setWindowModality(Qt::WindowModal);
118 upgradeProgress->setCancelButton(0);
119 Library *library = Library::instance();
120 connect(library, SIGNAL(beginUpgrade(int)), this, SLOT(onBeginUpgrade(int)));
121 connect(library, SIGNAL(upgrading(const QString &)),
122 this, SLOT(onUpgrading(const QString &)));
123 connect(library, SIGNAL(endUpgrade()), this, SLOT(onEndUpgrade()));
127 // Load book on command line, or load last read book, or load default book
128 if (QCoreApplication::arguments().size() == 2) {
129 QString path = QCoreApplication::arguments()[1];
131 QModelIndex index = library->find(path);
132 if (index.isValid()) {
133 library->setNowReading(index);
136 QModelIndex index = library->nowReading();
137 if (index.isValid()) {
138 library->setNowReading(index);
140 if (!library->rowCount()) {
141 library->add(":/books/2BR02B.epub");
143 library->setNowReading(library->index(0));
147 // Handle loading book parts
148 connect(view, SIGNAL(partLoadStart(int)), this, SLOT(onPartLoadStart()));
149 connect(view, SIGNAL(partLoadEnd(int)), this, SLOT(onPartLoadEnd(int)));
152 connect(view, SIGNAL(progress(qreal)), progress, SLOT(setProgress(qreal)));
154 // Shadow window for full screen reading
155 fullScreenWindow = new FullScreenWindow(this);
156 connect(fullScreenWindow, SIGNAL(restore()), this, SLOT(showRegular()));
158 // Handle settings changes
159 Settings *settings = Settings::instance();
160 connect(settings, SIGNAL(valueChanged(const QString &)),
161 this, SLOT(onSettingsChanged(const QString &)));
162 settings->setValue("orientation", settings->value("orientation"));
163 settings->setValue("lightson", settings->value("lightson"));
164 settings->setValue("usevolumekeys", settings->value("usevolumekeys"));
166 // Handle book view buttons
167 connect(nextButton, SIGNAL(triggered()), this, SLOT(goToNextPage()));
168 connect(previousButton, SIGNAL(triggered()), this, SLOT(goToPreviousPage()));
170 #ifdef DORIAN_TEST_MODEL
171 (void)new ModelTest(Library::instance(), this);
175 MainWindow::~MainWindow()
179 void MainWindow::onCurrentBookChanged()
181 setCurrentBook(Library::instance()->nowReading());
184 void MainWindow::showRegular()
186 Trace t("MainWindow::showRegular");
187 fullScreenWindow->hide();
188 fullScreenWindow->leaveChildren();
190 QList<QWidget *> otherChildren;
191 otherChildren << progress << previousButton << nextButton;
192 takeChildren(view, otherChildren);
193 QRect geo = geometry();
194 progress->setGeometry(0, 0, geo.width(), PROGRESS_HEIGHT);
195 #if defined(Q_WS_MAEMO_5)
196 previousButton->setGeometry(0,
197 geo.height() - toolBar->height() - TranslucentButton::pixels,
198 TranslucentButton::pixels, TranslucentButton::pixels);
199 nextButton->setGeometry(geo.width() - TranslucentButton::pixels, 0,
200 TranslucentButton::pixels, TranslucentButton::pixels);
201 #elif defined(Q_OS_SYMBIAN)
202 previousButton->setGeometry(0, geo.height() - TranslucentButton::pixels,
203 TranslucentButton::pixels, TranslucentButton::pixels);
204 nextButton->setGeometry(geo.width() - TranslucentButton::pixels,
205 0, TranslucentButton::pixels, TranslucentButton::pixels);
207 previousButton->setGeometry(0, geo.height() - TranslucentButton::pixels,
208 TranslucentButton::pixels, TranslucentButton::pixels);
209 nextButton->setGeometry(geo.width() - TranslucentButton::pixels - 25,
210 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
211 #endif // Q_WS_MAEMO_5
212 qDebug() << "previousButton geometry" << previousButton->geometry();
215 previousButton->show();
216 nextButton->flash(1500);
217 previousButton->flash(1500);
220 void MainWindow::showBig()
222 Trace t("MainWindow::showBig");
224 QList<QWidget *> otherChildren;
225 otherChildren << progress << nextButton << previousButton;
226 QRect screen = QApplication::desktop()->screenGeometry();
227 progress->setGeometry(0, 0, screen.width(), PROGRESS_HEIGHT);
228 #if defined(Q_WS_MAEMO_5)
229 nextButton->setGeometry(screen.width() - TranslucentButton::pixels, 0,
230 TranslucentButton::pixels, TranslucentButton::pixels);
232 nextButton->setGeometry(screen.width() - TranslucentButton::pixels - 25, 0,
233 TranslucentButton::pixels, TranslucentButton::pixels);
234 #endif // Q_WS_MAEMO_5
235 previousButton->setGeometry(0, screen.height() - TranslucentButton::pixels,
236 TranslucentButton::pixels, TranslucentButton::pixels);
238 fullScreenWindow->takeChildren(view, otherChildren);
239 fullScreenWindow->showFullScreen();
241 nextButton->flash(1500);
242 previousButton->flash(1500);
245 void MainWindow::setCurrentBook(const QModelIndex ¤t)
248 Book *book = Library::instance()->book(current);
250 setWindowTitle(book? book->shortName(): tr("Dorian"));
253 void MainWindow::showLibrary()
255 (new LibraryDialog(this))->show();
258 void MainWindow::showSettings()
260 (new SettingsWindow(this))->show();
263 void MainWindow::showInfo()
265 if (mCurrent.isValid()) {
266 (new InfoDialog(Library::instance()->book(mCurrent), this, false))->
271 void MainWindow::showDevTools()
273 (new DevTools())->exec();
276 void MainWindow::showBookmarks()
278 Book *book = Library::instance()->book(mCurrent);
280 BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
281 bookmarks->setWindowModality(Qt::WindowModal);
282 connect(bookmarks, SIGNAL(addBookmark()), this, SLOT(onAddBookmark()));
283 connect(bookmarks, SIGNAL(goToBookmark(int)),
284 this, SLOT(onGoToBookmark(int)));
289 void MainWindow::closeEvent(QCloseEvent *event)
291 Trace t("MainWindow::closeEvent");
292 view->setLastBookmark();
296 void MainWindow::onSettingsChanged(const QString &key)
299 if (key == "orientation") {
300 QString value = Settings::instance()->value(key).toString();
301 qDebug() << "MainWindow::onSettingsChanged: orientation" << value;
302 if (value == "portrait") {
303 setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
304 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
306 setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
307 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
309 } else if (key == "lightson") {
310 bool enable = Settings::instance()->value(key, false).toBool();
311 qDebug() << "MainWindow::onSettingsChanged: lightson:" << enable;
312 killTimer(preventBlankingTimer);
314 preventBlankingTimer = startTimer(29 * 1000);
316 } else if (key == "usevolumekeys") {
317 bool value = Settings::instance()->value(key).toBool();
318 qDebug() << "MainWindow::onSettingsChanged: usevolumekeys" << value;
320 fullScreenWindow->grabZoomKeys(value);
324 #endif // Q_WS_MAEMO_5
327 void MainWindow::onPartLoadStart()
329 Trace t("MainWindow::onPartLoadStart");
331 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
335 void MainWindow::onPartLoadEnd(int index)
337 Trace t("MainWindow::onPartLoadEnd");
338 bool enablePrevious = false;
339 bool enableNext = false;
340 Book *book = Library::instance()->book(mCurrent);
343 enablePrevious = true;
345 if (index < (book->parts.size() - 1)) {
350 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
351 #endif // Q_WS_MAEMO_5
354 void MainWindow::onAddBookmark()
356 Trace t("MainWindow:onAddBookmark");
360 void MainWindow::onGoToBookmark(int index)
362 Trace t("MainWindow::onGoToBookmark");
363 Book *book = Library::instance()->book(mCurrent);
364 view->goToBookmark(book->bookmarks()[index]);
367 void MainWindow::showChapters()
369 Book *book = Library::instance()->book(mCurrent);
371 ChaptersDialog *chapters = new ChaptersDialog(book, this);
372 chapters->setWindowModality(Qt::WindowModal);
373 connect(chapters, SIGNAL(goToChapter(int)),
374 this, SLOT(onGoToChapter(int)));
379 void MainWindow::onGoToChapter(int index)
381 Trace t("MainWindow::onGoToChapter");
383 Book *book = Library::instance()->book(mCurrent);
385 int partIndex = book->partFromChapter(index);
386 if (partIndex != -1) {
387 view->goToBookmark(Book::Bookmark(partIndex, 0));
392 void MainWindow::timerEvent(QTimerEvent *event)
394 if (event->timerId() == preventBlankingTimer) {
396 QDBusInterface mce(MCE_SERVICE, MCE_REQUEST_PATH,
397 MCE_REQUEST_IF, QDBusConnection::systemBus());
398 mce.call(MCE_PREVENT_BLANK_REQ);
399 #endif // Q_WS_MAEMO_5
400 qDebug() << "MainWindow::timerEvent: Prevent display blanking";
404 void MainWindow::resizeEvent(QResizeEvent *e)
406 Trace t("MainWindow::resizeEvent");
407 progress->setGeometry(QRect(0, 0, e->size().width(), PROGRESS_HEIGHT));
408 #if defined(Q_WS_MAEMO_5)
409 previousButton->setGeometry(0,
410 e->size().height() - toolBar->height() - TranslucentButton::pixels,
411 TranslucentButton::pixels, TranslucentButton::pixels);
412 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels, 0,
413 TranslucentButton::pixels, TranslucentButton::pixels);
414 #elif defined(Q_OS_SYMBIAN)
415 previousButton->setGeometry(0, e->size().height() - TranslucentButton::pixels,
416 TranslucentButton::pixels, TranslucentButton::pixels);
417 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels,
418 0, TranslucentButton::pixels, TranslucentButton::pixels);
420 previousButton->setGeometry(0, e->size().height() - TranslucentButton::pixels,
421 TranslucentButton::pixels, TranslucentButton::pixels);
422 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels - 25,
423 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
424 #endif // Q_WS_MAEMO_5
425 qDebug() << "previousButton geometry" << previousButton->geometry();
426 previousButton->flash(1500);
427 nextButton->flash(1500);
428 QMainWindow::resizeEvent(e);
431 void MainWindow::about()
433 Dyalog *aboutDialog = new Dyalog(this);
434 aboutDialog->setWindowTitle(tr("About Dorian"));
435 QLabel *label = new QLabel(aboutDialog);
436 label->setTextFormat(Qt::RichText);
437 label->setOpenExternalLinks(true);
438 label->setWordWrap(true);
439 label->setText(tr("<b>Dorian %1</b><br><br>Copyright © 2010 "
440 "Akos Polster <akos@pipacs.com><br>"
441 "Licensed under GNU General Public License, Version 3<br>"
442 "Source code: <a href='https://garage.maemo.org/projects/dorian/'>"
443 "garage.maemo.org/projects/dorian</a>").arg(DORIAN_VERSION));
444 aboutDialog->addWidget(label);
445 aboutDialog->addStretch();
450 void MainWindow::goToNextPage()
452 nextButton->flash(1500);
453 previousButton->flash(1500);
457 void MainWindow::goToPreviousPage()
459 nextButton->flash(1500);
460 previousButton->flash(1500);
461 view->goPreviousPage();
464 void MainWindow::onBeginUpgrade(int total)
466 upgradeProgress->setVisible(total > 0);
467 upgradeProgress->setMaximum(total);
470 void MainWindow::onUpgrading(const QString &path)
472 upgradeProgress->setLabelText(tr("Upgrading %1").
473 arg(QFileInfo(path).fileName()));
474 upgradeProgress->setValue(upgradeProgress->value() + 1);
477 void MainWindow::onEndUpgrade()
479 upgradeProgress->hide();
480 upgradeProgress->reset();