More modelification.
[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 "translucentbutton.h"
18 #include "settingswindow.h"
19 #include "bookmarksdialog.h"
20 #include "settings.h"
21
22 #ifdef Q_WS_MAC
23 #   define ICON_PREFIX ":/icons/mac/"
24 #else
25 #   define ICON_PREFIX ":/icons/"
26 #endif
27
28 const Qt::WindowFlags WIN_BIG_FLAGS =
29         Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint;
30 const int WIN_BIG_TIMER = 3000;
31
32 MainWindow::MainWindow(QWidget *parent):
33         QMainWindow(parent), view(0), book(0), isFullscreen(false)
34 {
35 #ifdef Q_WS_MAEMO_5
36     setAttribute(Qt::WA_Maemo5StackedWindow, true);
37 #endif
38     setWindowTitle("Dorian");
39
40     // Book view
41     view = new BookView(this);
42     setCentralWidget(view);
43
44     // Tool bar
45     setUnifiedTitleAndToolBarOnMac(true);
46     settings = new QDialog(this);
47     toolBar = addToolBar("controls");
48     toolBar->setMovable(false);
49     toolBar->setFloatable(false);
50     toolBar->toggleViewAction()->setVisible(false);
51 #if defined(Q_WS_X11) && !defined(Q_WS_MAEMO_5)
52     toolBar->setIconSize(QSize(42, 42));
53 #endif
54     previousAction = addToolBarAction(view, SLOT(goPrevious()), "previous");
55     nextAction = addToolBarAction(view, SLOT(goNext()), "next");
56     bookmarksAction = addToolBarAction(this, SLOT(showBookmarks()),
57                                        "bookmarks");
58 #ifdef Q_WS_MAEMO_5
59     infoAction = new QAction(this);
60 #else
61     infoAction = addToolBarAction(this, SLOT(showInfo()), "document-properties");
62 #endif
63     libraryAction = addToolBarAction(this, SLOT(showLibrary()),
64                                      "system-file-manager");
65     settingsAction = addToolBarAction(this, SLOT(showSettings()),
66                                       "preferences-system");
67 #ifdef Q_WS_MAEMO_5
68     devToolsAction = new QAction(this);
69 #else
70     devToolsAction = addToolBarAction(this, SLOT(showDevTools()), "developer");
71     QFrame *frame = new QFrame(toolBar);
72     frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
73     toolBar->addWidget(frame);
74 #endif
75     fullScreenAction = addToolBarAction(this, SLOT(showFullScreen()),
76                                         "view-fullscreen");
77
78     // Handle model changes
79     connect(Library::instance(), SIGNAL(currentBookChanged()),
80             this, SLOT(onCurrentBookChanged()));
81
82     normalFlags = windowFlags();
83     restoreButton = new TranslucentButton("view-fullscreen", this);
84
85     // Load book on command line, or load last read book, or load default book
86     Library *library = Library::instance();
87     if (QCoreApplication::arguments().size() == 2) {
88         QString path = QCoreApplication::arguments()[1];
89         library->add(path);
90         QModelIndex index = library->find(path);
91         if (index.isValid()) {
92             library->setCurrent(index);
93         }
94     }
95     else {
96         Book *current = library->current();
97         if (current) {
98             setCurrentBook(current);
99         }
100         else {
101             if (!library->rowCount()) {
102                 library->add(":/books/2 B R 0 2 B.epub");
103             }
104             library->setCurrent(library->index(0));
105         }
106     }
107
108     // Handle settings changes
109     connect(Settings::instance(), SIGNAL(valueChanged(const QString &)),
110             this, SLOT(onSettingsChanged(const QString &)));
111     Settings::instance()->setValue("orientation",
112                                    Settings::instance()->value("orientation"));
113
114     // Handle loading chapters
115     connect(view, SIGNAL(chapterLoaded(int)), this, SLOT(onChapterLoaded(int)));
116 }
117
118 void MainWindow::onCurrentBookChanged()
119 {
120     setCurrentBook(Library::instance()->current());
121 }
122
123 void MainWindow::showNormal()
124 {
125     qDebug() << "MainWindow::showNormal";
126     isFullscreen = false;
127     setWindowFlags(normalFlags);
128     hide();
129     setGeometry(normalGeometry);
130     toolBar->show();
131     restoreButton->hide();
132     show();
133 }
134
135 void MainWindow::showFullScreen()
136 {
137     qDebug() << "MainWindow::showFullscreen";
138     normalGeometry = geometry();
139     isFullscreen = true;
140     toolBar->hide();
141     setWindowFlags(normalFlags | WIN_BIG_FLAGS);
142     showMaximized();
143     restoreButton->flash();
144 }
145
146 void MainWindow::setCurrentBook(Book *current)
147 {
148     book = current;
149     view->setBook(current);
150     setWindowTitle(current? current->title: "Dorian");
151 }
152
153 QAction *MainWindow::addToolBarAction(const QObject *receiver, const char *member,
154                                       const QString &name)
155 {
156     return toolBar->
157         addAction(QIcon(ICON_PREFIX + name + ".png"), "", receiver, member);
158 }
159
160 void MainWindow::showLibrary()
161 {
162     LibraryDialog *dialog = new LibraryDialog();
163     dialog->exec();
164 }
165
166 void MainWindow::showSettings()
167 {
168     SettingsWindow *settings = new SettingsWindow(this);
169     settings->show();
170 }
171
172 void MainWindow::showInfo()
173 {
174     if (book) {
175         InfoDialog *info = new InfoDialog(book, this);
176         info->exec();
177     }
178 }
179
180 void MainWindow::showDevTools()
181 {
182     DevTools *devTools = new DevTools();
183     devTools->exec();
184 }
185
186 void MainWindow::showBookmarks()
187 {
188     if (book) {
189         BookmarksDialog *bookmarks = new BookmarksDialog(book, this);
190         int ret = bookmarks->exec();
191         if (ret > 0) {
192             int index = ret - 1;
193             view->goToBookmark(book->bookmarks()[index]);
194         }
195         else if (ret < 0) {
196             view->addBookmark();
197         }
198     }
199 }
200
201 void MainWindow::MOUSE_ACTIVATE_EVENT(QMouseEvent *event)
202 {
203     qDebug() << "MainWindow::mousePress/ReleaseEvent at" << event->pos()
204             << "against" << fullScreenZone();
205     if (isFullscreen && fullScreenZone().contains(event->x(), event->y())) {
206         qDebug() << " In fullScreenZone";
207         showNormal();
208     }
209     QMainWindow::MOUSE_ACTIVATE_EVENT(event);
210 }
211
212 QRect MainWindow::fullScreenZone() const
213 {
214     return QRect(width() / 2 - 45, height() - 104, 95, 95);
215 }
216
217 void MainWindow::resizeEvent(QResizeEvent *event)
218 {
219     (void)event;
220     restoreButton->setGeometry(fullScreenZone());
221 }
222
223 void MainWindow::closeEvent(QCloseEvent *event)
224 {
225     qDebug() << "MainWindow::closeEvent";
226     view->setLastBookmark();
227     event->accept();
228 }
229
230 void MainWindow::onSettingsChanged(const QString &key)
231 {
232 #ifdef Q_WS_MAEMO_5
233     if (key == "orientation") {
234         QString value = Settings::instance()->value(key).toString();
235         if (value == "portrait") {
236             setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
237             setAttribute(Qt::WA_Maemo5LandscapeOrientation, false);
238         }
239         else {
240             setAttribute(Qt::WA_Maemo5PortraitOrientation, false);
241             setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
242         }
243     }
244 #else
245     Q_UNUSED(key);
246 #endif // Q_WS_MAEMO_5
247 }
248
249 void MainWindow::onChapterLoaded(int index)
250 {
251     bool enablePrevious = false;
252     bool enableNext = false;
253     if (book) {
254         if (index > 0) {
255             enablePrevious = true;
256         }
257         if (index < (book->toc.size() - 1)) {
258             enableNext = true;
259         }
260     }
261 #ifdef Q_WS_MAEMO_5
262     previousAction->setIcon(QIcon(enablePrevious?
263         ":/icons/previous.png" : ":/icons/previous-disabled.png"));
264     nextAction->setIcon(QIcon(enableNext?
265         ":/icons/next.png": ":/icons/next-disabled.png"));
266 #endif // Q_WS_MAEMO_5
267     previousAction->setEnabled(enablePrevious);
268     nextAction->setEnabled(enableNext);
269 }