5 # include <QtGui/QX11Info>
7 # include <X11/Xatom.h>
8 # include <mce/mode-names.h>
9 # include <mce/dbus-names.h>
10 #endif // Q_WS_MAEMO_5
15 #include "infodialog.h"
16 #include "librarydialog.h"
18 #include "mainwindow.h"
19 #include "settingswindow.h"
20 #include "bookmarksdialog.h"
22 #include "chaptersdialog.h"
23 #include "fullscreenwindow.h"
25 #include "bookfinder.h"
28 #include "translucentbutton.h"
30 #include "progressdialog.h"
32 #ifdef DORIAN_TEST_MODEL
33 # include "modeltest.h"
36 const int DORIAN_PROGRESS_HEIGHT = 17;
38 MainWindow::MainWindow(QWidget *parent):
39 AdopterWindow(parent), view(0), preventBlankingTimer(-1)
43 setAttribute(Qt::WA_Maemo5StackedWindow, true);
45 setWindowTitle("Dorian");
47 // Central widget. Must be an intermediate, because the book view widget
48 // can be re-parented later
49 QFrame *central = new QFrame(this);
50 QVBoxLayout *layout = new QVBoxLayout(central);
52 central->setLayout(layout);
53 setCentralWidget(central);
56 view = new BookView(central);
58 layout->addWidget(view);
61 progress = new Progress(central);
64 settings = new QDialog(this);
69 fullScreenAction = addToolBarAction(this, SLOT(showBig()),
70 "view-fullscreen", tr("Full screen"));
73 chaptersAction = addToolBarAction(this, SLOT(showChapters()),
74 "chapters", tr("Chapters"));
75 bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()),
76 "bookmarks", tr("Bookmarks"));
77 infoAction = addToolBarAction(this, SLOT(showInfo()),
78 "info", tr("Book info"));
79 libraryAction = addToolBarAction(this, SLOT(showLibrary()),
80 "library", tr("Library"));
83 settingsAction = menuBar()->addAction(tr("Settings"));
84 connect(settingsAction, SIGNAL(triggered()), this, SLOT(showSettings()));
85 devToolsAction = menuBar()->addAction(tr("Developer"));
86 connect(devToolsAction, SIGNAL(triggered()), this, SLOT(showDevTools()));
87 QAction *aboutAction = menuBar()->addAction(tr("About"));
88 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
90 settingsAction = addToolBarAction(this, SLOT(showSettings()),
91 "preferences-system", tr("Settings"));
92 devToolsAction = addToolBarAction(this, SLOT(showDevTools()),
93 "developer", tr("Developer"));
94 addToolBarAction(this, SLOT(about()), "about", tr("About"));
95 #endif // Q_WS_MAEMO_5
99 fullScreenAction = addToolBarAction(this, SLOT(showBig()),
100 "view-fullscreen", tr("Full screen"));
102 (void)addToolBarAction(this, SLOT(close()), "", tr("Exit"));
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 libraryProgress = new ProgressDialog(tr("Upgrading library"), this);
115 Library *library = Library::instance();
116 connect(library, SIGNAL(beginUpgrade(int)), this, SLOT(onBeginUpgrade(int)));
117 connect(library, SIGNAL(upgrading(const QString &)),
118 this, SLOT(onUpgrading(const QString &)));
119 connect(library, SIGNAL(endUpgrade()), this, SLOT(onEndUpgrade()));
120 connect(library, SIGNAL(beginLoad(int)), this, SLOT(onBeginLoad(int)));
121 connect(library, SIGNAL(loading(const QString &)),
122 this, SLOT(onLoading(const QString &)));
123 connect(library, SIGNAL(endLoad()), this, SLOT(onEndLoad()));
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()
188 // Re-parent children
189 fullScreenWindow->leaveChildren();
190 QList<QWidget *> otherChildren;
191 otherChildren << progress << previousButton << nextButton;
192 takeChildren(view, otherChildren);
194 // Adjust geometry of decorations
195 QRect geo = geometry();
196 progress->setGeometry(0, 0, geo.width(), DORIAN_PROGRESS_HEIGHT);
197 #if defined(Q_WS_MAEMO_5)
198 previousButton->setGeometry(0,
199 geo.height() - toolBar->height() - TranslucentButton::pixels,
200 TranslucentButton::pixels, TranslucentButton::pixels);
201 nextButton->setGeometry(geo.width() - TranslucentButton::pixels, 0,
202 TranslucentButton::pixels, TranslucentButton::pixels);
203 #elif defined(Q_OS_SYMBIAN)
204 previousButton->setGeometry(0, geo.height() - TranslucentButton::pixels,
205 TranslucentButton::pixels, TranslucentButton::pixels);
206 nextButton->setGeometry(geo.width() - TranslucentButton::pixels,
207 0, TranslucentButton::pixels, TranslucentButton::pixels);
209 previousButton->setGeometry(0, geo.height() - TranslucentButton::pixels,
210 TranslucentButton::pixels, TranslucentButton::pixels);
211 nextButton->setGeometry(geo.width() - TranslucentButton::pixels - 25,
212 toolBar->height(), TranslucentButton::pixels,
213 TranslucentButton::pixels);
214 #endif // Q_WS_MAEMO_5
215 qDebug() << "previousButton geometry" << previousButton->geometry();
217 fullScreenWindow->hide();
219 #if defined(Q_OS_SYMBIAN)
221 #elif defined(Q_WS_MAEMO_5)
222 // FIXME: This is ugly.
223 view->restoreLastBookmark();
227 previousButton->flash();
230 void MainWindow::showBig()
234 // Re-parent children
236 QList<QWidget *> otherChildren;
237 otherChildren << progress << nextButton << previousButton;
238 fullScreenWindow->takeChildren(view, otherChildren);
240 // Adjust geometry of decorations
241 QRect screen = QApplication::desktop()->screenGeometry();
242 progress->setGeometry(0, 0, screen.width(), DORIAN_PROGRESS_HEIGHT);
243 #if defined(Q_WS_MAEMO_5)
244 nextButton->setGeometry(screen.width() - TranslucentButton::pixels, 0,
245 TranslucentButton::pixels, TranslucentButton::pixels);
247 nextButton->setGeometry(screen.width() - TranslucentButton::pixels - 25, 0,
248 TranslucentButton::pixels, TranslucentButton::pixels);
249 #endif // Q_WS_MAEMO_5
250 previousButton->setGeometry(0, screen.height() - TranslucentButton::pixels,
251 TranslucentButton::pixels, TranslucentButton::pixels);
256 fullScreenWindow->showFullScreen();
258 fullScreenWindow->activateWindow();
262 previousButton->flash();
265 void MainWindow::setCurrentBook(const QModelIndex ¤t)
268 Book *book = Library::instance()->book(current);
270 setWindowTitle(book? book->shortName(): tr("Dorian"));
273 void MainWindow::showLibrary()
275 (new LibraryDialog(this))->show();
278 void MainWindow::showSettings()
280 (new SettingsWindow(this))->show();
283 void MainWindow::showInfo()
285 if (mCurrent.isValid()) {
286 (new InfoDialog(Library::instance()->book(mCurrent), this, false))->
291 void MainWindow::showDevTools()
293 (new DevTools())->exec();
296 void MainWindow::showBookmarks()
298 Book *book = Library::instance()->book(mCurrent);
300 BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
301 bookmarks->setWindowModality(Qt::WindowModal);
302 connect(bookmarks, SIGNAL(addBookmark(const QString &)),
303 this, SLOT(onAddBookmark(const QString &)));
304 connect(bookmarks, SIGNAL(goToBookmark(int)),
305 this, SLOT(onGoToBookmark(int)));
310 void MainWindow::closeEvent(QCloseEvent *event)
313 view->setLastBookmark();
317 void MainWindow::onSettingsChanged(const QString &key)
319 #if defined(Q_WS_MAEMO_5)
320 if (key == "orientation") {
321 QString value = Settings::instance()->value(key).toString();
322 qDebug() << "MainWindow::onSettingsChanged: orientation" << value;
323 if (value == "portrait") {
324 setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
325 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
327 setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
328 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
330 } else if (key == "lightson") {
331 bool enable = Settings::instance()->value(key, false).toBool();
332 qDebug() << "MainWindow::onSettingsChanged: lightson:" << enable;
333 killTimer(preventBlankingTimer);
335 preventBlankingTimer = startTimer(29 * 1000);
337 } else if (key == "usevolumekeys") {
338 bool value = Settings::instance()->value(key).toBool();
339 qDebug() << "MainWindow::onSettingsChanged: usevolumekeys" << value;
341 fullScreenWindow->grabZoomKeys(value);
345 #endif // Q_WS_MAEMO_5
348 void MainWindow::onPartLoadStart()
352 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
356 void MainWindow::onPartLoadEnd(int index)
359 bool enablePrevious = false;
360 bool enableNext = false;
361 Book *book = Library::instance()->book(mCurrent);
364 enablePrevious = true;
366 if (index < (book->parts.size() - 1)) {
371 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
372 #endif // Q_WS_MAEMO_5
375 void MainWindow::onAddBookmark(const QString ¬e)
378 view->addBookmark(note);
379 Platform::information(tr("Bookmarked current position"), this);
382 void MainWindow::onGoToBookmark(int index)
385 Book *book = Library::instance()->book(mCurrent);
386 view->goToBookmark(book->bookmarks()[index]);
389 void MainWindow::showChapters()
391 Book *book = Library::instance()->book(mCurrent);
393 ChaptersDialog *chapters = new ChaptersDialog(book, this);
394 chapters->setWindowModality(Qt::WindowModal);
395 connect(chapters, SIGNAL(goToChapter(int)),
396 this, SLOT(onGoToChapter(int)));
401 void MainWindow::onGoToChapter(int index)
405 Book *book = Library::instance()->book(mCurrent);
408 int partIndex = book->partFromChapter(index, fragment);
409 if (partIndex != -1) {
410 view->goToPart(partIndex, fragment);
415 void MainWindow::timerEvent(QTimerEvent *event)
417 if (event->timerId() == preventBlankingTimer) {
419 QDBusInterface mce(MCE_SERVICE, MCE_REQUEST_PATH,
420 MCE_REQUEST_IF, QDBusConnection::systemBus());
421 mce.call(MCE_PREVENT_BLANK_REQ);
422 #endif // Q_WS_MAEMO_5
423 qDebug() << "MainWindow::timerEvent: Prevent display blanking";
425 AdopterWindow::timerEvent(event);
428 void MainWindow::resizeEvent(QResizeEvent *e)
431 progress->setGeometry(QRect(0, 0, e->size().width(), DORIAN_PROGRESS_HEIGHT));
432 #if defined(Q_WS_MAEMO_5)
433 previousButton->setGeometry(0,
434 e->size().height() - toolBar->height() - TranslucentButton::pixels,
435 TranslucentButton::pixels, TranslucentButton::pixels);
436 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels, 0,
437 TranslucentButton::pixels, TranslucentButton::pixels);
438 #elif defined(Q_OS_SYMBIAN)
439 previousButton->setGeometry(0, e->size().height() - TranslucentButton::pixels,
440 TranslucentButton::pixels, TranslucentButton::pixels);
441 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels,
442 0, TranslucentButton::pixels, TranslucentButton::pixels);
444 previousButton->setGeometry(0, e->size().height() - TranslucentButton::pixels,
445 TranslucentButton::pixels, TranslucentButton::pixels);
446 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels - 25,
447 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
448 #endif // Q_WS_MAEMO_5
449 qDebug() << "previousButton geometry" << previousButton->geometry();
450 previousButton->flash();
452 QMainWindow::resizeEvent(e);
455 void MainWindow::about()
457 Dyalog *aboutDialog = new Dyalog(this, false);
458 aboutDialog->setWindowTitle(tr("About Dorian"));
459 QLabel *label = new QLabel(aboutDialog);
460 label->setTextFormat(Qt::RichText);
461 label->setOpenExternalLinks(true);
462 label->setWordWrap(true);
463 label->setText(tr("<b>Dorian %1</b><br><br>Copyright © 2010 "
464 "Akos Polster <akos@pipacs.com><br>"
465 "Licensed under GNU General Public License, Version 3<br>"
466 "Source code:<br><a href='https://garage.maemo.org/projects/dorian/'>"
467 "garage.maemo.org/projects/dorian</a>").arg(Platform::version()));
468 aboutDialog->addWidget(label);
469 aboutDialog->addStretch();
474 void MainWindow::goToNextPage()
477 previousButton->flash();
481 void MainWindow::goToPreviousPage()
484 previousButton->flash();
485 view->goPreviousPage();
488 void MainWindow::onBeginUpgrade(int total)
490 libraryProgress->setVisible(total > 0);
491 libraryProgress->setWindowTitle(tr("Upgrading library"));
492 libraryProgress->setMaximum(total);
495 void MainWindow::onUpgrading(const QString &path)
497 libraryProgress->setLabelText(tr("Upgrading %1").
498 arg(QFileInfo(path).fileName()));
499 libraryProgress->setValue(libraryProgress->value() + 1);
502 void MainWindow::onEndUpgrade()
504 libraryProgress->hide();
505 libraryProgress->reset();
509 void MainWindow::onBeginLoad(int total)
511 libraryProgress->setVisible(total > 0);
512 libraryProgress->setWindowTitle(tr("Loading library"));
513 libraryProgress->setMaximum(total);
516 void MainWindow::onLoading(const QString &path)
518 libraryProgress->setLabelText(tr("Loading %1").
519 arg(QFileInfo(path).fileName()));
520 libraryProgress->setValue(libraryProgress->value() + 1);
523 void MainWindow::onEndLoad()
525 libraryProgress->hide();
526 libraryProgress->reset();