launcherwindow.cpp 46 KB

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