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 static 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);
77 settings = new QDialog(this);
81 chaptersAction = addToolBarAction(this, SLOT(showChapters()),
82 "chapters", tr("Chapters"));
83 bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()),
84 "bookmarks", tr("Bookmarks"));
85 infoAction = addToolBarAction(this, SLOT(showInfo()),
86 "info", tr("Book info"));
87 libraryAction = addToolBarAction(this, SLOT(showLibrary()),
88 "library", tr("Library"));
91 settingsAction = menuBar()->addAction(tr("Settings"));
92 connect(settingsAction, SIGNAL(triggered()), this, SLOT(showSettings()));
93 devToolsAction = menuBar()->addAction(tr("Developer"));
94 connect(devToolsAction, SIGNAL(triggered()), this, SLOT(showDevTools()));
95 QAction *aboutAction = menuBar()->addAction(tr("About"));
96 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
98 settingsAction = addToolBarAction(this, SLOT(showSettings()),
99 "preferences-system", tr("Settings"));
100 devToolsAction = addToolBarAction(this, SLOT(showDevTools()),
101 "developer", tr("Developer"));
102 addToolBarAction(this, SLOT(about()), "about", tr("About"));
103 #endif // Q_WS_MAEMO_5
105 QFrame *frame = new QFrame(toolBar);
106 frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
107 toolBar->addWidget(frame);
109 fullScreenAction = addToolBarAction(this, SLOT(showBig()),
110 "view-fullscreen", tr("Full screen"));
112 // Buttons on top of the book view
113 previousButton = new TranslucentButton("back", this);
114 nextButton = new TranslucentButton("forward", this);
116 // Handle model changes
117 connect(Library::instance(), SIGNAL(nowReadingChanged()),
118 this, SLOT(onCurrentBookChanged()));
120 // Load book on command line, or load last read book, or load default book
121 Library *library = Library::instance();
122 if (QCoreApplication::arguments().size() == 2) {
123 QString path = QCoreApplication::arguments()[1];
125 QModelIndex index = library->find(path);
126 if (index.isValid()) {
127 library->setNowReading(index);
131 QModelIndex index = library->nowReading();
132 if (index.isValid()) {
133 library->setNowReading(index);
136 if (!library->rowCount()) {
137 library->add(":/books/2 B R 0 2 B.epub");
139 library->setNowReading(library->index(0));
143 // Handle loading book parts
144 connect(view, SIGNAL(partLoadStart(int)), this, SLOT(onPartLoadStart()));
145 connect(view, SIGNAL(partLoadEnd(int)), this, SLOT(onPartLoadEnd(int)));
148 connect(view, SIGNAL(progress(qreal)), progress, SLOT(setProgress(qreal)));
150 // Shadow window for full screen reading
151 fullScreenWindow = new FullScreenWindow(this);
152 connect(fullScreenWindow, SIGNAL(restore()), this, SLOT(showRegular()));
154 // Handle settings changes
155 Settings *settings = Settings::instance();
156 connect(settings, SIGNAL(valueChanged(const QString &)),
157 this, SLOT(onSettingsChanged(const QString &)));
158 settings->setValue("orientation", settings->value("orientation"));
159 settings->setValue("lightson", settings->value("lightson"));
160 settings->setValue("usevolumekeys", settings->value("usevolumekeys"));
162 // Handle book view buttons
163 connect(nextButton, SIGNAL(triggered()), this, SLOT(goToNextPage()));
164 connect(previousButton, SIGNAL(triggered()), this, SLOT(goToPreviousPage()));
166 #ifdef DORIAN_TEST_MODEL
167 (void)new ModelTest(Library::instance(), this);
171 MainWindow::~MainWindow()
175 void MainWindow::onCurrentBookChanged()
177 setCurrentBook(Library::instance()->nowReading());
180 void MainWindow::showRegular()
182 Trace t("MainWindow::showRegular");
183 fullScreenWindow->hide();
184 fullScreenWindow->leaveChildren();
186 QList<QWidget *> otherChildren;
187 otherChildren << progress << previousButton << nextButton;
188 takeChildren(view, otherChildren);
189 QRect geo = geometry();
190 qDebug() << "Geometry" << geo << "toolbar" << toolBar->height();
191 progress->setGeometry(0, 0, geo.width(), PROGRESS_HEIGHT);
193 previousButton->setGeometry(0,
194 geo.height() - toolBar->height() - TranslucentButton::pixels,
195 TranslucentButton::pixels, TranslucentButton::pixels);
196 nextButton->setGeometry(geo.width() - TranslucentButton::pixels, 0,
197 TranslucentButton::pixels, TranslucentButton::pixels);
199 previousButton->setGeometry(0, geo.height() - TranslucentButton::pixels,
200 TranslucentButton::pixels, TranslucentButton::pixels);
201 nextButton->setGeometry(geo.width() - TranslucentButton::pixels,
202 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
203 #endif // Q_WS_MAEMO_5
204 qDebug() << "previousButton geometry" << previousButton->geometry();
207 previousButton->show();
208 nextButton->flash(1500);
209 previousButton->flash(1500);
212 void MainWindow::showBig()
214 Trace t("MainWindow::showBig");
216 QList<QWidget *> otherChildren;
217 otherChildren << progress << nextButton << previousButton;
218 QRect screen = QApplication::desktop()->screenGeometry();
219 progress->setGeometry(0, 0, screen.width(), PROGRESS_HEIGHT);
220 nextButton->setGeometry(screen.width() - TranslucentButton::pixels, 0,
221 TranslucentButton::pixels, TranslucentButton::pixels);
222 previousButton->setGeometry(0, screen.height() - TranslucentButton::pixels,
223 TranslucentButton::pixels, TranslucentButton::pixels);
225 fullScreenWindow->takeChildren(view, otherChildren);
226 fullScreenWindow->showFullScreen();
228 nextButton->flash(1500);
229 previousButton->flash(1500);
232 void MainWindow::setCurrentBook(const QModelIndex ¤t)
235 Book *book = Library::instance()->book(current);
237 setWindowTitle(book? book->shortName(): tr("Dorian"));
240 void MainWindow::showLibrary()
242 (new LibraryDialog(this))->show();
245 void MainWindow::showSettings()
247 (new SettingsWindow(this))->show();
250 void MainWindow::showInfo()
252 if (mCurrent.isValid()) {
253 (new InfoDialog(Library::instance()->book(mCurrent), this, false))->exec();
257 void MainWindow::showDevTools()
259 (new DevTools())->exec();
262 void MainWindow::showBookmarks()
264 Book *book = Library::instance()->book(mCurrent);
266 BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
267 bookmarks->setWindowModality(Qt::WindowModal);
268 connect(bookmarks, SIGNAL(addBookmark()), this, SLOT(onAddBookmark()));
269 connect(bookmarks, SIGNAL(goToBookmark(int)),
270 this, SLOT(onGoToBookmark(int)));
275 void MainWindow::closeEvent(QCloseEvent *event)
277 Trace t("MainWindow::closeEvent");
278 view->setLastBookmark();
282 void MainWindow::onSettingsChanged(const QString &key)
285 if (key == "orientation") {
286 QString value = Settings::instance()->value(key).toString();
287 qDebug() << "MainWindow::onSettingsChanged: orientation" << value;
288 if (value == "portrait") {
289 setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
290 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
293 setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
294 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
296 } else if (key == "lightson") {
297 bool enable = Settings::instance()->value(key, false).toBool();
298 qDebug() << "MainWindow::onSettingsChanged: lightson:" << enable;
299 killTimer(preventBlankingTimer);
301 preventBlankingTimer = startTimer(29 * 1000);
303 } else if (key == "usevolumekeys") {
304 bool value = Settings::instance()->value(key).toBool();
305 qDebug() << "MainWindow::onSettingsChanged: usevolumekeys" << value;
307 fullScreenWindow->grabZoomKeys(value);
311 #endif // Q_WS_MAEMO_5
314 void MainWindow::onPartLoadStart()
316 Trace t("MainWindow::onPartLoadStart");
318 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
322 void MainWindow::onPartLoadEnd(int index)
324 Trace t("MainWindow::onPartLoadEnd");
325 bool enablePrevious = false;
326 bool enableNext = false;
327 Book *book = Library::instance()->book(mCurrent);
330 enablePrevious = true;
332 if (index < (book->parts.size() - 1)) {
337 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
338 #endif // Q_WS_MAEMO_5
341 void MainWindow::onAddBookmark()
343 Trace t("MainWindow:onAddBookmark");
347 void MainWindow::onGoToBookmark(int index)
349 Trace t("MainWindow::onGoToBookmark");
350 Book *book = Library::instance()->book(mCurrent);
351 view->goToBookmark(book->bookmarks()[index]);
354 void MainWindow::showChapters()
356 Book *book = Library::instance()->book(mCurrent);
358 ChaptersDialog *chapters = new ChaptersDialog(book, this);
359 chapters->setWindowModality(Qt::WindowModal);
360 connect(chapters, SIGNAL(goToChapter(int)),
361 this, SLOT(onGoToChapter(int)));
366 void MainWindow::onGoToChapter(int index)
368 Trace t("MainWindow::onGoToChapter");
370 Book *book = Library::instance()->book(mCurrent);
372 int partIndex = book->partFromChapter(index);
373 if (partIndex != -1) {
374 view->goToBookmark(Book::Bookmark(partIndex, 0));
379 void MainWindow::timerEvent(QTimerEvent *event)
381 if (event->timerId() == preventBlankingTimer) {
383 QDBusInterface mce(MCE_SERVICE, MCE_REQUEST_PATH,
384 MCE_REQUEST_IF, QDBusConnection::systemBus());
385 mce.call(MCE_PREVENT_BLANK_REQ);
386 #endif // Q_WS_MAEMO_5
387 qDebug() << "MainWindow::timerEvent: Prevent display blanking";
391 void MainWindow::resizeEvent(QResizeEvent *e)
393 Trace t("MainWindow::resizeEvent");
394 progress->setGeometry(QRect(0, 0, e->size().width(), PROGRESS_HEIGHT));
395 qDebug() << "Toolbar height" << toolBar->height();
397 previousButton->setGeometry(0,
398 e->size().height() - toolBar->height() - TranslucentButton::pixels,
399 TranslucentButton::pixels, TranslucentButton::pixels);
400 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels, 0,
401 TranslucentButton::pixels, TranslucentButton::pixels);
403 previousButton->setGeometry(0, e->size().height() - TranslucentButton::pixels,
404 TranslucentButton::pixels, TranslucentButton::pixels);
405 nextButton->setGeometry(e->size().width() - TranslucentButton::pixels,
406 toolBar->height(), TranslucentButton::pixels, TranslucentButton::pixels);
407 #endif // Q_WS_MAEMO_5
408 qDebug() << "previousButton geometry" << previousButton->geometry();
409 previousButton->flash(1500);
410 nextButton->flash(1500);
411 QMainWindow::resizeEvent(e);
414 void MainWindow::about()
416 Dyalog *aboutDialog = new Dyalog(this);
417 aboutDialog->setWindowTitle(tr("About Dorian"));
418 QLabel *label = new QLabel(aboutDialog);
419 label->setTextFormat(Qt::RichText);
420 label->setOpenExternalLinks(true);
421 label->setText(tr("<b>Dorian %1</b><br><br>Copyright © 2010 by "
422 "Akos Polster <akos@pipacs.com><br>"
423 "Licensed under GNU General Public License, Version 3<br>"
424 "Source code: <a href='https://garage.maemo.org/projects/dorian/'>"
425 "garage.maemo.org/projects/dorian</a>").arg(DORIAN_VERSION));
426 aboutDialog->addWidget(label);
431 void MainWindow::goToNextPage()
433 nextButton->flash(1500);
434 previousButton->flash(1500);
438 void MainWindow::goToPreviousPage()
440 nextButton->flash(1500);
441 previousButton->flash(1500);
442 view->goPreviousPage();