Fix webgl crash issue.
[framework/web/webkit-efl.git] / Tools / QtTestBrowser / launcherwindow.cpp
1 /*
2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2011 University of Szeged
4  * Copyright (C) 2011 Kristof Kosztyo <Kosztyo.Kristof@stud.u-szeged.hu>
5  * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
6  * Copyright (C) 2006 George Staikos <staikos@kde.org>
7  * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
8  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
9  * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
10  *
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
23  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
30  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include "config.h"
36
37 #include "launcherwindow.h"
38 #include "cookiejar.h"
39 #include "urlloader.h"
40
41 #include <QApplication>
42 #include <QCheckBox>
43 #include <QComboBox>
44 #include <QCoreApplication>
45 #include <QDialogButtonBox>
46 #include <QInputDialog>
47 #include <QLabel>
48 #ifndef QT_NO_LINEEDIT
49 #include <QLineEdit>
50 #endif
51 #ifndef QT_NO_SHORTCUT
52 #include <QMenuBar>
53 #endif
54 #include <QSlider>
55 #include <QSplitter>
56 #include <QStatusBar>
57 #include <QToolButton>
58 #include <QToolTip>
59 #include <QVBoxLayout>
60
61 #if !defined(QT_NO_FILEDIALOG) && !defined(QT_NO_MESSAGEBOX)
62 #include <QFileDialog>
63 #include <QFileInfo>
64 #include <QMessageBox>
65 #include <QNetworkReply>
66 #endif
67
68 #if !defined(QT_NO_NETWORKDISKCACHE) && !defined(QT_NO_DESKTOPSERVICES)
69 #if HAVE(QT5)
70 #include <QStandardPaths>
71 #else
72 #include <QDesktopServices>
73 #endif
74 #include <QtNetwork/QNetworkDiskCache>
75 #endif
76
77 const int gExitClickArea = 80;
78 QVector<int> LauncherWindow::m_zoomLevels;
79
80 static TestBrowserCookieJar* testBrowserCookieJarInstance()
81 {
82     static TestBrowserCookieJar* cookieJar = new TestBrowserCookieJar(qApp);
83     return cookieJar;
84 }
85
86 LauncherWindow::LauncherWindow(WindowOptions* data, QGraphicsScene* sharedScene)
87     : MainWindow()
88     , m_currentZoom(100)
89     , m_urlLoader(0)
90     , m_view(0)
91     , m_inspector(0)
92     , m_formatMenuAction(0)
93     , m_zoomAnimation(0)
94 #if !defined(QT_NO_FILEDIALOG) && !defined(QT_NO_MESSAGEBOX)
95     , m_reply(0)
96 #endif
97 #ifndef QT_NO_LINEEDIT
98     , m_findFlag(0)
99 #endif
100 {
101     if (data)
102         m_windowOptions = *data;
103
104     init();
105     if (sharedScene && data->useGraphicsView)
106         static_cast<QGraphicsView*>(m_view)->setScene(sharedScene);
107
108     createChrome();
109 #if !defined(QT_NO_FILEDIALOG) && !defined(QT_NO_MESSAGEBOX)
110     connect(page(), SIGNAL(downloadRequested(const QNetworkRequest&)), this, SLOT(downloadRequest(const QNetworkRequest&)));
111 #endif
112 }
113
114 LauncherWindow::~LauncherWindow()
115 {
116     delete m_urlLoader;
117 }
118
119 void LauncherWindow::init()
120 {
121     QSplitter* splitter = new QSplitter(Qt::Vertical, this);
122     setCentralWidget(splitter);
123
124     if (m_windowOptions.startMaximized)
125         setWindowState(windowState() | Qt::WindowMaximized);
126     else
127         resize(800, 600);
128
129     m_inspector = new WebInspector;
130 #ifndef QT_NO_PROPERTIES
131     if (!m_windowOptions.inspectorUrl.isEmpty())
132         m_inspector->setProperty("_q_inspectorUrl", m_windowOptions.inspectorUrl);
133 #endif
134     connect(this, SIGNAL(destroyed()), m_inspector, SLOT(deleteLater()));
135
136     // the zoom values are chosen to be like in Mozilla Firefox 3
137     if (!m_zoomLevels.count()) {
138         m_zoomLevels << 30 << 50 << 67 << 80 << 90;
139         m_zoomLevels << 100;
140         m_zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300;
141     }
142
143     initializeView();
144 }
145
146 void LauncherWindow::initializeView()
147 {
148     delete m_view;
149
150     m_inputUrl = addressUrl();
151     QUrl url = page()->mainFrame()->url();
152     setPage(new WebPage(this));
153     setDiskCache(m_windowOptions.useDiskCache);
154     setUseDiskCookies(m_windowOptions.useDiskCookies);
155
156     // We reuse the same cookieJar on multiple QNAMs, which is OK.
157     QObject* cookieJarParent = testBrowserCookieJarInstance()->parent();
158     page()->networkAccessManager()->setCookieJar(testBrowserCookieJarInstance());
159     testBrowserCookieJarInstance()->setParent(cookieJarParent);
160
161     QSplitter* splitter = static_cast<QSplitter*>(centralWidget());
162
163     if (!m_windowOptions.useGraphicsView) {
164         WebViewTraditional* view = new WebViewTraditional(splitter);
165         view->setPage(page());
166
167         view->installEventFilter(this);
168
169         m_view = view;
170     } else {
171         WebViewGraphicsBased* view = new WebViewGraphicsBased(splitter);
172         m_view = view;
173 #ifndef QT_NO_OPENGL
174         toggleQGLWidgetViewport(m_windowOptions.useQGLWidgetViewport);
175 #endif
176         view->setPage(page());
177
178         connect(view, SIGNAL(currentFPSUpdated(int)), this, SLOT(updateFPS(int)));
179
180         view->installEventFilter(this);
181         // The implementation of QAbstractScrollArea::eventFilter makes us need
182         // to install the event filter also on the viewport of a QGraphicsView.
183         view->viewport()->installEventFilter(this);
184     }
185
186     m_touchMocking = false;
187
188     connect(page(), SIGNAL(loadStarted()), this, SLOT(loadStarted()));
189     connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
190     connect(page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
191             this, SLOT(showLinkHover(const QString&, const QString&)));
192     connect(this, SIGNAL(enteredFullScreenMode(bool)), this, SLOT(toggleFullScreenMode(bool)));
193
194     if (m_windowOptions.printLoadedUrls)
195         connect(page()->mainFrame(), SIGNAL(urlChanged(QUrl)), this, SLOT(printURL(QUrl)));
196
197     applyPrefs();
198
199     splitter->addWidget(m_inspector);
200     m_inspector->setPage(page());
201     m_inspector->hide();
202
203     if (m_windowOptions.remoteInspectorPort)
204         page()->setProperty("_q_webInspectorServerPort", m_windowOptions.remoteInspectorPort);
205
206     if (url.isValid())
207         page()->mainFrame()->load(url);
208     else  {
209         setAddressUrl(m_inputUrl);
210         m_inputUrl = QString();
211     }
212 }
213
214 void LauncherWindow::applyPrefs()
215 {
216     QWebSettings* settings = page()->settings();
217     settings->setAttribute(QWebSettings::AcceleratedCompositingEnabled, m_windowOptions.useCompositing);
218     settings->setAttribute(QWebSettings::TiledBackingStoreEnabled, m_windowOptions.useTiledBackingStore);
219     settings->setAttribute(QWebSettings::FrameFlatteningEnabled, m_windowOptions.useFrameFlattening);
220     settings->setAttribute(QWebSettings::WebGLEnabled, m_windowOptions.useWebGL);
221
222     if (!isGraphicsBased())
223         return;
224
225     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
226     view->setViewportUpdateMode(m_windowOptions.viewportUpdateMode);
227     view->setFrameRateMeasurementEnabled(m_windowOptions.showFrameRate);
228     view->setItemCacheMode(m_windowOptions.cacheWebView ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
229
230     if (m_windowOptions.resizesToContents)
231         toggleResizesToContents(m_windowOptions.resizesToContents);
232 }
233
234 void LauncherWindow::createChrome()
235 {
236 #ifndef QT_NO_SHORTCUT
237     QMenu* fileMenu = menuBar()->addMenu("&File");
238     fileMenu->addAction("New Window", this, SLOT(newWindow()), QKeySequence::New);
239     fileMenu->addAction(tr("Open File..."), this, SLOT(openFile()), QKeySequence::Open);
240     fileMenu->addAction(tr("Open Location..."), this, SLOT(openLocation()), QKeySequence(Qt::CTRL | Qt::Key_L));
241     fileMenu->addAction("Close Window", this, SLOT(close()), QKeySequence::Close);
242     fileMenu->addSeparator();
243     fileMenu->addAction("Take Screen Shot...", this, SLOT(screenshot()));
244 #ifndef QT_NO_PRINTER
245     fileMenu->addAction(tr("Print..."), this, SLOT(print()), QKeySequence::Print);
246 #endif
247     fileMenu->addSeparator();
248     fileMenu->addAction("Quit", QApplication::instance(), SLOT(closeAllWindows()), QKeySequence(Qt::CTRL | Qt::Key_Q));
249
250     QMenu* editMenu = menuBar()->addMenu("&Edit");
251     editMenu->addAction(page()->action(QWebPage::Undo));
252     editMenu->addAction(page()->action(QWebPage::Redo));
253     editMenu->addSeparator();
254     editMenu->addAction(page()->action(QWebPage::Cut));
255     editMenu->addAction(page()->action(QWebPage::Copy));
256     editMenu->addAction(page()->action(QWebPage::Paste));
257     editMenu->addSeparator();
258 #ifndef QT_NO_LINEEDIT
259     editMenu->addAction("&Find", this, SLOT(showFindBar()), QKeySequence(Qt::CTRL | Qt::Key_F));
260     editMenu->addSeparator();
261 #endif
262     QAction* setEditable = editMenu->addAction("Set Editable", this, SLOT(setEditable(bool)));
263     setEditable->setCheckable(true);
264
265     editMenu->addAction("Clear Cookies", this, SLOT(clearCookies()));
266
267     QMenu* viewMenu = menuBar()->addMenu("&View");
268     viewMenu->addAction(page()->action(QWebPage::Stop));
269     viewMenu->addAction(page()->action(QWebPage::Reload));
270     viewMenu->addSeparator();
271     QAction* zoomIn = viewMenu->addAction("Zoom &In", this, SLOT(zoomIn()));
272     QAction* zoomOut = viewMenu->addAction("Zoom &Out", this, SLOT(zoomOut()));
273     QAction* resetZoom = viewMenu->addAction("Reset Zoom", this, SLOT(resetZoom()));
274     QAction* zoomTextOnly = viewMenu->addAction("Zoom Text Only", this, SLOT(toggleZoomTextOnly(bool)));
275     zoomTextOnly->setCheckable(true);
276     zoomTextOnly->setChecked(false);
277     viewMenu->addSeparator();
278     viewMenu->addAction("Dump HTML", this, SLOT(dumpHtml()));
279     // viewMenu->addAction("Dump plugins", this, SLOT(dumpPlugins()));
280
281     zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
282     zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
283     resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
284
285     QMenu* formatMenu = new QMenu("F&ormat", this);
286     m_formatMenuAction = menuBar()->addMenu(formatMenu);
287     m_formatMenuAction->setVisible(false);
288     formatMenu->addAction(page()->action(QWebPage::ToggleBold));
289     formatMenu->addAction(page()->action(QWebPage::ToggleItalic));
290     formatMenu->addAction(page()->action(QWebPage::ToggleUnderline));
291     QMenu* writingMenu = formatMenu->addMenu(tr("Writing Direction"));
292     writingMenu->addAction(page()->action(QWebPage::SetTextDirectionDefault));
293     writingMenu->addAction(page()->action(QWebPage::SetTextDirectionLeftToRight));
294     writingMenu->addAction(page()->action(QWebPage::SetTextDirectionRightToLeft));
295
296     QMenu* windowMenu = menuBar()->addMenu("&Window");
297     QAction* toggleFullScreen = windowMenu->addAction("Toggle FullScreen", this, SIGNAL(enteredFullScreenMode(bool)));
298     toggleFullScreen->setShortcut(Qt::Key_F11);
299     toggleFullScreen->setCheckable(true);
300     toggleFullScreen->setChecked(false);
301     // When exit fullscreen mode by clicking on the exit area (bottom right corner) we must
302     // uncheck the Toggle FullScreen action.
303     toggleFullScreen->connect(this, SIGNAL(enteredFullScreenMode(bool)), SLOT(setChecked(bool)));
304
305     QWebSettings* settings = page()->settings();
306
307     QMenu* toolsMenu = menuBar()->addMenu("&Develop");
308     QMenu* graphicsViewMenu = toolsMenu->addMenu("QGraphicsView");
309     QAction* toggleGraphicsView = graphicsViewMenu->addAction("Toggle use of QGraphicsView", this, SLOT(toggleWebView(bool)));
310     toggleGraphicsView->setCheckable(true);
311     toggleGraphicsView->setChecked(isGraphicsBased());
312
313     QAction* toggleWebGL = toolsMenu->addAction("Toggle WebGL", this, SLOT(toggleWebGL(bool)));
314     toggleWebGL->setCheckable(true);
315     toggleWebGL->setChecked(settings->testAttribute(QWebSettings::WebGLEnabled));
316
317     QAction* spatialNavigationAction = toolsMenu->addAction("Toggle Spatial Navigation", this, SLOT(toggleSpatialNavigation(bool)));
318     spatialNavigationAction->setCheckable(true);
319     spatialNavigationAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_S));
320
321     QAction* toggleFrameFlattening = toolsMenu->addAction("Toggle Frame Flattening", this, SLOT(toggleFrameFlattening(bool)));
322     toggleFrameFlattening->setCheckable(true);
323     toggleFrameFlattening->setChecked(settings->testAttribute(QWebSettings::FrameFlatteningEnabled));
324
325     QAction* touchMockAction = toolsMenu->addAction("Toggle touch mocking", this, SLOT(setTouchMocking(bool)));
326     touchMockAction->setCheckable(true);
327     touchMockAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_T));
328
329     toolsMenu->addSeparator();
330
331     QAction* toggleLocalStorage = toolsMenu->addAction("Enable Local Storage", this, SLOT(toggleLocalStorage(bool)));
332     toggleLocalStorage->setCheckable(true);
333     toggleLocalStorage->setChecked(m_windowOptions.useLocalStorage);
334
335     QAction* toggleOfflineStorageDatabase = toolsMenu->addAction("Enable Offline Storage Database", this, SLOT(toggleOfflineStorageDatabase(bool)));
336     toggleOfflineStorageDatabase->setCheckable(true);
337     toggleOfflineStorageDatabase->setChecked(m_windowOptions.useOfflineStorageDatabase);
338
339     QAction* toggleOfflineWebApplicationCache = toolsMenu->addAction("Enable Offline Web Application Cache", this, SLOT(toggleOfflineWebApplicationCache(bool)));
340     toggleOfflineWebApplicationCache->setCheckable(true);
341     toggleOfflineWebApplicationCache->setChecked(m_windowOptions.useOfflineWebApplicationCache);
342
343     QAction* offlineStorageDefaultQuotaAction = toolsMenu->addAction("Set Offline Storage Default Quota Size", this, SLOT(setOfflineStorageDefaultQuota()));
344     offlineStorageDefaultQuotaAction->setCheckable(true);
345     offlineStorageDefaultQuotaAction->setChecked(m_windowOptions.offlineStorageDefaultQuotaSize);
346
347     toolsMenu->addSeparator();
348
349     QAction* userAgentAction = toolsMenu->addAction("Change User Agent", this, SLOT(showUserAgentDialog()));
350     userAgentAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_U));
351
352     toolsMenu->addAction("Select Elements...", this, SLOT(selectElements()));
353
354     QAction* showInspectorAction = toolsMenu->addAction("Show Web Inspector", m_inspector, SLOT(setVisible(bool)), QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_I));
355     showInspectorAction->setCheckable(true);
356     showInspectorAction->connect(m_inspector, SIGNAL(visibleChanged(bool)), SLOT(setChecked(bool)));
357     toolsMenu->addSeparator();
358     toolsMenu->addAction("Load URLs from file", this, SLOT(loadURLListFromFile()));
359
360     // GraphicsView sub menu.
361     QAction* toggleAcceleratedCompositing = graphicsViewMenu->addAction("Toggle Accelerated Compositing", this, SLOT(toggleAcceleratedCompositing(bool)));
362     toggleAcceleratedCompositing->setCheckable(true);
363     toggleAcceleratedCompositing->setChecked(settings->testAttribute(QWebSettings::AcceleratedCompositingEnabled));
364     toggleAcceleratedCompositing->setEnabled(isGraphicsBased());
365     toggleAcceleratedCompositing->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
366
367     QAction* toggleResizesToContents = graphicsViewMenu->addAction("Toggle Resizes To Contents Mode", this, SLOT(toggleResizesToContents(bool)));
368     toggleResizesToContents->setCheckable(true);
369     toggleResizesToContents->setChecked(m_windowOptions.resizesToContents);
370     toggleResizesToContents->setEnabled(isGraphicsBased());
371     toggleResizesToContents->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
372
373     QAction* toggleTiledBackingStore = graphicsViewMenu->addAction("Toggle Tiled Backing Store", this, SLOT(toggleTiledBackingStore(bool)));
374     toggleTiledBackingStore->setCheckable(true);
375     toggleTiledBackingStore->setChecked(m_windowOptions.useTiledBackingStore);
376     toggleTiledBackingStore->setEnabled(isGraphicsBased());
377     toggleTiledBackingStore->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
378
379 #ifndef QT_NO_OPENGL
380     QAction* toggleQGLWidgetViewport = graphicsViewMenu->addAction("Toggle use of QGLWidget Viewport", this, SLOT(toggleQGLWidgetViewport(bool)));
381     toggleQGLWidgetViewport->setCheckable(true);
382     toggleQGLWidgetViewport->setChecked(m_windowOptions.useQGLWidgetViewport);
383     toggleQGLWidgetViewport->setEnabled(isGraphicsBased());
384     toggleQGLWidgetViewport->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
385 #endif
386
387     QMenu* viewportUpdateMenu = graphicsViewMenu->addMenu("Change Viewport Update Mode");
388     viewportUpdateMenu->setEnabled(isGraphicsBased());
389     viewportUpdateMenu->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
390
391     QAction* fullUpdate = viewportUpdateMenu->addAction("FullViewportUpdate");
392     fullUpdate->setCheckable(true);
393     fullUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::FullViewportUpdate) ? true : false);
394
395     QAction* minimalUpdate = viewportUpdateMenu->addAction("MinimalViewportUpdate");
396     minimalUpdate->setCheckable(true);
397     minimalUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::MinimalViewportUpdate) ? true : false);
398
399     QAction* smartUpdate = viewportUpdateMenu->addAction("SmartViewportUpdate");
400     smartUpdate->setCheckable(true);
401     smartUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::SmartViewportUpdate) ? true : false);
402
403     QAction* boundingRectUpdate = viewportUpdateMenu->addAction("BoundingRectViewportUpdate");
404     boundingRectUpdate->setCheckable(true);
405     boundingRectUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) ? true : false);
406
407     QAction* noUpdate = viewportUpdateMenu->addAction("NoViewportUpdate");
408     noUpdate->setCheckable(true);
409     noUpdate->setChecked((m_windowOptions.viewportUpdateMode == QGraphicsView::NoViewportUpdate) ? true : false);
410
411     QSignalMapper* signalMapper = new QSignalMapper(viewportUpdateMenu);
412     signalMapper->setMapping(fullUpdate, QGraphicsView::FullViewportUpdate);
413     signalMapper->setMapping(minimalUpdate, QGraphicsView::MinimalViewportUpdate);
414     signalMapper->setMapping(smartUpdate, QGraphicsView::SmartViewportUpdate);
415     signalMapper->setMapping(boundingRectUpdate, QGraphicsView::BoundingRectViewportUpdate);
416     signalMapper->setMapping(noUpdate, QGraphicsView::NoViewportUpdate);
417
418     connect(fullUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
419     connect(minimalUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
420     connect(smartUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
421     connect(boundingRectUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
422     connect(noUpdate, SIGNAL(triggered()), signalMapper, SLOT(map()));
423
424     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(changeViewportUpdateMode(int)));
425
426     QActionGroup* viewportUpdateModeActions = new QActionGroup(viewportUpdateMenu);
427     viewportUpdateModeActions->addAction(fullUpdate);
428     viewportUpdateModeActions->addAction(minimalUpdate);
429     viewportUpdateModeActions->addAction(smartUpdate);
430     viewportUpdateModeActions->addAction(boundingRectUpdate);
431     viewportUpdateModeActions->addAction(noUpdate);
432
433     graphicsViewMenu->addSeparator();
434
435     QAction* flipAnimated = graphicsViewMenu->addAction("Animated Flip");
436     flipAnimated->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
437     flipAnimated->setEnabled(isGraphicsBased());
438     connect(flipAnimated, SIGNAL(triggered()), SLOT(animatedFlip()));
439
440     QAction* flipYAnimated = graphicsViewMenu->addAction("Animated Y-Flip");
441     flipYAnimated->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
442     flipYAnimated->setEnabled(isGraphicsBased());
443     connect(flipYAnimated, SIGNAL(triggered()), SLOT(animatedYFlip()));
444
445     QAction* cloneWindow = graphicsViewMenu->addAction("Clone Window", this, SLOT(cloneWindow()));
446     cloneWindow->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
447     cloneWindow->setEnabled(isGraphicsBased());
448
449     graphicsViewMenu->addSeparator();
450
451     QAction* showFPS = graphicsViewMenu->addAction("Show FPS", this, SLOT(showFPS(bool)));
452     showFPS->setCheckable(true);
453     showFPS->setEnabled(isGraphicsBased());
454     showFPS->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
455     showFPS->setChecked(m_windowOptions.showFrameRate);
456
457     QMenu* settingsMenu = menuBar()->addMenu("&Settings");
458
459 #if !defined(QT_NO_NETWORKDISKCACHE) && !defined(QT_NO_DESKTOPSERVICES)
460     QAction* toggleDiskCache = settingsMenu->addAction("Use Disk Cache", this, SLOT(setDiskCache(bool)));
461     toggleDiskCache->setCheckable(true);
462     toggleDiskCache->setChecked(m_windowOptions.useDiskCache);
463 #endif
464
465     QAction* toggleAutoLoadImages = settingsMenu->addAction("Disable Auto Load Images", this, SLOT(toggleAutoLoadImages(bool)));
466     toggleAutoLoadImages->setCheckable(true);
467     toggleAutoLoadImages->setChecked(false);
468
469     QAction* togglePlugins = settingsMenu->addAction("Disable Plugins", this, SLOT(togglePlugins(bool)));
470     togglePlugins->setCheckable(true);
471     togglePlugins->setChecked(false);
472
473     QAction* toggleInterruptingJavaScripteEnabled = settingsMenu->addAction("Enable interrupting js scripts", this, SLOT(toggleInterruptingJavaScriptEnabled(bool)));
474     toggleInterruptingJavaScripteEnabled->setCheckable(true);
475     toggleInterruptingJavaScripteEnabled->setChecked(false);
476
477     QAction* toggleJavascriptCanOpenWindows = settingsMenu->addAction("Enable js popup windows", this, SLOT(toggleJavascriptCanOpenWindows(bool)));
478     toggleJavascriptCanOpenWindows->setCheckable(true);
479     toggleJavascriptCanOpenWindows->setChecked(false);
480
481     QAction* toggleUseDiskCookies = settingsMenu->addAction("Save Cookies on Disk", this, SLOT(setUseDiskCookies(bool)));
482     toggleUseDiskCookies->setCheckable(true);
483     toggleUseDiskCookies->setChecked(m_windowOptions.useDiskCookies);
484
485 #ifndef QT_NO_LINEEDIT
486     m_findBar = new QToolBar("Find", this);
487     addToolBar(Qt::BottomToolBarArea, m_findBar);
488
489     QToolButton* findClose = new QToolButton(m_findBar);
490     findClose->setText("X");
491     m_lineEdit = new QLineEdit(m_findBar);
492     m_lineEdit->setMaximumWidth(200);
493     QToolButton* findPrevious = new QToolButton(m_findBar);
494     findPrevious->setArrowType(Qt::LeftArrow);
495     QToolButton* findNext = new QToolButton(m_findBar);
496     findNext->setArrowType(Qt::RightArrow);
497     QCheckBox* findCaseSensitive = new QCheckBox("Case Sensitive", m_findBar);
498     QCheckBox* findWrapAround = new QCheckBox("Wrap Around", m_findBar);
499     QCheckBox* findHighLightAll = new QCheckBox("HighLight All", m_findBar);
500
501     QSignalMapper* findSignalMapper = new QSignalMapper(m_findBar);
502     findSignalMapper->setMapping(m_lineEdit, s_findNormalFlag);
503     findSignalMapper->setMapping(findPrevious, QWebPage::FindBackward);
504     findSignalMapper->setMapping(findNext, s_findNormalFlag);
505     findSignalMapper->setMapping(findCaseSensitive, QWebPage::FindCaseSensitively);
506     findSignalMapper->setMapping(findWrapAround, QWebPage::FindWrapsAroundDocument);
507     findSignalMapper->setMapping(findHighLightAll, QWebPage::HighlightAllOccurrences);
508
509     connect(findClose, SIGNAL(clicked()), this, SLOT(showFindBar()));
510     connect(m_lineEdit, SIGNAL(textChanged(const QString &)), findSignalMapper, SLOT(map()));
511     connect(findPrevious, SIGNAL(pressed()), findSignalMapper, SLOT(map()));
512     connect(findNext, SIGNAL(pressed()), findSignalMapper, SLOT(map()));
513     connect(findCaseSensitive, SIGNAL(stateChanged(int)), findSignalMapper, SLOT(map()));
514     connect(findWrapAround, SIGNAL(stateChanged(int)), findSignalMapper, SLOT(map()));
515     connect(findHighLightAll, SIGNAL(stateChanged(int)), findSignalMapper, SLOT(map()));
516
517     connect(findSignalMapper, SIGNAL(mapped(int)), this, SLOT(find(int)));
518
519     m_findBar->addWidget(findClose);
520     m_findBar->addWidget(m_lineEdit);
521     m_findBar->addWidget(findPrevious);
522     m_findBar->addWidget(findNext);
523     m_findBar->addWidget(findCaseSensitive);
524     m_findBar->addWidget(findWrapAround);
525     m_findBar->addWidget(findHighLightAll);
526     m_findBar->setMovable(false);
527     m_findBar->setVisible(false);
528 #endif
529 #endif
530 }
531
532 bool LauncherWindow::isGraphicsBased() const
533 {
534     return bool(qobject_cast<QGraphicsView*>(m_view));
535 }
536
537 void LauncherWindow::sendTouchEvent()
538 {
539     if (m_touchPoints.isEmpty())
540         return;
541
542     QEvent::Type type = QEvent::TouchUpdate;
543     if (m_touchPoints.size() == 1) {
544         if (m_touchPoints[0].state() == Qt::TouchPointReleased)
545             type = QEvent::TouchEnd;
546         else if (m_touchPoints[0].state() == Qt::TouchPointPressed)
547             type = QEvent::TouchBegin;
548     }
549
550     QTouchEvent touchEv(type);
551     touchEv.setTouchPoints(m_touchPoints);
552     QCoreApplication::sendEvent(page(), &touchEv);
553
554     // After sending the event, remove all touchpoints that were released
555     if (m_touchPoints[0].state() == Qt::TouchPointReleased)
556         m_touchPoints.removeAt(0);
557     if (m_touchPoints.size() > 1 && m_touchPoints[1].state() == Qt::TouchPointReleased)
558         m_touchPoints.removeAt(1);
559 }
560
561 bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
562 {
563     // If click pos is the bottom right corner (square with size defined by gExitClickArea)
564     // and the window is on FullScreen, the window must return to its original state.
565     if (event->type() == QEvent::MouseButtonRelease) {
566         QMouseEvent* ev = static_cast<QMouseEvent*>(event);
567         if (windowState() == Qt::WindowFullScreen
568             && ev->pos().x() > (width() - gExitClickArea)
569             && ev->pos().y() > (height() - gExitClickArea)) {
570
571             emit enteredFullScreenMode(false);
572         }
573     }
574
575     if (!m_touchMocking)
576         return QObject::eventFilter(obj, event);
577
578     if (event->type() == QEvent::MouseButtonPress
579         || event->type() == QEvent::MouseButtonRelease
580         || event->type() == QEvent::MouseButtonDblClick
581         || event->type() == QEvent::MouseMove) {
582
583         QMouseEvent* ev = static_cast<QMouseEvent*>(event);
584         if (ev->type() == QEvent::MouseMove
585             && !(ev->buttons() & Qt::LeftButton))
586             return false;
587
588         QTouchEvent::TouchPoint touchPoint;
589         touchPoint.setState(Qt::TouchPointMoved);
590         if ((ev->type() == QEvent::MouseButtonPress
591              || ev->type() == QEvent::MouseButtonDblClick))
592             touchPoint.setState(Qt::TouchPointPressed);
593         else if (ev->type() == QEvent::MouseButtonRelease)
594             touchPoint.setState(Qt::TouchPointReleased);
595
596         touchPoint.setId(0);
597         touchPoint.setScreenPos(ev->globalPos());
598         touchPoint.setPos(ev->pos());
599         touchPoint.setPressure(1);
600
601         // If the point already exists, update it. Otherwise create it.
602         if (m_touchPoints.size() > 0 && !m_touchPoints[0].id())
603             m_touchPoints[0] = touchPoint;
604         else if (m_touchPoints.size() > 1 && !m_touchPoints[1].id())
605             m_touchPoints[1] = touchPoint;
606         else
607             m_touchPoints.append(touchPoint);
608
609         sendTouchEvent();
610     } else if (event->type() == QEvent::KeyPress
611         && static_cast<QKeyEvent*>(event)->key() == Qt::Key_F
612         && static_cast<QKeyEvent*>(event)->modifiers() == Qt::ControlModifier) {
613
614         // If the keyboard point is already pressed, release it.
615         // Otherwise create it and append to m_touchPoints.
616         if (m_touchPoints.size() > 0 && m_touchPoints[0].id() == 1) {
617             m_touchPoints[0].setState(Qt::TouchPointReleased);
618             sendTouchEvent();
619         } else if (m_touchPoints.size() > 1 && m_touchPoints[1].id() == 1) {
620             m_touchPoints[1].setState(Qt::TouchPointReleased);
621             sendTouchEvent();
622         } else {
623             QTouchEvent::TouchPoint touchPoint;
624             touchPoint.setState(Qt::TouchPointPressed);
625             touchPoint.setId(1);
626             touchPoint.setScreenPos(QCursor::pos());
627             touchPoint.setPos(m_view->mapFromGlobal(QCursor::pos()));
628             touchPoint.setPressure(1);
629             m_touchPoints.append(touchPoint);
630             sendTouchEvent();
631
632             // After sending the event, change the touchpoint state to stationary
633             m_touchPoints.last().setState(Qt::TouchPointStationary);
634         }
635     }
636
637     return false;
638 }
639
640 void LauncherWindow::loadStarted()
641 {
642     m_view->setFocus(Qt::OtherFocusReason);
643 }
644
645 void LauncherWindow::loadFinished()
646 {
647     QUrl url = page()->mainFrame()->url();
648     addCompleterEntry(url);
649     if (m_inputUrl.isEmpty())
650         setAddressUrl(url.toString(QUrl::RemoveUserInfo));
651     else {
652         setAddressUrl(m_inputUrl);
653         m_inputUrl = QString();
654     }
655 }
656
657 void LauncherWindow::showLinkHover(const QString &link, const QString &toolTip)
658 {
659     statusBar()->showMessage(link);
660 #ifndef QT_NO_TOOLTIP
661     if (!toolTip.isEmpty())
662         QToolTip::showText(QCursor::pos(), toolTip);
663 #endif
664 }
665
666 void LauncherWindow::zoomAnimationFinished()
667 {
668     if (!isGraphicsBased())
669         return;
670     QGraphicsWebView* view = static_cast<WebViewGraphicsBased*>(m_view)->graphicsWebView();
671     view->setTiledBackingStoreFrozen(false);
672 }
673
674 void LauncherWindow::applyZoom()
675 {
676 #ifndef QT_NO_ANIMATION
677     if (isGraphicsBased() && page()->settings()->testAttribute(QWebSettings::TiledBackingStoreEnabled)) {
678         QGraphicsWebView* view = static_cast<WebViewGraphicsBased*>(m_view)->graphicsWebView();
679         view->setTiledBackingStoreFrozen(true);
680         if (!m_zoomAnimation) {
681             m_zoomAnimation = new QPropertyAnimation(view, "scale");
682             m_zoomAnimation->setStartValue(view->scale());
683             connect(m_zoomAnimation, SIGNAL(finished()), this, SLOT(zoomAnimationFinished()));
684         } else {
685             m_zoomAnimation->stop();
686             m_zoomAnimation->setStartValue(m_zoomAnimation->currentValue());
687         }
688
689         m_zoomAnimation->setDuration(300);
690         m_zoomAnimation->setEndValue(qreal(m_currentZoom) / 100.);
691         m_zoomAnimation->start();
692         return;
693     }
694 #endif
695     page()->mainFrame()->setZoomFactor(qreal(m_currentZoom) / 100.0);
696 }
697
698 void LauncherWindow::zoomIn()
699 {
700     int i = m_zoomLevels.indexOf(m_currentZoom);
701     Q_ASSERT(i >= 0);
702     if (i < m_zoomLevels.count() - 1)
703         m_currentZoom = m_zoomLevels[i + 1];
704
705     applyZoom();
706 }
707
708 void LauncherWindow::zoomOut()
709 {
710     int i = m_zoomLevels.indexOf(m_currentZoom);
711     Q_ASSERT(i >= 0);
712     if (i > 0)
713         m_currentZoom = m_zoomLevels[i - 1];
714
715     applyZoom();
716 }
717
718 void LauncherWindow::resetZoom()
719 {
720     m_currentZoom = 100;
721     applyZoom();
722 }
723
724 void LauncherWindow::toggleZoomTextOnly(bool b)
725 {
726     page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, b);
727 }
728
729 void LauncherWindow::print()
730 {
731 #if !defined(QT_NO_PRINTER)
732     QPrintPreviewDialog dlg(this);
733     connect(&dlg, SIGNAL(paintRequested(QPrinter*)),
734             page()->mainFrame(), SLOT(print(QPrinter*)));
735     dlg.exec();
736 #endif
737 }
738
739 void LauncherWindow::screenshot()
740 {
741     QPixmap pixmap = QPixmap::grabWidget(m_view);
742     QLabel* label = 0;
743     label = new QLabel;
744     label->setAttribute(Qt::WA_DeleteOnClose);
745     label->setWindowTitle("Screenshot - Preview");
746     label->setPixmap(pixmap);
747     label->show();
748
749 #ifndef QT_NO_FILEDIALOG
750     QString fileName = QFileDialog::getSaveFileName(label, "Screenshot");
751     if (!fileName.isEmpty()) {
752         pixmap.save(fileName, "png");
753         if (label)
754             label->setWindowTitle(QString("Screenshot - Saved at %1").arg(fileName));
755     }
756 #endif
757
758 #ifndef QT_NO_OPENGL
759     toggleQGLWidgetViewport(m_windowOptions.useQGLWidgetViewport);
760 #endif
761 }
762
763 void LauncherWindow::setEditable(bool on)
764 {
765     page()->setContentEditable(on);
766 #ifndef QT_NO_SHORTCUT
767     m_formatMenuAction->setVisible(on);
768 #endif
769 }
770
771 /*
772 void LauncherWindow::dumpPlugins() {
773     QList<QWebPluginInfo> plugins = QWebSettings::pluginDatabase()->plugins();
774     foreach (const QWebPluginInfo plugin, plugins) {
775         qDebug() << "Plugin:" << plugin.name();
776         foreach (const QWebPluginInfo::MimeType mime, plugin.mimeTypes()) {
777             qDebug() << "   " << mime.name;
778         }
779     }
780 }
781 */
782
783 void LauncherWindow::dumpHtml()
784 {
785     qDebug() << "HTML: " << page()->mainFrame()->toHtml();
786 }
787
788 void LauncherWindow::selectElements()
789 {
790 #ifndef QT_NO_INPUTDIALOG
791     bool ok;
792     QString str = QInputDialog::getText(this, "Select elements", "Choose elements",
793                                         QLineEdit::Normal, "a", &ok);
794
795     if (ok && !str.isEmpty()) {
796         QWebElementCollection result =  page()->mainFrame()->findAllElements(str);
797         foreach (QWebElement e, result)
798             e.setStyleProperty("background-color", "yellow");
799         statusBar()->showMessage(QString("%1 element(s) selected").arg(result.count()), 5000);
800     }
801 #endif
802 }
803
804 void LauncherWindow::setDiskCache(bool enable)
805 {
806 #if !defined(QT_NO_NETWORKDISKCACHE) && !defined(QT_NO_DESKTOPSERVICES)
807     m_windowOptions.useDiskCache = enable;
808     QNetworkDiskCache* cache = 0;
809     if (enable) {
810         cache = new QNetworkDiskCache();
811 #if HAVE(QT5)
812         QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
813 #else
814         QString cacheLocation = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
815 #endif
816         cache->setCacheDirectory(cacheLocation);
817     }
818     page()->networkAccessManager()->setCache(cache);
819 #endif
820 }
821
822 void LauncherWindow::setTouchMocking(bool on)
823 {
824     m_touchMocking = on;
825 }
826
827 void LauncherWindow::toggleWebView(bool graphicsBased)
828 {
829     m_windowOptions.useGraphicsView = graphicsBased;
830     initializeView();
831 #ifndef QT_NO_SHORTCUT
832     menuBar()->clear();
833 #endif
834     createChrome();
835 }
836
837 void LauncherWindow::toggleAcceleratedCompositing(bool toggle)
838 {
839     m_windowOptions.useCompositing = toggle;
840     page()->settings()->setAttribute(QWebSettings::AcceleratedCompositingEnabled, toggle);
841 }
842
843 void LauncherWindow::toggleTiledBackingStore(bool toggle)
844 {
845     page()->settings()->setAttribute(QWebSettings::TiledBackingStoreEnabled, toggle);
846 }
847
848 void LauncherWindow::toggleResizesToContents(bool toggle)
849 {
850     m_windowOptions.resizesToContents = toggle;
851     static_cast<WebViewGraphicsBased*>(m_view)->setResizesToContents(toggle);
852 }
853
854 void LauncherWindow::toggleWebGL(bool toggle)
855 {
856     m_windowOptions.useWebGL = toggle;
857     page()->settings()->setAttribute(QWebSettings::WebGLEnabled, toggle);
858 }
859
860 void LauncherWindow::animatedFlip()
861 {
862     qobject_cast<WebViewGraphicsBased*>(m_view)->animatedFlip();
863 }
864
865 void LauncherWindow::animatedYFlip()
866 {
867     qobject_cast<WebViewGraphicsBased*>(m_view)->animatedYFlip();
868 }
869 void LauncherWindow::toggleSpatialNavigation(bool b)
870 {
871     page()->settings()->setAttribute(QWebSettings::SpatialNavigationEnabled, b);
872 }
873
874 void LauncherWindow::toggleFullScreenMode(bool enable)
875 {
876     bool alreadyEnabled = windowState() & Qt::WindowFullScreen;
877     if (enable ^ alreadyEnabled)
878         setWindowState(windowState() ^ Qt::WindowFullScreen);
879 }
880
881 void LauncherWindow::toggleFrameFlattening(bool toggle)
882 {
883     m_windowOptions.useFrameFlattening = toggle;
884     page()->settings()->setAttribute(QWebSettings::FrameFlatteningEnabled, toggle);
885 }
886
887 void LauncherWindow::toggleInterruptingJavaScriptEnabled(bool enable)
888 {
889     page()->setInterruptingJavaScriptEnabled(enable);
890 }
891
892 void LauncherWindow::toggleJavascriptCanOpenWindows(bool enable)
893 {
894     page()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, enable);
895 }
896
897 void LauncherWindow::setUseDiskCookies(bool enable)
898 {
899     testBrowserCookieJarInstance()->setDiskStorageEnabled(enable);
900 }
901
902 void LauncherWindow::clearCookies()
903 {
904     testBrowserCookieJarInstance()->reset();
905 }
906
907 void LauncherWindow::toggleAutoLoadImages(bool enable)
908 {
909     page()->settings()->setAttribute(QWebSettings::AutoLoadImages, !enable);
910 }
911
912 void LauncherWindow::togglePlugins(bool enable)
913 {
914     page()->settings()->setAttribute(QWebSettings::PluginsEnabled, !enable);
915 }
916
917 #ifndef QT_NO_OPENGL
918 void LauncherWindow::toggleQGLWidgetViewport(bool enable)
919 {
920     if (!isGraphicsBased())
921         return;
922
923     m_windowOptions.useQGLWidgetViewport = enable;
924     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
925
926     view->setViewport(enable ? new QGLWidget() : 0);
927 }
928 #endif
929
930 void LauncherWindow::changeViewportUpdateMode(int mode)
931 {
932     m_windowOptions.viewportUpdateMode = QGraphicsView::ViewportUpdateMode(mode);
933
934     if (!isGraphicsBased())
935         return;
936
937     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
938     view->setViewportUpdateMode(m_windowOptions.viewportUpdateMode);
939 }
940
941 void LauncherWindow::showFPS(bool enable)
942 {
943     if (!isGraphicsBased())
944         return;
945
946     m_windowOptions.showFrameRate = enable;
947     WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
948     view->setFrameRateMeasurementEnabled(enable);
949
950     if (!enable)
951         statusBar()->clearMessage();
952 }
953
954 void LauncherWindow::showUserAgentDialog()
955 {
956     QStringList items;
957     QFile file(":/useragentlist.txt");
958     if (file.open(QIODevice::ReadOnly)) {
959          while (!file.atEnd())
960             items << file.readLine().trimmed();
961         file.close();
962     }
963
964     QSettings settings;
965     QString customUserAgent = settings.value("CustomUserAgent").toString();
966     if (!items.contains(customUserAgent) && !customUserAgent.isEmpty())
967         items << customUserAgent;
968
969     QDialog* dialog = new QDialog(this);
970     dialog->resize(size().width() * 0.7, dialog->size().height());
971     dialog->setWindowTitle("Change User Agent");
972
973     QVBoxLayout* layout = new QVBoxLayout(dialog);
974     dialog->setLayout(layout);
975
976 #ifndef QT_NO_COMBOBOX
977     QComboBox* combo = new QComboBox(dialog);
978     combo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
979     combo->setEditable(true);
980     combo->insertItems(0, items);
981     layout->addWidget(combo);
982
983     int index = combo->findText(page()->userAgentForUrl(QUrl()));
984     combo->setCurrentIndex(index);
985 #endif
986
987     QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
988             | QDialogButtonBox::Cancel, Qt::Horizontal, dialog);
989     connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
990     connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
991     layout->addWidget(buttonBox);
992
993 #ifndef QT_NO_COMBOBOX
994     if (dialog->exec() && !combo->currentText().isEmpty()) {
995         page()->setUserAgent(combo->currentText());
996         if (!items.contains(combo->currentText()))
997             settings.setValue("CustomUserAgent", combo->currentText());
998     }
999 #endif
1000
1001     delete dialog;
1002 }
1003
1004 void LauncherWindow::loadURLListFromFile()
1005 {
1006     QString selectedFile;
1007 #ifndef QT_NO_FILEDIALOG
1008     selectedFile = QFileDialog::getOpenFileName(this, tr("Load URL list from file")
1009                                                        , QString(), tr("Text Files (*.txt);;All Files (*)"));
1010 #endif
1011     if (selectedFile.isEmpty())
1012        return;
1013
1014     m_urlLoader = new UrlLoader(this->page()->mainFrame(), selectedFile, 0, 0);
1015     m_urlLoader->loadNext();
1016 }
1017
1018 void LauncherWindow::printURL(const QUrl& url)
1019 {
1020     QTextStream output(stdout);
1021     output << "Loaded: " << url.toString() << endl;
1022 }
1023
1024 #if !defined(QT_NO_FILEDIALOG) && !defined(QT_NO_MESSAGEBOX)
1025 void LauncherWindow::downloadRequest(const QNetworkRequest &request)
1026 {
1027     QNetworkAccessManager* manager = new QNetworkAccessManager(this);
1028     m_reply = manager->get(request);
1029     connect(m_reply, SIGNAL(finished()), this, SLOT(fileDownloadFinished()));
1030 }
1031
1032 void LauncherWindow::fileDownloadFinished()
1033 {
1034     QFileInfo fileInf(m_reply->request().url().toString());
1035     QString requestFileName = QDir::homePath() + "/" + fileInf.fileName();
1036     QString fileName = QFileDialog::getSaveFileName(this, "Save as...", requestFileName, "All Files (*)");
1037
1038     if (fileName.isEmpty())
1039         return;
1040     if (m_reply->error() != QNetworkReply::NoError)
1041         QMessageBox::critical(this, QString("Download"), QString("Download failed."));
1042     else {
1043         QFile file(fileName);
1044         file.open(QIODevice::WriteOnly);
1045         file.write(m_reply->readAll());
1046         file.close();
1047         QMessageBox::information(this, QString("Download"), fileName + QString(" downloaded successfully."));
1048     }
1049 }
1050 #endif
1051
1052 void LauncherWindow::updateFPS(int fps)
1053 {
1054     QString fpsStatusText = QString("Current FPS: %1").arg(fps);
1055
1056     statusBar()->showMessage(fpsStatusText);
1057 }
1058
1059 void LauncherWindow::toggleLocalStorage(bool toggle)
1060 {
1061     m_windowOptions.useLocalStorage = toggle;
1062     page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, toggle);
1063 }
1064
1065 void LauncherWindow::toggleOfflineStorageDatabase(bool toggle)
1066 {
1067     m_windowOptions.useOfflineStorageDatabase = toggle;
1068     page()->settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, toggle);
1069 }
1070
1071 void LauncherWindow::toggleOfflineWebApplicationCache(bool toggle)
1072 {
1073     m_windowOptions.useOfflineWebApplicationCache = toggle;
1074     page()->settings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, toggle);
1075 }
1076
1077 void LauncherWindow::setOfflineStorageDefaultQuota()
1078 {
1079     // For command line execution, quota size is taken from command line.   
1080     if (m_windowOptions.offlineStorageDefaultQuotaSize)
1081         page()->settings()->setOfflineStorageDefaultQuota(m_windowOptions.offlineStorageDefaultQuotaSize);
1082     else {
1083 #ifndef QT_NO_INPUTDIALOG
1084         bool ok;
1085         // Maximum size is set to 25 * 1024 * 1024.
1086         int quotaSize = QInputDialog::getInt(this, "Offline Storage Default Quota Size" , "Quota Size", 0, 0, 26214400, 1, &ok);
1087         if (ok) 
1088             page()->settings()->setOfflineStorageDefaultQuota(quotaSize);
1089 #endif
1090     }
1091 }
1092
1093 LauncherWindow* LauncherWindow::newWindow()
1094 {
1095     LauncherWindow* mw = new LauncherWindow(&m_windowOptions);
1096     mw->show();
1097     return mw;
1098 }
1099
1100 LauncherWindow* LauncherWindow::cloneWindow()
1101 {
1102     LauncherWindow* mw = new LauncherWindow(&m_windowOptions, qobject_cast<QGraphicsView*>(m_view)->scene());
1103     mw->show();
1104     return mw;
1105 }
1106
1107 #ifndef QT_NO_LINEEDIT
1108 void LauncherWindow::showFindBar()
1109 {
1110     if (!m_findBar->isVisible()) {
1111         m_findBar->setVisible(true);
1112         m_lineEdit->setText(page()->selectedText());
1113         m_lineEdit->setFocus(Qt::PopupFocusReason);
1114     } else {
1115         m_findBar->setVisible(false);
1116         page()->findText("", QWebPage::HighlightAllOccurrences);
1117     }
1118 }
1119
1120 void LauncherWindow::find(int mode = s_findNormalFlag)
1121 {
1122     QPalette palette;
1123     bool found;
1124     palette.setColor(m_lineEdit->backgroundRole(), Qt::white);
1125     page()->findText("", QFlag(QWebPage::HighlightAllOccurrences));
1126
1127     m_findFlag = m_findFlag ^ mode;
1128     if (mode == s_findNormalFlag || mode == QWebPage::FindBackward) {
1129         found = page()->findText(m_lineEdit->text(), QFlag(m_findFlag & ~QWebPage::HighlightAllOccurrences));
1130         m_findFlag = m_findFlag ^ mode;
1131
1132         if (found || m_lineEdit->text().isEmpty())
1133             m_lineEdit->setPalette(palette);
1134         else {
1135             palette.setColor(m_lineEdit->backgroundRole(), QColor(255, 0, 0, 127));
1136             m_lineEdit->setPalette(palette);
1137         }
1138     }
1139
1140     if (m_findFlag & QWebPage::HighlightAllOccurrences)
1141         page()->findText(m_lineEdit->text(), QFlag(m_findFlag));
1142 }
1143 #endif