2011-01-26 Mansi Mithal <mansi.mithal@nokia.com>
[WebKit.git] / Tools / QtTestBrowser / launcherwindow.cpp
1 /*
2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
4  * Copyright (C) 2006 George Staikos <staikos@kde.org>
5  * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
6  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
7  * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "launcherwindow.h"
34
35 const int gExitClickArea = 80;
36 QVector<int> LauncherWindow::m_zoomLevels;
37
38 LauncherWindow::LauncherWindow(WindowOptions* data, QGraphicsScene* sharedScene)
39     : MainWindow()
40     , m_currentZoom(100)
41     , m_view(0)
42     , m_inspector(0)
43     , m_formatMenuAction(0)
44     , m_zoomAnimation(0)
45 {
46     if (data)
47         m_windowOptions = *data;
48
49     init();
50     if (sharedScene && data->useGraphicsView)
51         static_cast<QGraphicsView*>(m_view)->setScene(sharedScene);
52
53     createChrome();
54 }
55
56 LauncherWindow::~LauncherWindow()
57 {
58     grabZoomKeys(false);
59
60     if (page())
61         page()->setQnamThreaded(false);
62 }
63
64 void LauncherWindow::init()
65 {
66     QSplitter* splitter = new QSplitter(Qt::Vertical, this);
67     setCentralWidget(splitter);
68
69 #if defined(Q_OS_SYMBIAN)
70     setWindowState(Qt::WindowMaximized);
71 #else
72     setWindowState(Qt::WindowNoState);
73     resize(800, 600);
74 #endif
75
76     m_inspector = new WebInspector;
77 #ifndef QT_NO_PROPERTIES
78     if (!m_windowOptions.inspectorUrl.isEmpty())
79         m_inspector->setProperty("_q_inspectorUrl", m_windowOptions.inspectorUrl);
80 #endif
81     connect(this, SIGNAL(destroyed()), m_inspector, SLOT(deleteLater()));
82
83     // the zoom values are chosen to be like in Mozilla Firefox 3
84     if (!m_zoomLevels.count()) {
85         m_zoomLevels << 30 << 50 << 67 << 80 << 90;
86         m_zoomLevels << 100;
87         m_zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300;
88     }
89
90     grabZoomKeys(true);
91
92     initializeView();
93 }
94
95 void LauncherWindow::initializeView()
96 {
97     delete m_view;
98
99     QUrl url = page()->mainFrame()->url();
100     setPage(new WebPage(this));
101     page()->setQnamThreaded(m_windowOptions.useThreadedQnam);
102
103     QSplitter* splitter = static_cast<QSplitter*>(centralWidget());
104
105     if (!m_windowOptions.useGraphicsView) {
106         WebViewTraditional* view = new WebViewTraditional(splitter);
107         view->setPage(page());
108
109         view->installEventFilter(this);
110
111         m_view = view;
112     } else {
113         WebViewGraphicsBased* view = new WebViewGraphicsBased(splitter);
114         view->setPage(page());
115
116         connect(view, SIGNAL(currentFPSUpdated(int)), this, SLOT(updateFPS(int)));
117
118         view->installEventFilter(this);
119         // The implementation of QAbstractScrollArea::eventFilter makes us need
120         // to install the event filter also on the viewport of a QGraphicsView.
121         view->viewport()->installEventFilter(this);
122
123         m_view = view;
124     }
125
126     m_touchMocking = false;
127
128     connect(page(), SIGNAL(loadStarted()), this, SLOT(loadStarted()));
129     connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
130     connect(page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
131             this, SLOT(showLinkHover(const QString&, const QString&)));
132     connect(this, SIGNAL(enteredFullScreenMode(bool)), this, SLOT(toggleFullScreenMode(bool)));
133
134     applyPrefs();
135
136     splitter->addWidget(m_inspector);
137     m_inspector->setPage(page());
138     m_inspector->hide();
139
140     if (m_windowOptions.remoteInspectorPort)
141         page()->setProperty("_q_webInspectorServerPort", m_windowOptions.remoteInspectorPort);
142
143     if (url.isValid())
144         page()->mainFrame()->load(url);
145 }
146
147 void LauncherWindow::applyPrefs()
148 {
149     QWebSettings* settings = page()->settings();
150     settings->setAttribute(QWebSettings::AcceleratedCompositingEnabled, m_windowOptions.useCompositing);
151     settings->setAttribute(QWebSettings::TiledBackingStoreEnabled, m_windowOptions.useTiledBackingStore);
152     settings->setAttribute(QWebSettings::FrameFlatteningEnabled, m_windowOptions.useFrameFlattening);
153     settings->setAttribute(QWebSettings::WebGLEnabled, m_windowOptions.useWebGL);
154
155     if (!isGraphicsBased())
156         return;
157
158     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
159     view->setViewportUpdateMode(m_windowOptions.viewportUpdateMode);
160     view->setFrameRateMeasurementEnabled(m_windowOptions.showFrameRate);
161     view->setItemCacheMode(m_windowOptions.cacheWebView ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
162
163     if (m_windowOptions.resizesToContents)
164         toggleResizesToContents(m_windowOptions.resizesToContents);
165 }
166
167 void LauncherWindow::createChrome()
168 {
169 #ifndef QT_NO_SHORTCUT
170     QMenu* fileMenu = menuBar()->addMenu("&File");
171     fileMenu->addAction("New Window", this, SLOT(newWindow()), QKeySequence::New);
172     fileMenu->addAction(tr("Open File..."), this, SLOT(openFile()), QKeySequence::Open);
173     fileMenu->addAction(tr("Open Location..."), this, SLOT(openLocation()), QKeySequence(Qt::CTRL | Qt::Key_L));
174     fileMenu->addAction("Close Window", this, SLOT(close()), QKeySequence::Close);
175     fileMenu->addSeparator();
176     fileMenu->addAction("Take Screen Shot...", this, SLOT(screenshot()));
177 #ifndef QT_NO_PRINTER
178     fileMenu->addAction(tr("Print..."), this, SLOT(print()), QKeySequence::Print);
179 #endif
180     fileMenu->addSeparator();
181     fileMenu->addAction("Quit", QApplication::instance(), SLOT(closeAllWindows()), QKeySequence(Qt::CTRL | Qt::Key_Q));
182
183     QMenu* editMenu = menuBar()->addMenu("&Edit");
184     editMenu->addAction(page()->action(QWebPage::Undo));
185     editMenu->addAction(page()->action(QWebPage::Redo));
186     editMenu->addSeparator();
187     editMenu->addAction(page()->action(QWebPage::Cut));
188     editMenu->addAction(page()->action(QWebPage::Copy));
189     editMenu->addAction(page()->action(QWebPage::Paste));
190     editMenu->addSeparator();
191     QAction* setEditable = editMenu->addAction("Set Editable", this, SLOT(setEditable(bool)));
192     setEditable->setCheckable(true);
193
194     QMenu* viewMenu = menuBar()->addMenu("&View");
195     viewMenu->addAction(page()->action(QWebPage::Stop));
196     viewMenu->addAction(page()->action(QWebPage::Reload));
197     viewMenu->addSeparator();
198     QAction* zoomIn = viewMenu->addAction("Zoom &In", this, SLOT(zoomIn()));
199     QAction* zoomOut = viewMenu->addAction("Zoom &Out", this, SLOT(zoomOut()));
200     QAction* resetZoom = viewMenu->addAction("Reset Zoom", this, SLOT(resetZoom()));
201     QAction* zoomTextOnly = viewMenu->addAction("Zoom Text Only", this, SLOT(toggleZoomTextOnly(bool)));
202     zoomTextOnly->setCheckable(true);
203     zoomTextOnly->setChecked(false);
204     viewMenu->addSeparator();
205     viewMenu->addAction("Dump HTML", this, SLOT(dumpHtml()));
206     // viewMenu->addAction("Dump plugins", this, SLOT(dumpPlugins()));
207
208     zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
209     zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
210     resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
211
212     QMenu* formatMenu = new QMenu("F&ormat", this);
213     m_formatMenuAction = menuBar()->addMenu(formatMenu);
214     m_formatMenuAction->setVisible(false);
215     formatMenu->addAction(page()->action(QWebPage::ToggleBold));
216     formatMenu->addAction(page()->action(QWebPage::ToggleItalic));
217     formatMenu->addAction(page()->action(QWebPage::ToggleUnderline));
218     QMenu* writingMenu = formatMenu->addMenu(tr("Writing Direction"));
219     writingMenu->addAction(page()->action(QWebPage::SetTextDirectionDefault));
220     writingMenu->addAction(page()->action(QWebPage::SetTextDirectionLeftToRight));
221     writingMenu->addAction(page()->action(QWebPage::SetTextDirectionRightToLeft));
222
223     QMenu* windowMenu = menuBar()->addMenu("&Window");
224     QAction* toggleFullScreen = windowMenu->addAction("Toggle FullScreen", this, SIGNAL(enteredFullScreenMode(bool)));
225     toggleFullScreen->setShortcut(Qt::Key_F11);
226     toggleFullScreen->setCheckable(true);
227     toggleFullScreen->setChecked(false);
228     // When exit fullscreen mode by clicking on the exit area (bottom right corner) we must
229     // uncheck the Toggle FullScreen action.
230     toggleFullScreen->connect(this, SIGNAL(enteredFullScreenMode(bool)), SLOT(setChecked(bool)));
231
232     QWebSettings* settings = page()->settings();
233
234     QMenu* toolsMenu = menuBar()->addMenu("&Develop");
235     QMenu* graphicsViewMenu = toolsMenu->addMenu("QGraphicsView");
236     QAction* toggleGraphicsView = graphicsViewMenu->addAction("Toggle use of QGraphicsView", this, SLOT(toggleWebView(bool)));
237     toggleGraphicsView->setCheckable(true);
238     toggleGraphicsView->setChecked(isGraphicsBased());
239
240     QAction* toggleWebGL = toolsMenu->addAction("Toggle WebGL", this, SLOT(toggleWebGL(bool)));
241     toggleWebGL->setCheckable(true);
242     toggleWebGL->setChecked(settings->testAttribute(QWebSettings::WebGLEnabled));
243
244     QAction* toggleThreadedQnam = toolsMenu->addAction("Toggle threaded network", this, SLOT(toggleThreadedQnam(bool)));
245     toggleThreadedQnam->setCheckable(true);
246     toggleThreadedQnam->setChecked(m_windowOptions.useThreadedQnam);
247
248     QAction* spatialNavigationAction = toolsMenu->addAction("Toggle Spatial Navigation", this, SLOT(toggleSpatialNavigation(bool)));
249     spatialNavigationAction->setCheckable(true);
250     spatialNavigationAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_S));
251
252     QAction* toggleFrameFlattening = toolsMenu->addAction("Toggle Frame Flattening", this, SLOT(toggleFrameFlattening(bool)));
253     toggleFrameFlattening->setCheckable(true);
254     toggleFrameFlattening->setChecked(settings->testAttribute(QWebSettings::FrameFlatteningEnabled));
255
256     QAction* touchMockAction = toolsMenu->addAction("Toggle touch mocking", this, SLOT(setTouchMocking(bool)));
257     touchMockAction->setCheckable(true);
258     touchMockAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_T));
259
260     toolsMenu->addSeparator();
261
262     QAction* userAgentAction = toolsMenu->addAction("Change User Agent", this, SLOT(showUserAgentDialog()));
263     userAgentAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_U));
264
265     toolsMenu->addAction("Select Elements...", this, SLOT(selectElements()));
266
267     QAction* showInspectorAction = toolsMenu->addAction("Show Web Inspector", m_inspector, SLOT(setVisible(bool)), QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_I));
268     showInspectorAction->setCheckable(true);
269     showInspectorAction->connect(m_inspector, SIGNAL(visibleChanged(bool)), SLOT(setChecked(bool)));
270
271     // GraphicsView sub menu.
272     QAction* toggleAcceleratedCompositing = graphicsViewMenu->addAction("Toggle Accelerated Compositing", this, SLOT(toggleAcceleratedCompositing(bool)));
273     toggleAcceleratedCompositing->setCheckable(true);
274     toggleAcceleratedCompositing->setChecked(settings->testAttribute(QWebSettings::AcceleratedCompositingEnabled));
275     toggleAcceleratedCompositing->setEnabled(isGraphicsBased());
276     toggleAcceleratedCompositing->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
277
278     QAction* toggleResizesToContents = graphicsViewMenu->addAction("Toggle Resizes To Contents Mode", this, SLOT(toggleResizesToContents(bool)));
279     toggleResizesToContents->setCheckable(true);
280     toggleResizesToContents->setChecked(m_windowOptions.resizesToContents);
281     toggleResizesToContents->setEnabled(isGraphicsBased());
282     toggleResizesToContents->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
283
284     QAction* toggleTiledBackingStore = graphicsViewMenu->addAction("Toggle Tiled Backing Store", this, SLOT(toggleTiledBackingStore(bool)));
285     toggleTiledBackingStore->setCheckable(true);
286     toggleTiledBackingStore->setChecked(m_windowOptions.useTiledBackingStore);
287     toggleTiledBackingStore->setEnabled(isGraphicsBased());
288     toggleTiledBackingStore->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
289
290 #if defined(QT_CONFIGURED_WITH_OPENGL)
291     QAction* toggleQGLWidgetViewport = graphicsViewMenu->addAction("Toggle use of QGLWidget Viewport", this, SLOT(toggleQGLWidgetViewport(bool)));
292     toggleQGLWidgetViewport->setCheckable(true);
293     toggleQGLWidgetViewport->setChecked(m_windowOptions.useQGLWidgetViewport);
294     toggleQGLWidgetViewport->setEnabled(isGraphicsBased());
295     toggleQGLWidgetViewport->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
296 #endif
297
298     QMenu* viewportUpdateMenu = graphicsViewMenu->addMenu("Change Viewport Update Mode");
299     viewportUpdateMenu->setEnabled(isGraphicsBased());
300     viewportUpdateMenu->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
301
302     QAction* fullUpdate = viewportUpdateMenu->addAction("FullViewportUpdate");
303     fullUpdate->setCheckable(true);
304     fullUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::FullViewportUpdate) ? true : false);
305
306     QAction* minimalUpdate = viewportUpdateMenu->addAction("MinimalViewportUpdate");
307     minimalUpdate->setCheckable(true);
308     minimalUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::MinimalViewportUpdate) ? true : false);
309
310     QAction* smartUpdate = viewportUpdateMenu->addAction("SmartViewportUpdate");
311     smartUpdate->setCheckable(true);
312     smartUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::SmartViewportUpdate) ? true : false);
313
314     QAction* boundingRectUpdate = viewportUpdateMenu->addAction("BoundingRectViewportUpdate");
315     boundingRectUpdate->setCheckable(true);
316     boundingRectUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) ? true : false);
317
318     QAction* noUpdate = viewportUpdateMenu->addAction("NoViewportUpdate");
319     noUpdate->setCheckable(true);
320     noUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::NoViewportUpdate) ? true : false);
321
322     QSignalMapper* signalMapper = new QSignalMapper(viewportUpdateMenu);
323     signalMapper->setMapping(fullUpdate, QGraphicsView::FullViewportUpdate);
324     signalMapper->setMapping(minimalUpdate, QGraphicsView::MinimalViewportUpdate);
325     signalMapper->setMapping(smartUpdate, QGraphicsView::SmartViewportUpdate);
326     signalMapper->setMapping(boundingRectUpdate, QGraphicsView::BoundingRectViewportUpdate);
327     signalMapper->setMapping(noUpdate, QGraphicsView::NoViewportUpdate);
328
329     connect(fullUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
330     connect(minimalUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
331     connect(smartUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
332     connect(boundingRectUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
333     connect(noUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
334
335     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(changeViewportUpdateMode(int)));
336
337     QActionGroup* viewportUpdateModeActions = new QActionGroup(viewportUpdateMenu);
338     viewportUpdateModeActions->addAction(fullUpdate);
339     viewportUpdateModeActions->addAction(minimalUpdate);
340     viewportUpdateModeActions->addAction(smartUpdate);
341     viewportUpdateModeActions->addAction(boundingRectUpdate);
342     viewportUpdateModeActions->addAction(noUpdate);
343
344     graphicsViewMenu->addSeparator();
345
346     QAction* flipAnimated = graphicsViewMenu->addAction("Animated Flip");
347     flipAnimated->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
348     flipAnimated->setEnabled(isGraphicsBased());
349     connect(flipAnimated, SIGNAL(triggered()), SLOT(animatedFlip()));
350
351     QAction* flipYAnimated = graphicsViewMenu->addAction("Animated Y-Flip");
352     flipYAnimated->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
353     flipYAnimated->setEnabled(isGraphicsBased());
354     connect(flipYAnimated, SIGNAL(triggered()), SLOT(animatedYFlip()));
355
356     QAction* cloneWindow = graphicsViewMenu->addAction("Clone Window", this, SLOT(cloneWindow()));
357     cloneWindow->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
358     cloneWindow->setEnabled(isGraphicsBased());
359
360     graphicsViewMenu->addSeparator();
361
362     QAction* showFPS = graphicsViewMenu->addAction("Show FPS", this, SLOT(showFPS(bool)));
363     showFPS->setCheckable(true);
364     showFPS->setEnabled(isGraphicsBased());
365     showFPS->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
366     showFPS->setChecked(m_windowOptions.showFrameRate);
367
368     QMenu* settingsMenu = menuBar()->addMenu("&Settings");
369
370     QAction* toggleAutoLoadImages = settingsMenu->addAction("Disable Auto Load Images", this, SLOT(toggleAutoLoadImages(bool)));
371     toggleAutoLoadImages->setCheckable(true);
372     toggleAutoLoadImages->setChecked(false);
373
374     QAction* togglePlugins = settingsMenu->addAction("Disable Plugins", this, SLOT(togglePlugins(bool)));
375     togglePlugins->setCheckable(true);
376     togglePlugins->setChecked(false);
377
378     QAction* toggleInterruptingJavaScripteEnabled = settingsMenu->addAction("Enable interrupting js scripts", this, SLOT(toggleInterruptingJavaScriptEnabled(bool)));
379     toggleInterruptingJavaScripteEnabled->setCheckable(true);
380     toggleInterruptingJavaScripteEnabled->setChecked(false);
381
382     QAction* toggleJavascriptCanOpenWindows = settingsMenu->addAction("Enable js popup windows", this, SLOT(toggleJavascriptCanOpenWindows(bool)));
383     toggleJavascriptCanOpenWindows->setCheckable(true);
384     toggleJavascriptCanOpenWindows->setChecked(false);
385
386 #endif
387 }
388
389 bool LauncherWindow::isGraphicsBased() const
390 {
391     return bool(qobject_cast<QGraphicsView*>(m_view));
392 }
393
394 void LauncherWindow::keyPressEvent(QKeyEvent* event)
395 {
396 #ifdef Q_WS_MAEMO_5
397     switch (event->key()) {
398     case Qt::Key_F7:
399         zoomIn();
400         event->accept();
401         break;
402     case Qt::Key_F8:
403         zoomOut();
404         event->accept();
405         break;
406     }
407 #endif
408     MainWindow::keyPressEvent(event);
409 }
410
411 void LauncherWindow::grabZoomKeys(bool grab)
412 {
413 #ifdef Q_WS_MAEMO_5
414     if (!winId()) {
415         qWarning("Can't grab keys unless we have a window id");
416         return;
417     }
418
419     Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
420     if (!atom) {
421         qWarning("Unable to obtain _HILDON_ZOOM_KEY_ATOM");
422         return;
423     }
424
425     unsigned long val = (grab) ? 1 : 0;
426     XChangeProperty(QX11Info::display(), winId(), atom, XA_INTEGER, 32, PropModeReplace, reinterpret_cast<unsigned char*>(&val), 1);
427 #endif
428 }
429
430 void LauncherWindow::sendTouchEvent()
431 {
432     if (m_touchPoints.isEmpty())
433         return;
434
435     QEvent::Type type = QEvent::TouchUpdate;
436     if (m_touchPoints.size() == 1) {
437         if (m_touchPoints[0].state() == Qt::TouchPointReleased)
438             type = QEvent::TouchEnd;
439         else if (m_touchPoints[0].state() == Qt::TouchPointPressed)
440             type = QEvent::TouchBegin;
441     }
442
443     QTouchEvent touchEv(type);
444     touchEv.setTouchPoints(m_touchPoints);
445     QCoreApplication::sendEvent(page(), &touchEv);
446
447     // After sending the event, remove all touchpoints that were released
448     if (m_touchPoints[0].state() == Qt::TouchPointReleased)
449         m_touchPoints.removeAt(0);
450     if (m_touchPoints.size() > 1 && m_touchPoints[1].state() == Qt::TouchPointReleased)
451         m_touchPoints.removeAt(1);
452 }
453
454 bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
455 {
456     // If click pos is the bottom right corner (square with size defined by gExitClickArea)
457     // and the window is on FullScreen, the window must return to its original state.
458     if (event->type() == QEvent::MouseButtonRelease) {
459         QMouseEvent* ev = static_cast<QMouseEvent*>(event);
460         if (windowState() == Qt::WindowFullScreen
461             && ev->pos().x() > (width() - gExitClickArea)
462             && ev->pos().y() > (height() - gExitClickArea)) {
463
464             emit enteredFullScreenMode(false);
465         }
466     }
467
468     if (!m_touchMocking)
469         return QObject::eventFilter(obj, event);
470
471     if (event->type() == QEvent::MouseButtonPress
472         || event->type() == QEvent::MouseButtonRelease
473         || event->type() == QEvent::MouseButtonDblClick
474         || event->type() == QEvent::MouseMove) {
475
476         QMouseEvent* ev = static_cast<QMouseEvent*>(event);
477         if (ev->type() == QEvent::MouseMove
478             && !(ev->buttons() & Qt::LeftButton))
479             return false;
480
481         QTouchEvent::TouchPoint touchPoint;
482         touchPoint.setState(Qt::TouchPointMoved);
483         if ((ev->type() == QEvent::MouseButtonPress
484              || ev->type() == QEvent::MouseButtonDblClick))
485             touchPoint.setState(Qt::TouchPointPressed);
486         else if (ev->type() == QEvent::MouseButtonRelease)
487             touchPoint.setState(Qt::TouchPointReleased);
488
489         touchPoint.setId(0);
490         touchPoint.setScreenPos(ev->globalPos());
491         touchPoint.setPos(ev->pos());
492         touchPoint.setPressure(1);
493
494         // If the point already exists, update it. Otherwise create it.
495         if (m_touchPoints.size() > 0 && !m_touchPoints[0].id())
496             m_touchPoints[0] = touchPoint;
497         else if (m_touchPoints.size() > 1 && !m_touchPoints[1].id())
498             m_touchPoints[1] = touchPoint;
499         else
500             m_touchPoints.append(touchPoint);
501
502         sendTouchEvent();
503     } else if (event->type() == QEvent::KeyPress
504         && static_cast<QKeyEvent*>(event)->key() == Qt::Key_F
505         && static_cast<QKeyEvent*>(event)->modifiers() == Qt::ControlModifier) {
506
507         // If the keyboard point is already pressed, release it.
508         // Otherwise create it and append to m_touchPoints.
509         if (m_touchPoints.size() > 0 && m_touchPoints[0].id() == 1) {
510             m_touchPoints[0].setState(Qt::TouchPointReleased);
511             sendTouchEvent();
512         } else if (m_touchPoints.size() > 1 && m_touchPoints[1].id() == 1) {
513             m_touchPoints[1].setState(Qt::TouchPointReleased);
514             sendTouchEvent();
515         } else {
516             QTouchEvent::TouchPoint touchPoint;
517             touchPoint.setState(Qt::TouchPointPressed);
518             touchPoint.setId(1);
519             touchPoint.setScreenPos(QCursor::pos());
520             touchPoint.setPos(m_view->mapFromGlobal(QCursor::pos()));
521             touchPoint.setPressure(1);
522             m_touchPoints.append(touchPoint);
523             sendTouchEvent();
524
525             // After sending the event, change the touchpoint state to stationary
526             m_touchPoints.last().setState(Qt::TouchPointStationary);
527         }
528     }
529
530     return false;
531 }
532
533 void LauncherWindow::loadStarted()
534 {
535     m_view->setFocus(Qt::OtherFocusReason);
536 }
537
538 void LauncherWindow::loadFinished()
539 {
540     QUrl url = page()->mainFrame()->url();
541     setAddressUrl(url.toString(QUrl::RemoveUserInfo));
542     addCompleterEntry(url);
543 }
544
545 void LauncherWindow::showLinkHover(const QString &link, const QString &toolTip)
546 {
547 #ifndef Q_WS_MAEMO_5
548     statusBar()->showMessage(link);
549 #endif
550 #ifndef QT_NO_TOOLTIP
551     if (!toolTip.isEmpty())
552         QToolTip::showText(QCursor::pos(), toolTip);
553 #endif
554 }
555
556 void LauncherWindow::zoomAnimationFinished()
557 {
558     if (!isGraphicsBased())
559         return;
560     QGraphicsWebView* view = static_cast<WebViewGraphicsBased*>(m_view)->graphicsWebView();
561     view->setTiledBackingStoreFrozen(false);
562 }
563
564 void LauncherWindow::applyZoom()
565 {
566 #ifndef QT_NO_ANIMATION
567     if (isGraphicsBased() && page()->settings()->testAttribute(QWebSettings::TiledBackingStoreEnabled)) {
568         QGraphicsWebView* view = static_cast<WebViewGraphicsBased*>(m_view)->graphicsWebView();
569         view->setTiledBackingStoreFrozen(true);
570         if (!m_zoomAnimation) {
571             m_zoomAnimation = new QPropertyAnimation(view, "scale");
572             m_zoomAnimation->setStartValue(view->scale());
573             connect(m_zoomAnimation, SIGNAL(finished()), this, SLOT(zoomAnimationFinished()));
574         } else {
575             m_zoomAnimation->stop();
576             m_zoomAnimation->setStartValue(m_zoomAnimation->currentValue());
577         }
578
579         m_zoomAnimation->setDuration(300);
580         m_zoomAnimation->setEndValue(qreal(m_currentZoom) / 100.);
581         m_zoomAnimation->start();
582         return;
583     }
584 #endif
585     page()->mainFrame()->setZoomFactor(qreal(m_currentZoom) / 100.0);
586 }
587
588 void LauncherWindow::zoomIn()
589 {
590     int i = m_zoomLevels.indexOf(m_currentZoom);
591     Q_ASSERT(i >= 0);
592     if (i < m_zoomLevels.count() - 1)
593         m_currentZoom = m_zoomLevels[i + 1];
594
595     applyZoom();
596 }
597
598 void LauncherWindow::zoomOut()
599 {
600     int i = m_zoomLevels.indexOf(m_currentZoom);
601     Q_ASSERT(i >= 0);
602     if (i > 0)
603         m_currentZoom = m_zoomLevels[i - 1];
604
605     applyZoom();
606 }
607
608 void LauncherWindow::resetZoom()
609 {
610     m_currentZoom = 100;
611     applyZoom();
612 }
613
614 void LauncherWindow::toggleZoomTextOnly(bool b)
615 {
616     page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, b);
617 }
618
619 void LauncherWindow::print()
620 {
621 #if !defined(QT_NO_PRINTER)
622     QPrintPreviewDialog dlg(this);
623     connect(&dlg, SIGNAL(paintRequested(QPrinter*)),
624             page()->mainFrame(), SLOT(print(QPrinter*)));
625     dlg.exec();
626 #endif
627 }
628
629 void LauncherWindow::screenshot()
630 {
631     QPixmap pixmap = QPixmap::grabWidget(m_view);
632     QLabel* label = 0;
633 #if !defined(Q_OS_SYMBIAN)
634     label = new QLabel;
635     label->setAttribute(Qt::WA_DeleteOnClose);
636     label->setWindowTitle("Screenshot - Preview");
637     label->setPixmap(pixmap);
638     label->show();
639 #endif
640
641 #ifndef QT_NO_FILEDIALOG
642     QString fileName = QFileDialog::getSaveFileName(label, "Screenshot");
643     if (!fileName.isEmpty()) {
644         pixmap.save(fileName, "png");
645         if (label)
646             label->setWindowTitle(QString("Screenshot - Saved at %1").arg(fileName));
647     }
648 #endif
649
650 #if defined(QT_CONFIGURED_WITH_OPENGL)
651     toggleQGLWidgetViewport(m_windowOptions.useQGLWidgetViewport);
652 #endif
653 }
654
655 void LauncherWindow::setEditable(bool on)
656 {
657     page()->setContentEditable(on);
658     m_formatMenuAction->setVisible(on);
659 }
660
661 /*
662 void LauncherWindow::dumpPlugins() {
663     QList<QWebPluginInfo> plugins = QWebSettings::pluginDatabase()->plugins();
664     foreach (const QWebPluginInfo plugin, plugins) {
665         qDebug() << "Plugin:" << plugin.name();
666         foreach (const QWebPluginInfo::MimeType mime, plugin.mimeTypes()) {
667             qDebug() << "   " << mime.name;
668         }
669     }
670 }
671 */
672
673 void LauncherWindow::dumpHtml()
674 {
675     qDebug() << "HTML: " << page()->mainFrame()->toHtml();
676 }
677
678 void LauncherWindow::selectElements()
679 {
680 #ifndef QT_NO_INPUTDIALOG
681     bool ok;
682     QString str = QInputDialog::getText(this, "Select elements", "Choose elements",
683                                         QLineEdit::Normal, "a", &ok);
684
685     if (ok && !str.isEmpty()) {
686         QWebElementCollection result =  page()->mainFrame()->findAllElements(str);
687         foreach (QWebElement e, result)
688             e.setStyleProperty("background-color", "yellow");
689 #ifndef Q_WS_MAEMO_5
690         statusBar()->showMessage(QString("%1 element(s) selected").arg(result.count()), 5000);
691 #endif
692     }
693 #endif
694 }
695
696 void LauncherWindow::setTouchMocking(bool on)
697 {
698     m_touchMocking = on;
699 }
700
701 void LauncherWindow::toggleWebView(bool graphicsBased)
702 {
703     m_windowOptions.useGraphicsView = graphicsBased;
704     initializeView();
705     menuBar()->clear();
706     createChrome();
707 }
708
709 void LauncherWindow::toggleAcceleratedCompositing(bool toggle)
710 {
711     m_windowOptions.useCompositing = toggle;
712     page()->settings()->setAttribute(QWebSettings::AcceleratedCompositingEnabled, toggle);
713 }
714
715 void LauncherWindow::toggleTiledBackingStore(bool toggle)
716 {
717     page()->settings()->setAttribute(QWebSettings::TiledBackingStoreEnabled, toggle);
718 }
719
720 void LauncherWindow::toggleResizesToContents(bool toggle)
721 {
722     m_windowOptions.resizesToContents = toggle;
723     static_cast<WebViewGraphicsBased*>(m_view)->setResizesToContents(toggle);
724 }
725
726 void LauncherWindow::toggleWebGL(bool toggle)
727 {
728     m_windowOptions.useWebGL = toggle;
729     page()->settings()->setAttribute(QWebSettings::WebGLEnabled, toggle);
730 }
731
732 void LauncherWindow::toggleThreadedQnam(bool toggle)
733 {
734     m_windowOptions.useThreadedQnam = toggle;
735     page()->setQnamThreaded(toggle);
736 }
737
738 void LauncherWindow::animatedFlip()
739 {
740     qobject_cast<WebViewGraphicsBased*>(m_view)->animatedFlip();
741 }
742
743 void LauncherWindow::animatedYFlip()
744 {
745     qobject_cast<WebViewGraphicsBased*>(m_view)->animatedYFlip();
746 }
747 void LauncherWindow::toggleSpatialNavigation(bool b)
748 {
749     page()->settings()->setAttribute(QWebSettings::SpatialNavigationEnabled, b);
750 }
751
752 void LauncherWindow::toggleFullScreenMode(bool enable)
753 {
754     if (enable)
755         setWindowState(Qt::WindowFullScreen);
756     else {
757 #if defined(Q_OS_SYMBIAN)
758         setWindowState(Qt::WindowMaximized);
759 #else
760         setWindowState(Qt::WindowNoState);
761 #endif
762     }
763 }
764
765 void LauncherWindow::toggleFrameFlattening(bool toggle)
766 {
767     m_windowOptions.useFrameFlattening = toggle;
768     page()->settings()->setAttribute(QWebSettings::FrameFlatteningEnabled, toggle);
769 }
770
771 void LauncherWindow::toggleInterruptingJavaScriptEnabled(bool enable)
772 {
773     page()->setInterruptingJavaScriptEnabled(enable);
774 }
775
776 void LauncherWindow::toggleJavascriptCanOpenWindows(bool enable)
777 {
778     page()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, enable);
779 }
780
781 void LauncherWindow::toggleAutoLoadImages(bool enable)
782 {
783     page()->settings()->setAttribute(QWebSettings::AutoLoadImages, !enable);
784 }
785
786 void LauncherWindow::togglePlugins(bool enable)
787 {
788     page()->settings()->setAttribute(QWebSettings::PluginsEnabled, !enable);
789 }
790
791 #if defined(QT_CONFIGURED_WITH_OPENGL)
792 void LauncherWindow::toggleQGLWidgetViewport(bool enable)
793 {
794     if (!isGraphicsBased())
795         return;
796
797     m_windowOptions.useQGLWidgetViewport = enable;
798     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
799
800     view->setViewport(enable ? new QGLWidget() : 0);
801 }
802 #endif
803
804 void LauncherWindow::changeViewportUpdateMode(int mode)
805 {
806     m_windowOptions.viewportUpdateMode = QGraphicsView::ViewportUpdateMode(mode);
807
808     if (!isGraphicsBased())
809         return;
810
811     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
812     view->setViewportUpdateMode(m_windowOptions.viewportUpdateMode);
813 }
814
815 void LauncherWindow::showFPS(bool enable)
816 {
817     if (!isGraphicsBased())
818         return;
819
820     m_windowOptions.showFrameRate = enable;
821     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
822     view->setFrameRateMeasurementEnabled(enable);
823
824     if (!enable) {
825 #if defined(Q_WS_MAEMO_5) && defined(Q_OS_SYMBIAN)
826         setWindowTitle("");
827 #else
828         statusBar()->clearMessage();
829 #endif
830     }
831 }
832
833 void LauncherWindow::showUserAgentDialog()
834 {
835     QStringList items;
836     QFile file(":/useragentlist.txt");
837     if (file.open(QIODevice::ReadOnly)) {
838          while (!file.atEnd())
839             items << file.readLine().trimmed();
840         file.close();
841     }
842
843     QSettings settings;
844     QString customUserAgent = settings.value("CustomUserAgent").toString();
845     if (!items.contains(customUserAgent) && !customUserAgent.isEmpty())
846         items << customUserAgent;
847
848     QDialog* dialog = new QDialog(this);
849     dialog->resize(size().width() * 0.7, dialog->size().height());
850     dialog->setMaximumHeight(dialog->size().height());
851     dialog->setWindowTitle("Change User Agent");
852
853     QVBoxLayout* layout = new QVBoxLayout(dialog);
854     dialog->setLayout(layout);
855
856 #ifndef QT_NO_COMBOBOX
857     QComboBox* combo = new QComboBox(dialog);
858     combo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
859     combo->setEditable(true);
860     combo->insertItems(0, items);
861     layout->addWidget(combo);
862
863     int index = combo->findText(page()->userAgentForUrl(QUrl()));
864     combo->setCurrentIndex(index);
865 #endif
866
867     QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
868             | QDialogButtonBox::Cancel, Qt::Horizontal, dialog);
869     connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
870     connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
871     layout->addWidget(buttonBox);
872
873 #ifndef QT_NO_COMBOBOX
874     if (dialog->exec() && !combo->currentText().isEmpty()) {
875         page()->setUserAgent(combo->currentText());
876         if (!items.contains(combo->currentText()))
877             settings.setValue("CustomUserAgent", combo->currentText());
878     }
879 #endif
880
881     delete dialog;
882 }
883
884 void LauncherWindow::updateFPS(int fps)
885 {
886     QString fpsStatusText = QString("Current FPS: %1").arg(fps);
887
888 #if defined(Q_WS_MAEMO_5) && defined(Q_OS_SYMBIAN)
889     setWindowTitle(fpsStatusText);
890 #else
891     statusBar()->showMessage(fpsStatusText);
892 #endif
893 }
894
895 LauncherWindow* LauncherWindow::newWindow()
896 {
897     LauncherWindow* mw = new LauncherWindow(&m_windowOptions);
898     mw->show();
899     return mw;
900 }
901
902 LauncherWindow* LauncherWindow::cloneWindow()
903 {
904     LauncherWindow* mw = new LauncherWindow(&m_windowOptions, qobject_cast<QGraphicsView*>(m_view)->scene());
905     mw->show();
906     return mw;
907 }
908