Make full screen truly full screen.
[dorian] / mainwindow.cpp
1 #include <QtGui>
2 #include <QtDebug>
3 #include <QDir>
4 #include <QCoreApplication>
5 #include <QFileInfo>
6 #ifdef Q_WS_MAEMO_5
7 #   include <QtMaemo5/QMaemo5InformationBox>
8 #endif
9
10 #include "bookview.h"
11 #include "book.h"
12 #include "library.h"
13 #include "infodialog.h"
14 #include "librarydialog.h"
15 #include "devtools.h"
16 #include "mainwindow.h"
17 #include "settingswindow.h"
18 #include "bookmarksdialog.h"
19 #include "settings.h"
20 #include "chaptersdialog.h"
21 #include "fullscreenwindow.h"
22
23 #ifdef DORIAN_TEST_MODEL
24 #include "modeltest.h"
25 #endif
26
27 #ifdef Q_WS_MAC
28 #   define ICON_PREFIX ":/icons/mac/"
29 #else
30 #   define ICON_PREFIX ":/icons/"
31 #endif
32
33 const Qt::WindowFlags WIN_BIG_FLAGS =
34         Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint;
35 const int WIN_BIG_TIMER = 3000;
36
37 MainWindow::MainWindow(QWidget *parent):
38         QMainWindow(parent), view(0), fullScreenWindow(0)
39 {
40 #ifdef Q_WS_MAEMO_5
41     setAttribute(Qt::WA_Maemo5StackedWindow, true);
42 #endif
43     setWindowTitle("Dorian");
44
45     // Book view
46     view = new BookView(this);
47     setCentralWidget(view);
48
49     // Tool bar
50     setUnifiedTitleAndToolBarOnMac(true);
51     settings = new QDialog(this);
52     toolBar = addToolBar("controls");
53     toolBar->setMovable(false);
54     toolBar->setFloatable(false);
55     toolBar->toggleViewAction()->setVisible(false);
56 #if defined(Q_WS_X11) && !defined(Q_WS_MAEMO_5)
57     toolBar->setIconSize(QSize(42, 42));
58 #endif
59
60     previousAction = addToolBarAction(view, SLOT(goPrevious()), "previous");
61     nextAction = addToolBarAction(view, SLOT(goNext()), "next");
62     chaptersAction = addToolBarAction(this, SLOT(showChapters()), "chapters");
63     bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()), "bookmarks");
64
65 #ifdef Q_WS_MAEMO_5
66     infoAction = menuBar()->addAction(tr("Book details"));
67     connect(infoAction, SIGNAL(triggered()), this, SLOT(showInfo()));
68     libraryAction = menuBar()->addAction(tr("Library"));
69     connect(libraryAction, SIGNAL(triggered()), this, SLOT(showLibrary()));
70     settingsAction = menuBar()->addAction(tr("Settings"));
71     connect(settingsAction, SIGNAL(triggered()), this, SLOT(showSettings()));
72     devToolsAction = menuBar()->addAction(tr("Developer"));
73     connect(devToolsAction, SIGNAL(triggered()), this, SLOT(showDevTools()));
74 #else
75     infoAction = addToolBarAction(this, SLOT(showInfo()), "document-properties");
76     libraryAction = addToolBarAction(this, SLOT(showLibrary()),
77                                      "system-file-manager");
78     settingsAction = addToolBarAction(this, SLOT(showSettings()),
79                                       "preferences-system");
80     devToolsAction = addToolBarAction(this, SLOT(showDevTools()), "developer");
81 #endif // Q_WS_MAEMO_5
82
83     QFrame *frame = new QFrame(toolBar);
84     frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
85     toolBar->addWidget(frame);
86
87     fullScreenAction = addToolBarAction(this, SLOT(showFullScreen()),
88                                         "view-fullscreen");
89
90     // Handle model changes
91     connect(Library::instance(), SIGNAL(nowReadingChanged()),
92             this, SLOT(onCurrentBookChanged()));
93
94     // Load book on command line, or load last read book, or load default book
95     Library *library = Library::instance();
96     if (QCoreApplication::arguments().size() == 2) {
97         QString path = QCoreApplication::arguments()[1];
98         library->add(path);
99         QModelIndex index = library->find(path);
100         if (index.isValid()) {
101             library->setNowReading(index);
102         }
103     }
104     else {
105         QModelIndex index = library->nowReading();
106         if (index.isValid()) {
107             library->setNowReading(index);
108         }
109         else {
110             if (!library->rowCount()) {
111                 library->add(":/books/2 B R 0 2 B.epub");
112             }
113             library->setNowReading(library->index(0));
114         }
115     }
116
117     // Handle settings changes
118     connect(Settings::instance(), SIGNAL(valueChanged(const QString &)),
119             this, SLOT(onSettingsChanged(const QString &)));
120     Settings::instance()->setValue("orientation",
121                                    Settings::instance()->value("orientation"));
122
123     // Handle loading chapters
124     connect(view, SIGNAL(chapterLoadStart(int)),
125             this, SLOT(onChapterLoadStart()));
126     connect(view, SIGNAL(chapterLoadEnd(int)),
127             this, SLOT(onChapterLoadEnd(int)));
128
129 #ifdef DORIAN_TEST_MODEL
130     (void)new ModelTest(Library::instance(), this);
131 #endif
132 }
133
134 void MainWindow::onCurrentBookChanged()
135 {
136     setCurrentBook(Library::instance()->nowReading());
137 }
138
139 void MainWindow::showNormal()
140 {
141     qDebug() << "MainWindow::showNormal";
142     view->setParent(this);
143     setCentralWidget(view);
144     show();
145     delete fullScreenWindow;
146     fullScreenWindow = 0;
147 }
148
149 void MainWindow::showFullScreen()
150 {
151     qDebug() << "MainWindow::showFullscreen";
152     fullScreenWindow = new FullScreenWindow(view, this);
153     fullScreenWindow->showFullScreen();
154     connect(fullScreenWindow, SIGNAL(restore()), this, SLOT(showNormal()));
155 }
156
157 void MainWindow::setCurrentBook(const QModelIndex &current)
158 {
159     mCurrent = current;
160     Book *book = Library::instance()->book(current);
161     view->setBook(book);
162     setWindowTitle(book? book->name(): tr("Dorian"));
163 }
164
165 QAction *MainWindow::addToolBarAction(const QObject *receiver,
166                                       const char *member,
167                                       const QString &name)
168 {
169     return toolBar->
170         addAction(QIcon(ICON_PREFIX + name + ".png"), "", receiver, member);
171 }
172
173 void MainWindow::showLibrary()
174 {
175     LibraryDialog *dialog = new LibraryDialog(this);
176     dialog->show();
177 }
178
179 void MainWindow::showSettings()
180 {
181     SettingsWindow *settings = new SettingsWindow(this);
182     settings->show();
183 }
184
185 void MainWindow::showInfo()
186 {
187     if (mCurrent.isValid()) {
188         InfoDialog *info =
189             new InfoDialog(Library::instance()->book(mCurrent), this);
190         info->exec();
191     }
192 }
193
194 void MainWindow::showDevTools()
195 {
196     DevTools *devTools = new DevTools();
197     devTools->exec();
198 }
199
200 void MainWindow::showBookmarks()
201 {
202     Book *book = Library::instance()->book(mCurrent);
203     if (book) {
204         BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
205         bookmarks->setWindowModality(Qt::WindowModal);
206         connect(bookmarks, SIGNAL(addBookmark()), this, SLOT(onAddBookmark()));
207         connect(bookmarks, SIGNAL(goToBookmark(int)),
208                 this, SLOT(onGoToBookmark(int)));
209         bookmarks->show();
210     }
211 }
212
213 void MainWindow::closeEvent(QCloseEvent *event)
214 {
215     qDebug() << "MainWindow::closeEvent";
216     view->setLastBookmark();
217     event->accept();
218 }
219
220 void MainWindow::onSettingsChanged(const QString &key)
221 {
222 #ifdef Q_WS_MAEMO_5
223     if (key == "orientation") {
224         QString value = Settings::instance()->value(key).toString();
225         if (value == "portrait") {
226             setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
227             setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
228         }
229         else {
230             setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
231             setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
232         }
233     }
234 #else
235     Q_UNUSED(key);
236 #endif // Q_WS_MAEMO_5
237 }
238
239 void MainWindow::onChapterLoadStart()
240 {
241 #ifdef Q_WS_MAEMO_5
242     setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
243 #endif
244 }
245
246 void MainWindow::onChapterLoadEnd(int index)
247 {
248     bool enablePrevious = false;
249     bool enableNext = false;
250     Book *book = Library::instance()->book(mCurrent);
251     if (book) {
252         if (index > 0) {
253             enablePrevious = true;
254         }
255         if (index < (book->toc.size() - 1)) {
256             enableNext = true;
257         }
258     }
259 #ifdef Q_WS_MAEMO_5
260     setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
261     previousAction->setIcon(QIcon(enablePrevious?
262         ":/icons/previous.png" : ":/icons/previous-disabled.png"));
263     nextAction->setIcon(QIcon(enableNext?
264         ":/icons/next.png": ":/icons/next-disabled.png"));
265 #endif // Q_WS_MAEMO_5
266     previousAction->setEnabled(enablePrevious);
267     nextAction->setEnabled(enableNext);
268 }
269
270 void MainWindow::onAddBookmark()
271 {
272     view->addBookmark();
273 }
274
275 void MainWindow::onGoToBookmark(int index)
276 {
277     Book *book = Library::instance()->book(mCurrent);
278     view->goToBookmark(book->bookmarks()[index]);
279 }
280
281 void MainWindow::showChapters()
282 {
283     Book *book = Library::instance()->book(mCurrent);
284     if (book) {
285         ChaptersDialog *chapters = new ChaptersDialog(book, this);
286         chapters->setWindowModality(Qt::WindowModal);
287         connect(chapters, SIGNAL(goToChapter(int)),
288                 this, SLOT(onGoToChapter(int)));
289         chapters->show();
290     }
291 }
292
293 void MainWindow::onGoToChapter(int index)
294 {
295     view->goToBookmark(Book::Bookmark(index, 0));
296 }
297