.
[dorian] / adopterwindow.cpp
1 #include <QtGui>
2
3 #if defined(Q_WS_MAEMO_5)
4 #   include <QtGui/QX11Info>
5 #   include <X11/Xlib.h>
6 #   include <X11/Xatom.h>
7 #   include <QAbstractKineticScroller>
8 #endif
9
10 #include "adopterwindow.h"
11 #include "trace.h"
12 #include "bookview.h"
13 #include "platform.h"
14 #include "settings.h"
15 #include "progress.h"
16 #include "translucentbutton.h"
17
18 AdopterWindow::AdopterWindow(QWidget *parent):
19     QMainWindow(parent), bookView(0), grabbingVolumeKeys(false), toolBar(0),
20     progress(0), previousButton(0), nextButton(0)
21 {
22     TRACE;
23
24 #ifdef Q_WS_MAEMO_5
25     setAttribute(Qt::WA_Maemo5StackedWindow, true);
26 #endif
27
28     QFrame *frame = new QFrame(this);
29     QVBoxLayout *layout = new QVBoxLayout(frame);
30     layout->setMargin(0);
31     frame->setLayout(layout);
32     //frame->show();
33     setCentralWidget(frame);
34
35 #ifdef Q_OS_SYMBIAN
36     QAction *closeAction = new QAction(parent? tr("Back"): tr("Exit"), this);
37     closeAction->setSoftKeyRole(QAction::NegativeSoftKey);
38     connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
39     QMainWindow::addAction(closeAction);
40 #else
41     // Tool bar
42     setUnifiedTitleAndToolBarOnMac(true);
43     toolBar = addToolBar("");
44     toolBar->setMovable(false);
45     toolBar->setFloatable(false);
46     toolBar->toggleViewAction()->setVisible(false);
47 #if defined(Q_WS_X11) && !defined(Q_WS_MAEMO_5)
48     toolBar->setIconSize(QSize(42, 42));
49 #endif
50 #endif // Q_OS_SYMBIAN
51
52     // Monitor settings
53     connect(Settings::instance(), SIGNAL(valueChanged(const QString &)),
54             this, SLOT(onSettingsChanged(const QString &)));
55 }
56
57 void AdopterWindow::takeBookView(BookView *view,
58                                  Progress *prog,
59                                  TranslucentButton *previous,
60                                  TranslucentButton *next)
61 {
62     TRACE;
63
64     Q_ASSERT(view);
65     Q_ASSERT(prog);
66     Q_ASSERT(previous);
67     Q_ASSERT(next);
68
69     leaveBookView();
70
71     bookView = view;
72     bookView->setParent(this);
73     centralWidget()->layout()->addWidget(bookView);
74     bookView->show();
75
76     progress = prog;
77     previousButton = previous;
78     nextButton = next;
79     progress->setParent(this);
80     previousButton->setParent(this);
81     nextButton->setParent(this);
82 }
83
84 void AdopterWindow::leaveBookView()
85 {
86     TRACE;
87     if (bookView) {
88         bookView->hide();
89         centralWidget()->layout()->removeWidget(bookView);
90     }
91     bookView = 0;
92     progress = 0;
93     nextButton = 0;
94     previousButton = 0;
95 }
96
97 bool AdopterWindow::hasBookView()
98 {
99     return bookView != 0;
100 }
101
102 void AdopterWindow::show()
103 {
104     Trace t("AdopterWindow::show");
105 #ifdef Q_OS_SYMBIAN
106     foreach (QWidget *w, QApplication::allWidgets()) {
107         w->setContextMenuPolicy(Qt::NoContextMenu);
108     }
109     showMaximized();
110 #else
111     QMainWindow::show();
112 #endif
113 }
114
115 QAction *AdopterWindow::addToolBarAction(QObject *receiver,
116                                          const char *member,
117                                          const QString &iconName,
118                                          const QString &text,
119                                          bool important)
120 {
121     TRACE;
122     qDebug() << "icon" << iconName << "text" << text;
123     QAction *action;
124 #ifndef Q_OS_SYMBIAN
125     Q_UNUSED(important);
126     action = toolBar->addAction(QIcon(Platform::instance()->icon(iconName)),
127                                 text, receiver, member);
128 #else
129     if (!toolBar && important) {
130         // Create tool bar if needed
131         toolBar = new QToolBar("", this);
132         // toolBar->setFixedWidth(QApplication::desktop()->
133         //                        availableGeometry().width());
134         toolBar->setFixedHeight(65);
135         toolBar->setStyleSheet("margin:0; border:0; padding:0");
136         toolBar->setSizePolicy(QSizePolicy::MinimumExpanding,
137                                QSizePolicy::Maximum);
138         addToolBar(Qt::BottomToolBarArea, toolBar);
139     }
140     if (important) {
141         // Add tool bar action
142         QPushButton *button = new QPushButton(this);
143         button->setIconSize(QSize(60, 60));
144         button->setFixedSize(89, 60);
145         button->setIcon(QIcon(Platform::instance()->icon(iconName)));
146         button->setSizePolicy(QSizePolicy::MinimumExpanding,
147                               QSizePolicy::Maximum);
148         connect(button, SIGNAL(clicked()), receiver, member);
149         toolBar->addWidget(button);
150     }
151     // Add menu action, too
152     action = new QAction(text, this);
153     menuBar()->addAction(action);
154     connect(action, SIGNAL(triggered()), receiver, member);
155 #endif
156
157 #if defined Q_WS_MAEMO_5
158     action->setText("");
159     action->setToolTip("");
160 #endif
161
162     return action;
163 }
164
165 void AdopterWindow::addToolBarSpace()
166 {
167 #ifndef Q_OS_SYMBIAN
168     QFrame *frame = new QFrame(toolBar);
169     frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
170     toolBar->addWidget(frame);
171 #endif
172 }
173
174 void AdopterWindow::grabVolumeKeys(bool grab)
175 {
176     TRACE;
177     grabbingVolumeKeys = grab;
178 #ifdef Q_WS_MAEMO_5
179     doGrabVolumeKeys(grab);
180 #endif
181 }
182
183 #ifdef Q_WS_MAEMO_5
184
185 void AdopterWindow::doGrabVolumeKeys(bool grab)
186 {
187     TRACE;
188     if (!isVisible()) {
189         qDebug() << "Not visible - skipping";
190         return;
191     }
192     if (!winId()) {
193         qDebug() << "Could not get window ID - skipping";
194         return;
195     }
196     unsigned long val = grab? 1: 0;
197     Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
198     if (!atom) {
199         qCritical() << "Unable to obtain _HILDON_ZOOM_KEY_ATOM";
200         return;
201     }
202     XChangeProperty(QX11Info::display(),
203         winId(),
204         atom,
205         XA_INTEGER,
206         32,
207         PropModeReplace,
208         reinterpret_cast<unsigned char *>(&val),
209         1);
210     qDebug() << "Grabbed volume keys";
211 }
212
213 #endif // Q_WS_MAEMO_5
214
215 void AdopterWindow::showEvent(QShowEvent *e)
216 {
217     Trace t("AdopterWindow::showEvent");
218
219 #ifdef Q_OS_SYMBIAN
220     if (toolBar) {
221         if (portrait()) {
222             qDebug() << "Show tool bar";
223             toolBar->setVisible(true);
224         } else {
225             qDebug() << "Hide tool bar";
226             toolBar->setVisible(false);
227         }
228     }
229 #endif // Q_OS_SYMBIAN
230     QMainWindow::showEvent(e);
231 #if defined(Q_WS_MAEMO_5)
232     doGrabVolumeKeys(grabbingVolumeKeys);
233 #endif // Q_WS_MAEMO_5
234     placeDecorations();
235 }
236
237 void AdopterWindow::resizeEvent(QResizeEvent *event)
238 {
239     Trace t("AdopterWindow::resizeEvent");
240 #ifdef Q_OS_SYMBIAN
241     if (toolBar) {
242         if (portrait()) {
243             qDebug() << "Show tool bar";
244             toolBar->setVisible(true);
245         } else {
246             qDebug() << "Hide tool bar";
247             toolBar->setVisible(false);
248         }
249     }
250 #endif // Q_OS_SYMBIAN
251
252     QMainWindow::resizeEvent(event);
253     placeDecorations();
254 }
255
256 void AdopterWindow::keyPressEvent(QKeyEvent *event)
257 {
258     TRACE;
259     if (bookView && grabbingVolumeKeys) {
260         switch (event->key()) {
261 #ifdef Q_WS_MAEMO_5
262         case Qt::Key_F7:
263             qDebug() << "F7";
264             bookView->goNextPage();
265             event->accept();
266             break;
267         case Qt::Key_F8:
268             qDebug() << "F8";
269             bookView->goPreviousPage();
270             event->accept();
271             break;
272 #endif // Q_WS_MAEMO_5
273         case Qt::Key_PageUp:
274             bookView->goPreviousPage();
275             event->accept();
276             break;
277         case Qt::Key_PageDown:
278             bookView->goNextPage();
279             event->accept();
280             break;
281         default:
282             ;
283         }
284     }
285     QMainWindow::keyPressEvent(event);
286 }
287
288 void AdopterWindow::onSettingsChanged(const QString &key)
289 {
290     if (key == "usevolumekeys") {
291         bool grab = Settings::instance()->value(key, false).toBool();
292         qDebug() << "AdopterWindow::onSettingsChanged: usevolumekeys" << grab;
293         grabVolumeKeys(grab);
294     }
295 }
296
297 bool AdopterWindow::portrait()
298 {
299     QRect geometry = QApplication::desktop()->geometry();
300     return geometry.width() < geometry.height();
301 }
302
303 void AdopterWindow::placeDecorations()
304 {
305     Trace t("AdopterWindow::placeDecorations");
306
307     if (!hasBookView()) {
308         return;
309     }
310
311     int toolBarHeight = 0;
312
313     QRect geo = bookView->geometry();
314     qDebug() << "bookView:" << geo;
315
316 #ifdef Q_OS_SYMBIAN
317     // Work around Symbian bug: If tool bar is hidden, increase bottom
318     // decorator widgets' Y coordinates by the tool bar's height
319     if (!portrait() && toolBar) {
320         toolBarHeight = toolBar->height();
321     }
322
323     // Work around another Symbian bug: When returning from full screen mode
324     // in landscape, the book view widget's height is miscalculated.
325     // My apologies for this kludge
326     if (geo.height() == 288) {
327         qDebug() << "Adjusting bottom Y";
328         toolBarHeight -= 288 - 223;
329     }
330 #endif // Q_OS_SYMBIAN
331
332     progress->setGeometry(geo.x(),
333         geo.y() + geo.height() - progress->thickness() + toolBarHeight,
334         geo.width(), progress->thickness());
335     previousButton->setGeometry(geo.x(),
336         geo.y() + geo.height() - TranslucentButton::pixels + toolBarHeight,
337         TranslucentButton::pixels, TranslucentButton::pixels);
338     nextButton->setGeometry(
339         geo.x() + geo.width() - TranslucentButton::pixels,
340         geo.y(), TranslucentButton::pixels, TranslucentButton::pixels);
341     progress->flash();
342     previousButton->flash();
343     nextButton->flash();
344     qDebug() << "progress:" << progress->geometry();
345 }