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"
35 #ifdef DORIAN_TEST_MODEL
36 #include "modeltest.h"
40 # define ICON_PREFIX ":/icons/mac/"
42 # define ICON_PREFIX ":/icons/"
45 const int PROGRESS_HEIGHT = 17;
46 const char *DORIAN_VERSION =
47 #include "pkg/version.txt"
50 MainWindow::MainWindow(QWidget *parent):
51 BookWindow(parent), view(0), preventBlankingTimer(-1)
53 Trace t("MainWindow::MainWindow");
55 setAttribute(Qt::WA_Maemo5StackedWindow, true);
57 setWindowTitle("Dorian");
59 // Central widget. Must be an intermediate, because the book view widget
60 // can be re-parented later
61 QFrame *central = new QFrame(this);
62 QVBoxLayout *layout = new QVBoxLayout(central);
64 central->setLayout(layout);
65 setCentralWidget(central);
68 view = new BookView(central);
70 layout->addWidget(view);
73 progress = new Progress(central);
76 setUnifiedTitleAndToolBarOnMac(true);
77 settings = new QDialog(this);
78 toolBar = addToolBar("controls");
79 toolBar->setMovable(false);
80 toolBar->setFloatable(false);
81 toolBar->toggleViewAction()->setVisible(false);
82 #if defined(Q_WS_X11) && !defined(Q_WS_MAEMO_5)
83 toolBar->setIconSize(QSize(42, 42));
86 previousAction = addToolBarAction(view, SLOT(goPrevious()), "previous");
87 nextAction = addToolBarAction(view, SLOT(goNext()), "next");
88 chaptersAction = addToolBarAction(this, SLOT(showChapters()), "chapters");
89 bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()), "bookmarks");
92 infoAction = menuBar()->addAction(tr("Book details"));
93 connect(infoAction, SIGNAL(triggered()), this, SLOT(showInfo()));
94 libraryAction = menuBar()->addAction(tr("Library"));
95 connect(libraryAction, SIGNAL(triggered()), this, SLOT(showLibrary()));
96 settingsAction = menuBar()->addAction(tr("Settings"));
97 connect(settingsAction, SIGNAL(triggered()), this, SLOT(showSettings()));
98 devToolsAction = menuBar()->addAction(tr("Developer"));
99 connect(devToolsAction, SIGNAL(triggered()), this, SLOT(showDevTools()));
100 QAction *aboutAction = menuBar()->addAction(tr("About"));
101 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
103 infoAction = addToolBarAction(this, SLOT(showInfo()), "document-properties");
104 libraryAction = addToolBarAction(this, SLOT(showLibrary()),
105 "system-file-manager");
106 settingsAction = addToolBarAction(this, SLOT(showSettings()),
107 "preferences-system");
108 devToolsAction = addToolBarAction(this, SLOT(showDevTools()), "developer");
109 addToolBarAction(this, SLOT(about()), "about");
110 #endif // Q_WS_MAEMO_5
112 QFrame *frame = new QFrame(toolBar);
113 frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
114 toolBar->addWidget(frame);
116 fullScreenAction = addToolBarAction(this, SLOT(showBig()), "view-fullscreen");
118 // Handle model changes
119 connect(Library::instance(), SIGNAL(nowReadingChanged()),
120 this, SLOT(onCurrentBookChanged()));
122 // Load book on command line, or load last read book, or load default book
123 Library *library = Library::instance();
124 if (QCoreApplication::arguments().size() == 2) {
125 QString path = QCoreApplication::arguments()[1];
127 QModelIndex index = library->find(path);
128 if (index.isValid()) {
129 library->setNowReading(index);
133 QModelIndex index = library->nowReading();
134 if (index.isValid()) {
135 library->setNowReading(index);
138 if (!library->rowCount()) {
139 library->add(":/books/2 B R 0 2 B.epub");
141 library->setNowReading(library->index(0));
145 // Handle loading book parts
146 connect(view, SIGNAL(partLoadStart(int)), this, SLOT(onPartLoadStart()));
147 connect(view, SIGNAL(partLoadEnd(int)), this, SLOT(onPartLoadEnd(int)));
150 connect(view, SIGNAL(progress(qreal)), progress, SLOT(setProgress(qreal)));
152 // Shadow window for full screen
153 fullScreenWindow = new FullScreenWindow(this);
154 connect(fullScreenWindow, SIGNAL(restore()), this, SLOT(showRegular()));
156 // Create thread for finding books in directories
157 bookFinder = new BookFinder();
158 connect(bookFinder, SIGNAL(add(const QString &)),
159 library, SLOT(add(const QString &)));
160 connect(bookFinder, SIGNAL(remove(const QString &)),
161 library, SLOT(remove(const QString &)));
162 bookFinder->moveToThread(&bookFinderThread);
163 bookFinderThread.start();
165 // Handle settings changes
166 Settings *settings = Settings::instance();
167 connect(settings, SIGNAL(valueChanged(const QString &)),
168 this, SLOT(onSettingsChanged(const QString &)));
169 settings->setValue("orientation", settings->value("orientation"));
170 settings->setValue("lightson", settings->value("lightson"));
171 settings->setValue("usevolumekeys", settings->value("usevolumekeys"));
173 #ifdef DORIAN_TEST_MODEL
174 (void)new ModelTest(Library::instance(), this);
178 MainWindow::~MainWindow()
180 bookFinderThread.quit();
181 bookFinderThread.wait();
185 void MainWindow::onCurrentBookChanged()
187 setCurrentBook(Library::instance()->nowReading());
190 void MainWindow::showRegular()
192 Trace t("MainWindow::showRegular");
193 fullScreenWindow->hide();
194 fullScreenWindow->leaveChildren();
195 progress->setGeometry(0, 0, geometry().width(), PROGRESS_HEIGHT);
196 QList<QWidget *> otherChildren;
197 otherChildren.append(progress);
198 takeChildren(view, otherChildren);
202 void MainWindow::showBig()
204 Trace t("MainWindow::showBig");
206 QList<QWidget *> otherChildren;
207 otherChildren.append(progress);
208 progress->setGeometry(0, 0, QApplication::desktop()->screenGeometry().width(),
210 fullScreenWindow->takeChildren(view, otherChildren);
211 fullScreenWindow->showFullScreen();
215 void MainWindow::setCurrentBook(const QModelIndex ¤t)
218 Book *book = Library::instance()->book(current);
220 setWindowTitle(book? book->shortName(): tr("Dorian"));
223 QAction *MainWindow::addToolBarAction(const QObject *receiver,
228 addAction(QIcon(ICON_PREFIX + name + ".png"), "", receiver, member);
231 void MainWindow::showLibrary()
233 (new LibraryDialog(this))->show();
236 void MainWindow::showSettings()
238 (new SettingsWindow(this))->show();
241 void MainWindow::showInfo()
243 if (mCurrent.isValid()) {
244 (new InfoDialog(Library::instance()->book(mCurrent), this))->exec();
248 void MainWindow::showDevTools()
250 (new DevTools())->exec();
253 void MainWindow::showBookmarks()
255 Book *book = Library::instance()->book(mCurrent);
257 BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
258 bookmarks->setWindowModality(Qt::WindowModal);
259 connect(bookmarks, SIGNAL(addBookmark()), this, SLOT(onAddBookmark()));
260 connect(bookmarks, SIGNAL(goToBookmark(int)),
261 this, SLOT(onGoToBookmark(int)));
266 void MainWindow::closeEvent(QCloseEvent *event)
268 Trace t("MainWindow::closeEvent");
269 view->setLastBookmark();
273 void MainWindow::onSettingsChanged(const QString &key)
276 if (key == "orientation") {
277 QString value = Settings::instance()->value(key).toString();
278 Trace::trace(QString("MainWindow::onSettingsChanged: orientation %1").
280 if (value == "portrait") {
281 setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
282 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
285 setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
286 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
288 } else if (key == "lightson") {
289 bool enable = Settings::instance()->value(key, false).toBool();
290 Trace::trace(QString("MainWindow::onSettingsChanged: lightson: %1").
292 killTimer(preventBlankingTimer);
294 preventBlankingTimer = startTimer(29 * 1000);
296 } else if (key == "usevolumekeys") {
297 bool value = Settings::instance()->value(key).toBool();
298 Trace::trace(QString("MainWindow::onSettingsChanged: usevolumekeys %1").
301 fullScreenWindow->grabZoomKeys(value);
305 #endif // Q_WS_MAEMO_5
308 void MainWindow::onPartLoadStart()
310 Trace t("MainWindow::onPartLoadStart");
312 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
316 void MainWindow::onPartLoadEnd(int index)
318 Trace t("MainWindow::onPartLoadEnd");
319 bool enablePrevious = false;
320 bool enableNext = false;
321 Book *book = Library::instance()->book(mCurrent);
324 enablePrevious = true;
326 if (index < (book->parts.size() - 1)) {
331 setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
332 previousAction->setIcon(QIcon(enablePrevious?
333 ":/icons/previous.png" : ":/icons/previous-disabled.png"));
334 nextAction->setIcon(QIcon(enableNext?
335 ":/icons/next.png": ":/icons/next-disabled.png"));
336 #endif // Q_WS_MAEMO_5
337 previousAction->setEnabled(enablePrevious);
338 nextAction->setEnabled(enableNext);
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 Trace::trace("MainWindow::timerEvent: Prevent display blanking");
391 void MainWindow::resizeEvent(QResizeEvent *e)
393 progress->setGeometry(QRect(0, 0, e->size().width(), PROGRESS_HEIGHT));
394 QMainWindow::resizeEvent(e);
397 void MainWindow::about()
399 Dyalog *aboutDialog = new Dyalog(this);
400 aboutDialog->setWindowTitle(tr("About Dorian"));
401 QLabel *label = new QLabel(aboutDialog);
402 label->setTextFormat(Qt::RichText);
403 label->setOpenExternalLinks(true);
404 label->setText(tr("<b>Dorian %1</b><br><br>Copyright © 2010 by "
405 "Akos Polster <akos@pipacs.com><br>"
406 "Licensed under GNU General Public License, Version 3<br>"
407 "Source code: <a href='https://garage.maemo.org/projects/dorian/'>"
408 "garage.maemo.org/projects/dorian</a>").arg(DORIAN_VERSION));
409 aboutDialog->addWidget(label);