4 #include <QApplication>
9 # include <QtMaemo5/QMaemo5InformationBox>
11 # include <QtGui/QX11Info>
12 # include <X11/Xlib.h>
13 # include <X11/Xatom.h>
14 # include <mce/mode-names.h>
15 # include <mce/dbus-names.h>
16 #endif // Q_WS_MAEMO_5
21 #include "infodialog.h"
22 #include "librarydialog.h"
24 #include "mainwindow.h"
25 #include "settingswindow.h"
26 #include "bookmarksdialog.h"
28 #include "chaptersdialog.h"
29 #include "fullscreenwindow.h"
31 #include "bookfinder.h"
34 #include "translucentbutton.h"
36 #ifdef DORIAN_TEST_MODEL
37 #include "modeltest.h"
41 # define ICON_PREFIX ":/icons/mac/"
43 # define ICON_PREFIX ":/icons/"
46 const int PROGRESS_HEIGHT = 17;
47 const char *DORIAN_VERSION =
48 #include "pkg/version.txt"
51 MainWindow::MainWindow(QWidget *parent):
52 AdopterWindow(parent), view(0), preventBlankingTimer(-1)
54 Trace t("MainWindow::MainWindow");
56 setAttribute(Qt::WA_Maemo5StackedWindow, true);
58 setWindowTitle("Dorian");
60 // Central widget. Must be an intermediate, because the book view widget
61 // can be re-parented later
62 QFrame *central = new QFrame(this);
63 QVBoxLayout *layout = new QVBoxLayout(central);
65 central->setLayout(layout);
66 setCentralWidget(central);
69 view = new BookView(central);
71 layout->addWidget(view);
74 progress = new Progress(central);
78 setUnifiedTitleAndToolBarOnMac(true);
79 settings = new QDialog(this);
80 toolBar = addToolBar("controls");
81 toolBar->setMovable(false);
82 toolBar->setFloatable(false);
83 toolBar->toggleViewAction()->setVisible(false);
84 #if defined(Q_WS_X11) && !defined(Q_WS_MAEMO_5)
85 toolBar->setIconSize(QSize(42, 42));
88 previousAction = addToolBarAction(view, SLOT(goPrevious()), "previous");
89 nextAction = addToolBarAction(view, SLOT(goNext()), "next");
90 chaptersAction = addToolBarAction(this, SLOT(showChapters()), "chapters");
91 bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()), "bookmarks");
94 infoAction = menuBar()->addAction(tr("Book details"));
95 connect(infoAction, SIGNAL(triggered()), this, SLOT(showInfo()));
96 libraryAction = menuBar()->addAction(tr("Library"));
97 connect(libraryAction, SIGNAL(triggered()), this, SLOT(showLibrary()));
98 settingsAction = menuBar()->addAction(tr("Settings"));
99 connect(settingsAction, SIGNAL(triggered()), this, SLOT(showSettings()));
100 devToolsAction = menuBar()->addAction(tr("Developer"));
101 connect(devToolsAction, SIGNAL(triggered()), this, SLOT(showDevTools()));
102 QAction *aboutAction = menuBar()->addAction(tr("About"));
103 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
105 infoAction = addToolBarAction(this, SLOT(showInfo()), "document-properties");
106 libraryAction = addToolBarAction(this, SLOT(showLibrary()),
107 "system-file-manager");
108 settingsAction = addToolBarAction(this, SLOT(showSettings()),
109 "preferences-system");
110 devToolsAction = addToolBarAction(this, SLOT(showDevTools()), "developer");
111 addToolBarAction(this, SLOT(about()), "about");
112 #endif // Q_WS_MAEMO_5
114 QFrame *frame = new QFrame(toolBar);
115 frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
116 toolBar->addWidget(frame);
118 fullScreenAction = addToolBarAction(this, SLOT(showBig()),
121 // Buttons on top of the book view
122 previousButton = new TranslucentButton("back", this);
123 nextButton = new TranslucentButton("forward", this);
125 // Handle model changes
126 connect(Library::instance(), SIGNAL(nowReadingChanged()),
127 this, SLOT(onCurrentBookChanged()));
129 // Load book on command line, or load last read book, or load default book
130 Library *library = Library::instance();
131 if (QCoreApplication::arguments().size() == 2) {
132 QString path = QCoreApplication::arguments()[1];
134 QModelIndex index = library->find(path);
135 if (index.isValid()) {
136 library->setNowReading(index);
140 QModelIndex index = library->nowReading();
141 if (index.isValid()) {
142 library->setNowReading(index);
145 if (!library->rowCount()) {
146 library->add(":/books/2 B R 0 2 B.epub");
148 library->setNowReading(library->index(0));
152 // Handle loading book parts
153 connect(view, SIGNAL(partLoadStart(int)), this, SLOT(onPartLoadStart()));
154 connect(view, SIGNAL(partLoadEnd(int)), this, SLOT(onPartLoadEnd(int)));
157 connect(view, SIGNAL(progress(qreal)), progress, SLOT(setProgress(qreal)));
159 // Shadow window for full screen reading
160 fullScreenWindow = new FullScreenWindow(this);
161 connect(fullScreenWindow, SIGNAL(restore()), this, SLOT(showRegular()));
163 // Handle settings changes
164 Settings *settings = Settings::instance();
165 connect(settings, SIGNAL(valueChanged(const QString &)),
166 this, SLOT(onSettingsChanged(const QString &)));
167 settings->setValue("orientation", settings->value("orientation"));
168 settings->setValue("lightson", settings->value("lightson"));
169 settings->setValue("usevolumekeys", settings->value("usevolumekeys"));
171 // Handle book view buttons
172 connect(nextButton, SIGNAL(triggered()), this, SLOT(goToNextPage()));
173 connect(previousButton, SIGNAL(triggered()), this, SLOT(goToPreviousPage()));
175 #ifdef DORIAN_TEST_MODEL
176 (void)new ModelTest(Library::instance(), this);
180 MainWindow::~MainWindow()
184 void MainWindow::onCurrentBookChanged()
186 setCurrentBook(Library::instance()->nowReading());
189 void MainWindow::showRegular()
191 Trace t("MainWindow::showRegular");
192 fullScreenWindow->hide();
193 fullScreenWindow->leaveChildren();
195 QList<QWidget *> otherChildren;
196 otherChildren << progress << previousButton << nextButton;
197 takeChildren(view, otherChildren);
198 QRect geo = geometry();
199 qDebug() << "Geometry" << geo << "toolbar" << toolBar->height();
200 progress->setGeometry(0, 0, geo.width(), PROGRESS_HEIGHT);
202 previousButton->setGeometry(0,
203 geo.height() - toolBar->height() - TranslucentButton::pixels,
204 TranslucentButton::pixels, TranslucentButton::pixels);
205 nextButton->setGeometry(geo.width() - TranslucentButton::pixels, 0,
206 TranslucentButton::pixels, TranslucentButton::pixels);
208 previousButton->setGeometry(0, geo.height() - TranslucentButton::pixels,
209 TranslucentButton::pixels, TranslucentButton::pixels);
210 nextButton->setGeometry(geo.width() - TranslucentButton::pixels,
211 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
212 #endif // Q_WS_MAEMO_5
213 qDebug() << "previousButton geometry" << previousButton->geometry();
216 previousButton->show();
217 nextButton->flash(1500);
218 previousButton->flash(1500);
221 void MainWindow::showBig()
223 Trace t("MainWindow::showBig");
225 QList<QWidget *> otherChildren;
226 otherChildren << progress << nextButton << previousButton;
227 QRect screen = QApplication::desktop()->screenGeometry();
228 progress->setGeometry(0, 0, screen.width(), PROGRESS_HEIGHT);
229 nextButton->setGeometry(screen.width() - TranslucentButton::pixels, 0,
230 TranslucentButton::pixels, TranslucentButton::pixels);
231 previousButton->setGeometry(0, screen.height() - TranslucentButton::pixels,
232 TranslucentButton::pixels, TranslucentButton::pixels);
234 fullScreenWindow->takeChildren(view, otherChildren);
235 fullScreenWindow->showFullScreen();
237 nextButton->flash(1500);
238 previousButton->flash(1500);
241 void MainWindow::setCurrentBook(const QModelIndex ¤t)
244 Book *book = Library::instance()->book(current);
246 setWindowTitle(book? book->shortName(): tr("Dorian"));
249 QAction *MainWindow::addToolBarAction(const QObject *receiver,
254 addAction(QIcon(ICON_PREFIX + name + ".png"), "", receiver, member);
257 void MainWindow::showLibrary()
259 (new LibraryDialog(this))->show();
262 void MainWindow::showSettings()
264 (new SettingsWindow(this))->show();
267 void MainWindow::showInfo()
269 if (mCurrent.isValid()) {
270 (new InfoDialog(Library::instance()->book(mCurrent), this))->exec();
274 void MainWindow::showDevTools()
276 (new DevTools())->exec();
279 void MainWindow::showBookmarks()
281 Book *book = Library::instance()->book(mCurrent);
283 BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
284 bookmarks->setWindowModality(Qt::WindowModal);
285 connect(bookmarks, SIGNAL(addBookmark()), this, SLOT(onAddBookmark()));
286 connect(bookmarks, SIGNAL(goToBookmark(int)),
287 this, SLOT(onGoToBookmark(int)));
292 void MainWindow::closeEvent(QCloseEvent *event)
294 Trace t("MainWindow::closeEvent");
295 view->setLastBookmark();
299 void MainWindow::onSettingsChanged(const QString &key)
302 if (key == "orientation") {
303 QString value = Settings::instance()->value(key).toString();
304 qDebug() << "MainWindow::onSettingsChanged: orientation" << value;
305 if (value == "portrait") {
306 setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
307 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
310 setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
311 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
313 } else if (key == "lightson") {
314 bool enable = Settings::instance()->value(key, false).toBool();
315 qDebug() << "MainWindow::onSettingsChanged: lightson:" << enable;
316 killTimer(preventBlankingTimer);
318 preventBlankingTimer = startTimer(29 * 1000);
320 } else if (key == "usevolumekeys") {
321 bool value = Settings::instance()->value(key).toBool();
322 qDebug() << "MainWindow::onSettingsChanged: usevolumekeys" << value;
324 fullScreenWindow->grabZoomKeys(value);
328 #endif // Q_WS_MAEMO_5
331 void MainWindow::onPartLoadStart()
333 Trace t("MainWindow::onPartLoadStart");
335 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
339 void MainWindow::onPartLoadEnd(int index)
341 Trace t("MainWindow::onPartLoadEnd");
342 bool enablePrevious = false;
343 bool enableNext = false;
344 Book *book = Library::instance()->book(mCurrent);
347 enablePrevious = true;
349 if (index < (book->parts.size() - 1)) {
354 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
355 previousAction->setIcon(QIcon(enablePrevious?
356 ":/icons/previous.png" : ":/icons/previous-disabled.png"));
357 nextAction->setIcon(QIcon(enableNext?
358 ":/icons/next.png": ":/icons/next-disabled.png"));
359 #endif // Q_WS_MAEMO_5
360 previousAction->setEnabled(enablePrevious);
361 nextAction->setEnabled(enableNext);
364 void MainWindow::onAddBookmark()
366 Trace t("MainWindow:onAddBookmark");
370 void MainWindow::onGoToBookmark(int index)
372 Trace t("MainWindow::onGoToBookmark");
373 Book *book = Library::instance()->book(mCurrent);
374 view->goToBookmark(book->bookmarks()[index]);
377 void MainWindow::showChapters()
379 Book *book = Library::instance()->book(mCurrent);
381 ChaptersDialog *chapters = new ChaptersDialog(book, this);
382 chapters->setWindowModality(Qt::WindowModal);
383 connect(chapters, SIGNAL(goToChapter(int)),
384 this, SLOT(onGoToChapter(int)));
389 void MainWindow::onGoToChapter(int index)
391 Trace t("MainWindow::onGoToChapter");
393 Book *book = Library::instance()->book(mCurrent);
395 int partIndex = book->partFromChapter(index);
396 if (partIndex != -1) {
397 view->goToBookmark(Book::Bookmark(partIndex, 0));
402 void MainWindow::timerEvent(QTimerEvent *event)
404 if (event->timerId() == preventBlankingTimer) {
406 QDBusInterface mce(MCE_SERVICE, MCE_REQUEST_PATH,
407 MCE_REQUEST_IF, QDBusConnection::systemBus());
408 mce.call(MCE_PREVENT_BLANK_REQ);
409 #endif // Q_WS_MAEMO_5
410 qDebug() << "MainWindow::timerEvent: Prevent display blanking";
414 void MainWindow::resizeEvent(QResizeEvent *e)
416 Trace t("MainWindow::resizeEvent");
417 progress->setGeometry(QRect(0, 0, e->size().width(), PROGRESS_HEIGHT));
418 qDebug() << "Toolbar height" << toolBar->height();
420 previousButton->setGeometry(0,
421 e->size().height() - toolBar->height() - TranslucentButton::pixels,
422 TranslucentButton::pixels, TranslucentButton::pixels);
423 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels, 0,
424 TranslucentButton::pixels, TranslucentButton::pixels);
426 previousButton->setGeometry(0, e->size().height() - TranslucentButton::pixels,
427 TranslucentButton::pixels, TranslucentButton::pixels);
428 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels,
429 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
430 #endif // Q_WS_MAEMO_5
431 qDebug() << "previousButton geometry" << previousButton->geometry();
432 previousButton->flash(1500);
433 nextButton->flash(1500);
434 QMainWindow::resizeEvent(e);
437 void MainWindow::about()
439 Dyalog *aboutDialog = new Dyalog(this);
440 aboutDialog->setWindowTitle(tr("About Dorian"));
441 QLabel *label = new QLabel(aboutDialog);
442 label->setTextFormat(Qt::RichText);
443 label->setOpenExternalLinks(true);
444 label->setText(tr("<b>Dorian %1</b><br><br>Copyright © 2010 by "
445 "Akos Polster <akos@pipacs.com><br>"
446 "Licensed under GNU General Public License, Version 3<br>"
447 "Source code: <a href='https://garage.maemo.org/projects/dorian/'>"
448 "garage.maemo.org/projects/dorian</a>").arg(DORIAN_VERSION));
449 aboutDialog->addWidget(label);
454 void MainWindow::goToNextPage()
456 nextButton->flash(1500);
457 previousButton->flash(1500);
461 void MainWindow::goToPreviousPage()
463 nextButton->flash(1500);
464 previousButton->flash(1500);
465 view->goPreviousPage();