/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebpage.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 4219 lines · 2641 code · 403 blank · 1175 comment · 401 complexity · a3c2af90db056dba79fb76b251779af7 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. Copyright (C) 2008, 2009 Nokia Corporation and/or its subsidiary(-ies)
  3. Copyright (C) 2007 Staikos Computing Services Inc.
  4. Copyright (C) 2007 Apple Inc.
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public License
  14. along with this library; see the file COPYING.LIB. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. Boston, MA 02110-1301, USA.
  17. */
  18. #include "config.h"
  19. #include "qwebpage.h"
  20. #include "qwebview.h"
  21. #include "qwebframe.h"
  22. #include "qwebpage_p.h"
  23. #include "qwebframe_p.h"
  24. #include "qwebhistory.h"
  25. #include "qwebhistory_p.h"
  26. #include "qwebinspector.h"
  27. #include "qwebinspector_p.h"
  28. #include "qwebsettings.h"
  29. #include "qwebkitplatformplugin.h"
  30. #include "qwebkitversion.h"
  31. #include "CSSComputedStyleDeclaration.h"
  32. #include "CSSParser.h"
  33. #include "ApplicationCacheStorage.h"
  34. #include "BackForwardListImpl.h"
  35. #include "MemoryCache.h"
  36. #include "Chrome.h"
  37. #include "ChromeClientQt.h"
  38. #include "ClientRect.h"
  39. #include "ContextMenu.h"
  40. #include "ContextMenuClientQt.h"
  41. #include "ContextMenuController.h"
  42. #include "DeviceMotionClientQt.h"
  43. #include "DeviceOrientationClientQt.h"
  44. #include "DocumentLoader.h"
  45. #include "DragClientQt.h"
  46. #include "DragController.h"
  47. #include "DragData.h"
  48. #include "Editor.h"
  49. #include "EditorClientQt.h"
  50. #include "FocusController.h"
  51. #include "FormState.h"
  52. #include "Frame.h"
  53. #include "FrameLoadRequest.h"
  54. #include "FrameLoader.h"
  55. #include "FrameLoader.h"
  56. #include "FrameLoaderClientQt.h"
  57. #include "FrameTree.h"
  58. #include "FrameView.h"
  59. #if ENABLE(CLIENT_BASED_GEOLOCATION)
  60. #include "GeolocationClientMock.h"
  61. #include "GeolocationClientQt.h"
  62. #endif // CLIENT_BASED_GEOLOCATION
  63. #include "GeolocationPermissionClientQt.h"
  64. #include "HTMLFormElement.h"
  65. #include "HTMLFrameOwnerElement.h"
  66. #include "HTMLInputElement.h"
  67. #include "HTMLNames.h"
  68. #include "HashMap.h"
  69. #include "HitTestResult.h"
  70. #include "Image.h"
  71. #include "InspectorClientQt.h"
  72. #include "InspectorController.h"
  73. #include "InspectorServerQt.h"
  74. #include "KURL.h"
  75. #include "LocalizedStrings.h"
  76. #include "Logging.h"
  77. #include "MIMETypeRegistry.h"
  78. #include "NavigationAction.h"
  79. #include "NetworkingContext.h"
  80. #include "NodeList.h"
  81. #include "NotificationPresenterClientQt.h"
  82. #include "NotImplemented.h"
  83. #include "Page.h"
  84. #include "PageClientQt.h"
  85. #include "PageGroup.h"
  86. #include "Pasteboard.h"
  87. #include "PlatformKeyboardEvent.h"
  88. #include "PlatformTouchEvent.h"
  89. #include "PlatformWheelEvent.h"
  90. #include "PluginDatabase.h"
  91. #include "PluginDatabase.h"
  92. #include "PluginPackage.h"
  93. #include "ProgressTracker.h"
  94. #include "QtPlatformPlugin.h"
  95. #include "RefPtr.h"
  96. #include "RenderTextControl.h"
  97. #include "SchemeRegistry.h"
  98. #include "Scrollbar.h"
  99. #include "SecurityOrigin.h"
  100. #include "Settings.h"
  101. #if defined Q_OS_WIN32
  102. #include "SystemInfo.h"
  103. #endif // Q_OS_WIN32
  104. #include "TextIterator.h"
  105. #include "WebPlatformStrategies.h"
  106. #if USE(QTKIT)
  107. #include "WebSystemInterface.h"
  108. #endif
  109. #include "WindowFeatures.h"
  110. #include "WorkerThread.h"
  111. #include "runtime/InitializeThreading.h"
  112. #include "wtf/Threading.h"
  113. #include <QApplication>
  114. #include <QBasicTimer>
  115. #include <QBitArray>
  116. #include <QDebug>
  117. #include <QDesktopWidget>
  118. #include <QDragEnterEvent>
  119. #include <QDragLeaveEvent>
  120. #include <QDragMoveEvent>
  121. #include <QDropEvent>
  122. #include <QFileDialog>
  123. #include <QHttpRequestHeader>
  124. #include <QInputDialog>
  125. #include <QMessageBox>
  126. #include <QNetworkProxy>
  127. #include <QUndoStack>
  128. #include <QUrl>
  129. #include <QPainter>
  130. #include <QClipboard>
  131. #include <QSslSocket>
  132. #include <QStyle>
  133. #include <QSysInfo>
  134. #include <QTextCharFormat>
  135. #include <QTextDocument>
  136. #include <QTouchEvent>
  137. #include <QNetworkAccessManager>
  138. #include <QNetworkRequest>
  139. #if defined(Q_WS_X11)
  140. #include <QX11Info>
  141. #endif
  142. #if USE(QT_MOBILITY_SYSTEMINFO)
  143. #include <qsysteminfo.h>
  144. #endif
  145. using namespace WebCore;
  146. // from text/qfont.cpp
  147. QT_BEGIN_NAMESPACE
  148. extern Q_GUI_EXPORT int qt_defaultDpi();
  149. QT_END_NAMESPACE
  150. bool QWebPagePrivate::drtRun = false;
  151. // Lookup table mapping QWebPage::WebActions to the associated Editor commands
  152. static const char* editorCommandWebActions[] =
  153. {
  154. 0, // OpenLink,
  155. 0, // OpenLinkInNewWindow,
  156. 0, // OpenFrameInNewWindow,
  157. 0, // DownloadLinkToDisk,
  158. 0, // CopyLinkToClipboard,
  159. 0, // OpenImageInNewWindow,
  160. 0, // DownloadImageToDisk,
  161. 0, // CopyImageToClipboard,
  162. 0, // Back,
  163. 0, // Forward,
  164. 0, // Stop,
  165. 0, // Reload,
  166. "Cut", // Cut,
  167. "Copy", // Copy,
  168. "Paste", // Paste,
  169. "Undo", // Undo,
  170. "Redo", // Redo,
  171. "MoveForward", // MoveToNextChar,
  172. "MoveBackward", // MoveToPreviousChar,
  173. "MoveWordForward", // MoveToNextWord,
  174. "MoveWordBackward", // MoveToPreviousWord,
  175. "MoveDown", // MoveToNextLine,
  176. "MoveUp", // MoveToPreviousLine,
  177. "MoveToBeginningOfLine", // MoveToStartOfLine,
  178. "MoveToEndOfLine", // MoveToEndOfLine,
  179. "MoveToBeginningOfParagraph", // MoveToStartOfBlock,
  180. "MoveToEndOfParagraph", // MoveToEndOfBlock,
  181. "MoveToBeginningOfDocument", // MoveToStartOfDocument,
  182. "MoveToEndOfDocument", // MoveToEndOfDocument,
  183. "MoveForwardAndModifySelection", // SelectNextChar,
  184. "MoveBackwardAndModifySelection", // SelectPreviousChar,
  185. "MoveWordForwardAndModifySelection", // SelectNextWord,
  186. "MoveWordBackwardAndModifySelection", // SelectPreviousWord,
  187. "MoveDownAndModifySelection", // SelectNextLine,
  188. "MoveUpAndModifySelection", // SelectPreviousLine,
  189. "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine,
  190. "MoveToEndOfLineAndModifySelection", // SelectEndOfLine,
  191. "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock,
  192. "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock,
  193. "MoveToBeginningOfDocumentAndModifySelection", //SelectStartOfDocument,
  194. "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument,
  195. "DeleteWordBackward", // DeleteStartOfWord,
  196. "DeleteWordForward", // DeleteEndOfWord,
  197. 0, // SetTextDirectionDefault,
  198. 0, // SetTextDirectionLeftToRight,
  199. 0, // SetTextDirectionRightToLeft,
  200. "ToggleBold", // ToggleBold,
  201. "ToggleItalic", // ToggleItalic,
  202. "ToggleUnderline", // ToggleUnderline,
  203. 0, // InspectElement,
  204. "InsertNewline", // InsertParagraphSeparator
  205. "InsertLineBreak", // InsertLineSeparator
  206. "SelectAll", // SelectAll
  207. 0, // ReloadAndBypassCache,
  208. "PasteAndMatchStyle", // PasteAndMatchStyle
  209. "RemoveFormat", // RemoveFormat
  210. "Strikethrough", // ToggleStrikethrough,
  211. "Subscript", // ToggleSubscript
  212. "Superscript", // ToggleSuperscript
  213. "InsertUnorderedList", // InsertUnorderedList
  214. "InsertOrderedList", // InsertOrderedList
  215. "Indent", // Indent
  216. "Outdent", // Outdent,
  217. "AlignCenter", // AlignCenter,
  218. "AlignJustified", // AlignJustified,
  219. "AlignLeft", // AlignLeft,
  220. "AlignRight", // AlignRight,
  221. 0, // StopScheduledPageRefresh,
  222. 0, // CopyImageUrlToClipboard,
  223. 0 // WebActionCount
  224. };
  225. // Lookup the appropriate editor command to use for WebAction \a action
  226. const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action)
  227. {
  228. if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*))))
  229. return editorCommandWebActions[action];
  230. return 0;
  231. }
  232. static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
  233. {
  234. unsigned result = 0;
  235. if (actions & Qt::CopyAction)
  236. result |= DragOperationCopy;
  237. // DragOperationgeneric represents InternetExplorer's equivalent of Move operation,
  238. // hence it should be considered as "move"
  239. if (actions & Qt::MoveAction)
  240. result |= (DragOperationMove | DragOperationGeneric);
  241. if (actions & Qt::LinkAction)
  242. result |= DragOperationLink;
  243. if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
  244. result = DragOperationEvery;
  245. return (DragOperation)result;
  246. }
  247. static inline Qt::DropAction dragOpToDropAction(unsigned actions)
  248. {
  249. Qt::DropAction result = Qt::IgnoreAction;
  250. if (actions & DragOperationCopy)
  251. result = Qt::CopyAction;
  252. else if (actions & DragOperationMove)
  253. result = Qt::MoveAction;
  254. // DragOperationgeneric represents InternetExplorer's equivalent of Move operation,
  255. // hence it should be considered as "move"
  256. else if (actions & DragOperationGeneric)
  257. result = Qt::MoveAction;
  258. else if (actions & DragOperationLink)
  259. result = Qt::LinkAction;
  260. return result;
  261. }
  262. QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
  263. : q(qq)
  264. , page(0)
  265. , mainFrame(0)
  266. #ifndef QT_NO_UNDOSTACK
  267. , undoStack(0)
  268. #endif
  269. , insideOpenCall(false)
  270. , m_totalBytes(0)
  271. , m_bytesReceived()
  272. , clickCausedFocus(false)
  273. , networkManager(0)
  274. , forwardUnsupportedContent(false)
  275. , smartInsertDeleteEnabled(true)
  276. , selectTrailingWhitespaceEnabled(false)
  277. , linkPolicy(QWebPage::DontDelegateLinks)
  278. , viewportSize(QSize(0, 0))
  279. , pixelRatio(1)
  280. #ifndef QT_NO_CONTEXTMENU
  281. , currentContextMenu(0)
  282. #endif
  283. , settings(0)
  284. , useFixedLayout(false)
  285. , pluginFactory(0)
  286. , inspectorFrontend(0)
  287. , inspector(0)
  288. , inspectorIsInternalOnly(false)
  289. , m_lastDropAction(Qt::IgnoreAction)
  290. {
  291. WebCore::InitializeLoggingChannelsIfNecessary();
  292. ScriptController::initializeThreading();
  293. WTF::initializeMainThread();
  294. WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
  295. WebPlatformStrategies::initialize();
  296. #if USE(QTKIT)
  297. InitWebCoreSystemInterface();
  298. #endif
  299. Page::PageClients pageClients;
  300. pageClients.chromeClient = new ChromeClientQt(q);
  301. pageClients.contextMenuClient = new ContextMenuClientQt();
  302. pageClients.editorClient = new EditorClientQt(q);
  303. pageClients.dragClient = new DragClientQt(q);
  304. pageClients.inspectorClient = new InspectorClientQt(q);
  305. #if ENABLE(DEVICE_ORIENTATION)
  306. pageClients.deviceOrientationClient = new DeviceOrientationClientQt(q);
  307. pageClients.deviceMotionClient = new DeviceMotionClientQt(q);
  308. #endif
  309. #if ENABLE(CLIENT_BASED_GEOLOCATION)
  310. if (QWebPagePrivate::drtRun)
  311. pageClients.geolocationClient = new GeolocationClientMock();
  312. else
  313. pageClients.geolocationClient = new GeolocationClientQt(q);
  314. #endif
  315. page = new Page(pageClients);
  316. // By default each page is put into their own unique page group, which affects popup windows
  317. // and visited links. Page groups (per process only) is a feature making it possible to use
  318. // separate settings for each group, so that for instance an integrated browser/email reader
  319. // can use different settings for displaying HTML pages and HTML email. To make QtWebKit work
  320. // as expected out of the box, we use a default group similar to what other ports are doing.
  321. page->setGroupName("Default Group");
  322. #if ENABLE(CLIENT_BASED_GEOLOCATION)
  323. // In case running in DumpRenderTree mode set the controller to mock provider.
  324. if (QWebPagePrivate::drtRun)
  325. static_cast<GeolocationClientMock*>(pageClients.geolocationClient)->setController(page->geolocationController());
  326. #endif
  327. settings = new QWebSettings(page->settings());
  328. history.d = new QWebHistoryPrivate(static_cast<WebCore::BackForwardListImpl*>(page->backForwardList()));
  329. memset(actions, 0, sizeof(actions));
  330. PageGroup::setShouldTrackVisitedLinks(true);
  331. #if ENABLE(NOTIFICATIONS)
  332. NotificationPresenterClientQt::notificationPresenter()->addClient();
  333. #endif
  334. }
  335. QWebPagePrivate::~QWebPagePrivate()
  336. {
  337. if (inspector && inspectorIsInternalOnly) {
  338. // Since we have to delete an internal inspector,
  339. // call setInspector(0) directly to prevent potential crashes
  340. setInspector(0);
  341. }
  342. #ifndef QT_NO_CONTEXTMENU
  343. delete currentContextMenu;
  344. #endif
  345. #ifndef QT_NO_UNDOSTACK
  346. delete undoStack;
  347. #endif
  348. delete settings;
  349. delete page;
  350. if (inspector)
  351. inspector->setPage(0);
  352. #if ENABLE(NOTIFICATIONS)
  353. NotificationPresenterClientQt::notificationPresenter()->removeClient();
  354. #endif
  355. }
  356. WebCore::ViewportArguments QWebPagePrivate::viewportArguments()
  357. {
  358. return page ? page->viewportArguments() : WebCore::ViewportArguments();
  359. }
  360. WebCore::Page* QWebPagePrivate::core(const QWebPage* page)
  361. {
  362. return page->d->page;
  363. }
  364. QWebPagePrivate* QWebPagePrivate::priv(QWebPage* page)
  365. {
  366. return page->d;
  367. }
  368. bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
  369. {
  370. if (insideOpenCall
  371. && frame == mainFrame)
  372. return true;
  373. return q->acceptNavigationRequest(frame, request, type);
  374. }
  375. void QWebPagePrivate::createMainFrame()
  376. {
  377. if (!mainFrame) {
  378. QWebFrameData frameData(page);
  379. mainFrame = new QWebFrame(q, &frameData);
  380. emit q->frameCreated(mainFrame);
  381. }
  382. }
  383. static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
  384. {
  385. switch (action) {
  386. case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
  387. case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
  388. case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
  389. case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
  390. case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
  391. case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
  392. case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
  393. case WebCore::ContextMenuItemTagCopyImageUrlToClipboard: return QWebPage::CopyImageUrlToClipboard;
  394. case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
  395. case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
  396. case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back;
  397. case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward;
  398. case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
  399. case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
  400. case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
  401. case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
  402. case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
  403. case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
  404. case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
  405. case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
  406. case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
  407. case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
  408. case WebCore::ContextMenuItemTagSelectAll: return QWebPage::SelectAll;
  409. #if ENABLE(INSPECTOR)
  410. case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
  411. #endif
  412. default: break;
  413. }
  414. return QWebPage::NoWebAction;
  415. }
  416. #ifndef QT_NO_CONTEXTMENU
  417. QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu,
  418. const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions)
  419. {
  420. if (!client || !webcoreMenu)
  421. return 0;
  422. QMenu* menu = new QMenu(client->ownerWidget());
  423. for (int i = 0; i < items->count(); ++i) {
  424. const ContextMenuItem &item = items->at(i);
  425. switch (item.type()) {
  426. case WebCore::CheckableActionType: /* fall through */
  427. case WebCore::ActionType: {
  428. QWebPage::WebAction action = webActionForContextMenuAction(item.action());
  429. QAction *a = q->action(action);
  430. if (a) {
  431. ContextMenuItem it(item);
  432. page->contextMenuController()->checkOrEnableIfNeeded(it);
  433. PlatformMenuItemDescription desc = it.releasePlatformDescription();
  434. a->setEnabled(desc.enabled);
  435. a->setChecked(desc.checked);
  436. a->setCheckable(item.type() == WebCore::CheckableActionType);
  437. menu->addAction(a);
  438. visitedWebActions->setBit(action);
  439. }
  440. break;
  441. }
  442. case WebCore::SeparatorType:
  443. menu->addSeparator();
  444. break;
  445. case WebCore::SubmenuType: {
  446. QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions);
  447. bool anyEnabledAction = false;
  448. QList<QAction *> actions = subMenu->actions();
  449. for (int i = 0; i < actions.count(); ++i) {
  450. if (actions.at(i)->isVisible())
  451. anyEnabledAction |= actions.at(i)->isEnabled();
  452. }
  453. // don't show sub-menus with just disabled actions
  454. if (anyEnabledAction) {
  455. subMenu->setTitle(item.title());
  456. menu->addAction(subMenu->menuAction());
  457. } else
  458. delete subMenu;
  459. break;
  460. }
  461. }
  462. }
  463. return menu;
  464. }
  465. #endif // QT_NO_CONTEXTMENU
  466. #ifndef QT_NO_ACTION
  467. void QWebPagePrivate::_q_webActionTriggered(bool checked)
  468. {
  469. QAction *a = qobject_cast<QAction *>(q->sender());
  470. if (!a)
  471. return;
  472. QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
  473. q->triggerAction(action, checked);
  474. }
  475. #endif // QT_NO_ACTION
  476. void QWebPagePrivate::_q_cleanupLeakMessages()
  477. {
  478. #ifndef NDEBUG
  479. // Need this to make leak messages accurate.
  480. memoryCache()->setCapacities(0, 0, 0);
  481. #endif
  482. }
  483. void QWebPagePrivate::updateAction(QWebPage::WebAction action)
  484. {
  485. #ifdef QT_NO_ACTION
  486. Q_UNUSED(action)
  487. #else
  488. QAction *a = actions[action];
  489. if (!a || !mainFrame)
  490. return;
  491. WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
  492. WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
  493. bool enabled = a->isEnabled();
  494. bool checked = a->isChecked();
  495. switch (action) {
  496. case QWebPage::Back:
  497. enabled = page->canGoBackOrForward(-1);
  498. break;
  499. case QWebPage::Forward:
  500. enabled = page->canGoBackOrForward(1);
  501. break;
  502. case QWebPage::Stop:
  503. enabled = loader->isLoading();
  504. break;
  505. case QWebPage::Reload:
  506. case QWebPage::ReloadAndBypassCache:
  507. enabled = !loader->isLoading();
  508. break;
  509. #ifndef QT_NO_UNDOSTACK
  510. case QWebPage::Undo:
  511. case QWebPage::Redo:
  512. // those two are handled by QUndoStack
  513. break;
  514. #endif // QT_NO_UNDOSTACK
  515. case QWebPage::SelectAll: // editor command is always enabled
  516. break;
  517. case QWebPage::SetTextDirectionDefault:
  518. case QWebPage::SetTextDirectionLeftToRight:
  519. case QWebPage::SetTextDirectionRightToLeft:
  520. enabled = editor->canEdit();
  521. checked = false;
  522. break;
  523. default: {
  524. // see if it's an editor command
  525. const char* commandName = editorCommandForWebActions(action);
  526. // if it's an editor command, let it's logic determine state
  527. if (commandName) {
  528. Editor::Command command = editor->command(commandName);
  529. enabled = command.isEnabled();
  530. if (enabled)
  531. checked = command.state() != FalseTriState;
  532. else
  533. checked = false;
  534. }
  535. break;
  536. }
  537. }
  538. a->setEnabled(enabled);
  539. if (a->isCheckable())
  540. a->setChecked(checked);
  541. #endif // QT_NO_ACTION
  542. }
  543. void QWebPagePrivate::updateNavigationActions()
  544. {
  545. updateAction(QWebPage::Back);
  546. updateAction(QWebPage::Forward);
  547. updateAction(QWebPage::Stop);
  548. updateAction(QWebPage::Reload);
  549. updateAction(QWebPage::ReloadAndBypassCache);
  550. }
  551. void QWebPagePrivate::updateEditorActions()
  552. {
  553. updateAction(QWebPage::Cut);
  554. updateAction(QWebPage::Copy);
  555. updateAction(QWebPage::Paste);
  556. updateAction(QWebPage::MoveToNextChar);
  557. updateAction(QWebPage::MoveToPreviousChar);
  558. updateAction(QWebPage::MoveToNextWord);
  559. updateAction(QWebPage::MoveToPreviousWord);
  560. updateAction(QWebPage::MoveToNextLine);
  561. updateAction(QWebPage::MoveToPreviousLine);
  562. updateAction(QWebPage::MoveToStartOfLine);
  563. updateAction(QWebPage::MoveToEndOfLine);
  564. updateAction(QWebPage::MoveToStartOfBlock);
  565. updateAction(QWebPage::MoveToEndOfBlock);
  566. updateAction(QWebPage::MoveToStartOfDocument);
  567. updateAction(QWebPage::MoveToEndOfDocument);
  568. updateAction(QWebPage::SelectNextChar);
  569. updateAction(QWebPage::SelectPreviousChar);
  570. updateAction(QWebPage::SelectNextWord);
  571. updateAction(QWebPage::SelectPreviousWord);
  572. updateAction(QWebPage::SelectNextLine);
  573. updateAction(QWebPage::SelectPreviousLine);
  574. updateAction(QWebPage::SelectStartOfLine);
  575. updateAction(QWebPage::SelectEndOfLine);
  576. updateAction(QWebPage::SelectStartOfBlock);
  577. updateAction(QWebPage::SelectEndOfBlock);
  578. updateAction(QWebPage::SelectStartOfDocument);
  579. updateAction(QWebPage::SelectEndOfDocument);
  580. updateAction(QWebPage::DeleteStartOfWord);
  581. updateAction(QWebPage::DeleteEndOfWord);
  582. updateAction(QWebPage::SetTextDirectionDefault);
  583. updateAction(QWebPage::SetTextDirectionLeftToRight);
  584. updateAction(QWebPage::SetTextDirectionRightToLeft);
  585. updateAction(QWebPage::ToggleBold);
  586. updateAction(QWebPage::ToggleItalic);
  587. updateAction(QWebPage::ToggleUnderline);
  588. updateAction(QWebPage::InsertParagraphSeparator);
  589. updateAction(QWebPage::InsertLineSeparator);
  590. updateAction(QWebPage::PasteAndMatchStyle);
  591. updateAction(QWebPage::RemoveFormat);
  592. updateAction(QWebPage::ToggleStrikethrough);
  593. updateAction(QWebPage::ToggleSubscript);
  594. updateAction(QWebPage::ToggleSuperscript);
  595. updateAction(QWebPage::InsertUnorderedList);
  596. updateAction(QWebPage::InsertOrderedList);
  597. updateAction(QWebPage::Indent);
  598. updateAction(QWebPage::Outdent);
  599. updateAction(QWebPage::AlignCenter);
  600. updateAction(QWebPage::AlignJustified);
  601. updateAction(QWebPage::AlignLeft);
  602. updateAction(QWebPage::AlignRight);
  603. }
  604. void QWebPagePrivate::timerEvent(QTimerEvent *ev)
  605. {
  606. int timerId = ev->timerId();
  607. if (timerId == tripleClickTimer.timerId())
  608. tripleClickTimer.stop();
  609. else
  610. q->timerEvent(ev);
  611. }
  612. template<class T>
  613. void QWebPagePrivate::mouseMoveEvent(T* ev)
  614. {
  615. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  616. if (!frame->view())
  617. return;
  618. bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0));
  619. ev->setAccepted(accepted);
  620. }
  621. template<class T>
  622. void QWebPagePrivate::mousePressEvent(T* ev)
  623. {
  624. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  625. if (!frame->view())
  626. return;
  627. RefPtr<WebCore::Node> oldNode;
  628. Frame* focusedFrame = page->focusController()->focusedFrame();
  629. if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
  630. oldNode = focusedDocument->focusedNode();
  631. if (tripleClickTimer.isActive()
  632. && (ev->pos() - tripleClick).manhattanLength()
  633. < QApplication::startDragDistance()) {
  634. mouseTripleClickEvent(ev);
  635. return;
  636. }
  637. bool accepted = false;
  638. adjustPointForClicking(ev);
  639. PlatformMouseEvent mev(ev, 1);
  640. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  641. if (mev.button() != NoButton)
  642. accepted = frame->eventHandler()->handleMousePressEvent(mev);
  643. ev->setAccepted(accepted);
  644. RefPtr<WebCore::Node> newNode;
  645. focusedFrame = page->focusController()->focusedFrame();
  646. if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
  647. newNode = focusedDocument->focusedNode();
  648. if (newNode && oldNode != newNode)
  649. clickCausedFocus = true;
  650. }
  651. template<class T>
  652. void QWebPagePrivate::mouseDoubleClickEvent(T *ev)
  653. {
  654. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  655. if (!frame->view())
  656. return;
  657. bool accepted = false;
  658. PlatformMouseEvent mev(ev, 2);
  659. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  660. if (mev.button() != NoButton)
  661. accepted = frame->eventHandler()->handleMousePressEvent(mev);
  662. ev->setAccepted(accepted);
  663. tripleClickTimer.start(QApplication::doubleClickInterval(), q);
  664. tripleClick = QPointF(ev->pos()).toPoint();
  665. }
  666. template<class T>
  667. void QWebPagePrivate::mouseTripleClickEvent(T *ev)
  668. {
  669. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  670. if (!frame->view())
  671. return;
  672. bool accepted = false;
  673. PlatformMouseEvent mev(ev, 3);
  674. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  675. if (mev.button() != NoButton)
  676. accepted = frame->eventHandler()->handleMousePressEvent(mev);
  677. ev->setAccepted(accepted);
  678. }
  679. void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button)
  680. {
  681. #ifndef QT_NO_CLIPBOARD
  682. if (QApplication::clipboard()->supportsSelection()) {
  683. bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
  684. Pasteboard::generalPasteboard()->setSelectionMode(true);
  685. WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame();
  686. if (button == Qt::LeftButton) {
  687. if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) {
  688. Pasteboard::generalPasteboard()->writeSelection(focusFrame->editor()->selectedRange().get(), focusFrame->editor()->canSmartCopyOrDelete(), focusFrame);
  689. ev->setAccepted(true);
  690. }
  691. } else if (button == Qt::MidButton) {
  692. if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) {
  693. focusFrame->editor()->paste();
  694. ev->setAccepted(true);
  695. }
  696. }
  697. Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
  698. }
  699. #endif
  700. }
  701. template<class T>
  702. void QWebPagePrivate::mouseReleaseEvent(T *ev)
  703. {
  704. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  705. if (!frame->view())
  706. return;
  707. bool accepted = false;
  708. adjustPointForClicking(ev);
  709. PlatformMouseEvent mev(ev, 0);
  710. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  711. if (mev.button() != NoButton)
  712. accepted = frame->eventHandler()->handleMouseReleaseEvent(mev);
  713. ev->setAccepted(accepted);
  714. handleClipboard(ev, ev->button());
  715. handleSoftwareInputPanel(ev->button(), QPointF(ev->pos()).toPoint());
  716. }
  717. void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button, const QPoint& pos)
  718. {
  719. Frame* frame = page->focusController()->focusedFrame();
  720. if (!frame)
  721. return;
  722. if (client && client->inputMethodEnabled()
  723. && frame->document()->focusedNode()
  724. && button == Qt::LeftButton && qApp->autoSipEnabled()) {
  725. QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
  726. client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
  727. if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
  728. HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(frame->view()->windowToContents(pos), false);
  729. if (result.isContentEditable()) {
  730. QEvent event(QEvent::RequestSoftwareInputPanel);
  731. QApplication::sendEvent(client->ownerWidget(), &event);
  732. }
  733. }
  734. }
  735. clickCausedFocus = false;
  736. }
  737. #ifndef QT_NO_CONTEXTMENU
  738. void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos)
  739. {
  740. QMenu *menu = q->createStandardContextMenu();
  741. if (menu) {
  742. menu->exec(globalPos);
  743. delete menu;
  744. }
  745. }
  746. #endif // QT_NO_CONTEXTMENU
  747. /*!
  748. \since 4.5
  749. This function creates the standard context menu which is shown when
  750. the user clicks on the web page with the right mouse button. It is
  751. called from the default contextMenuEvent() handler. The popup menu's
  752. ownership is transferred to the caller.
  753. */
  754. QMenu *QWebPage::createStandardContextMenu()
  755. {
  756. #ifndef QT_NO_CONTEXTMENU
  757. QMenu *menu = d->currentContextMenu;
  758. d->currentContextMenu = 0;
  759. return menu;
  760. #else
  761. return 0;
  762. #endif
  763. }
  764. #ifndef QT_NO_WHEELEVENT
  765. template<class T>
  766. void QWebPagePrivate::wheelEvent(T *ev)
  767. {
  768. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  769. if (!frame->view())
  770. return;
  771. WebCore::PlatformWheelEvent pev(ev);
  772. bool accepted = frame->eventHandler()->handleWheelEvent(pev);
  773. ev->setAccepted(accepted);
  774. }
  775. #endif // QT_NO_WHEELEVENT
  776. #ifndef QT_NO_SHORTCUT
  777. QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event)
  778. {
  779. static struct {
  780. QKeySequence::StandardKey standardKey;
  781. QWebPage::WebAction action;
  782. } editorActions[] = {
  783. { QKeySequence::Cut, QWebPage::Cut },
  784. { QKeySequence::Copy, QWebPage::Copy },
  785. { QKeySequence::Paste, QWebPage::Paste },
  786. { QKeySequence::Undo, QWebPage::Undo },
  787. { QKeySequence::Redo, QWebPage::Redo },
  788. { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar },
  789. { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar },
  790. { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord },
  791. { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord },
  792. { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine },
  793. { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine },
  794. { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine },
  795. { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine },
  796. { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock },
  797. { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock },
  798. { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument },
  799. { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument },
  800. { QKeySequence::SelectNextChar, QWebPage::SelectNextChar },
  801. { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar },
  802. { QKeySequence::SelectNextWord, QWebPage::SelectNextWord },
  803. { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord },
  804. { QKeySequence::SelectNextLine, QWebPage::SelectNextLine },
  805. { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine },
  806. { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine },
  807. { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine },
  808. { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock },
  809. { QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock },
  810. { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument },
  811. { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument },
  812. { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord },
  813. { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord },
  814. { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator },
  815. { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator },
  816. { QKeySequence::SelectAll, QWebPage::SelectAll },
  817. { QKeySequence::UnknownKey, QWebPage::NoWebAction }
  818. };
  819. for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i)
  820. if (event == editorActions[i].standardKey)
  821. return editorActions[i].action;
  822. return QWebPage::NoWebAction;
  823. }
  824. #endif // QT_NO_SHORTCUT
  825. void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
  826. {
  827. bool handled = false;
  828. WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
  829. // we forward the key event to WebCore first to handle potential DOM
  830. // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent
  831. // to trigger editor commands via triggerAction().
  832. if (!handled)
  833. handled = frame->eventHandler()->keyEvent(ev);
  834. if (!handled) {
  835. handled = true;
  836. if (!handleScrolling(ev, frame)) {
  837. switch (ev->key()) {
  838. case Qt::Key_Back:
  839. q->triggerAction(QWebPage::Back);
  840. break;
  841. case Qt::Key_Forward:
  842. q->triggerAction(QWebPage::Forward);
  843. break;
  844. case Qt::Key_Stop:
  845. q->triggerAction(QWebPage::Stop);
  846. break;
  847. case Qt::Key_Refresh:
  848. q->triggerAction(QWebPage::Reload);
  849. break;
  850. case Qt::Key_Backspace:
  851. if (ev->modifiers() == Qt::ShiftModifier)
  852. q->triggerAction(QWebPage::Forward);
  853. else
  854. q->triggerAction(QWebPage::Back);
  855. break;
  856. default:
  857. handled = false;
  858. break;
  859. }
  860. }
  861. }
  862. ev->setAccepted(handled);
  863. }
  864. void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
  865. {
  866. if (ev->isAutoRepeat()) {
  867. ev->setAccepted(true);
  868. return;
  869. }
  870. WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
  871. bool handled = frame->eventHandler()->keyEvent(ev);
  872. ev->setAccepted(handled);
  873. }
  874. void QWebPagePrivate::focusInEvent(QFocusEvent*)
  875. {
  876. FocusController *focusController = page->focusController();
  877. focusController->setActive(true);
  878. focusController->setFocused(true);
  879. if (!focusController->focusedFrame())
  880. focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame));
  881. }
  882. void QWebPagePrivate::focusOutEvent(QFocusEvent*)
  883. {
  884. // only set the focused frame inactive so that we stop painting the caret
  885. // and the focus frame. But don't tell the focus controller so that upon
  886. // focusInEvent() we can re-activate the frame.
  887. FocusController *focusController = page->focusController();
  888. // Call setFocused first so that window.onblur doesn't get called twice
  889. focusController->setFocused(false);
  890. focusController->setActive(false);
  891. }
  892. template<class T>
  893. void QWebPagePrivate::dragEnterEvent(T* ev)
  894. {
  895. #ifndef QT_NO_DRAGANDDROP
  896. DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
  897. QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
  898. Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
  899. ev->setDropAction(action);
  900. ev->acceptProposedAction();
  901. #endif
  902. }
  903. template<class T>
  904. void QWebPagePrivate::dragLeaveEvent(T *ev)
  905. {
  906. #ifndef QT_NO_DRAGANDDROP
  907. DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
  908. page->dragController()->dragExited(&dragData);
  909. ev->accept();
  910. #endif
  911. }
  912. template<class T>
  913. void QWebPagePrivate::dragMoveEvent(T *ev)
  914. {
  915. #ifndef QT_NO_DRAGANDDROP
  916. DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
  917. QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
  918. m_lastDropAction = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
  919. ev->setDropAction(m_lastDropAction);
  920. if (m_lastDropAction != Qt::IgnoreAction)
  921. ev->accept();
  922. #endif
  923. }
  924. template<class T>
  925. void QWebPagePrivate::dropEvent(T *ev)
  926. {
  927. #ifndef QT_NO_DRAGANDDROP
  928. DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
  929. QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
  930. if (page->dragController()->performDrag(&dragData)) {
  931. ev->setDropAction(m_lastDropAction);
  932. ev->accept();
  933. }
  934. #endif
  935. }
  936. void QWebPagePrivate::leaveEvent(QEvent*)
  937. {
  938. // Fake a mouse move event just outside of the widget, since all
  939. // the interesting mouse-out behavior like invalidating scrollbars
  940. // is handled by the WebKit event handler's mouseMoved function.
  941. QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
  942. mouseMoveEvent(&fakeEvent);
  943. }
  944. /*!
  945. \property QWebPage::palette
  946. \brief the page's palette
  947. The base brush of the palette is used to draw the background of the main frame.
  948. By default, this property contains the application's default palette.
  949. */
  950. void QWebPage::setPalette(const QPalette &pal)
  951. {
  952. d->palette = pal;
  953. if (!d->mainFrame || !d->mainFrame->d->frame->view())
  954. return;
  955. QBrush brush = pal.brush(QPalette::Base);
  956. QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
  957. QWebFramePrivate::core(d->mainFrame)->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha());
  958. }
  959. QPalette QWebPage::palette() const
  960. {
  961. return d->palette;
  962. }
  963. void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
  964. {
  965. WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
  966. WebCore::Editor *editor = frame->editor();
  967. if (!editor->canEdit()) {
  968. ev->ignore();
  969. return;
  970. }
  971. Node* node = 0;
  972. if (frame->selection()->rootEditableElement())
  973. node = frame->selection()->rootEditableElement()->shadowAncestorNode();
  974. Vector<CompositionUnderline> underlines;
  975. bool hasSelection = false;
  976. for (int i = 0; i < ev->attributes().size(); ++i) {
  977. const QInputMethodEvent::Attribute& a = ev->attributes().at(i);
  978. switch (a.type) {
  979. case QInputMethodEvent::TextFormat: {
  980. QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat();
  981. QColor qcolor = textCharFormat.underlineColor();
  982. underlines.append(CompositionUnderline(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)), Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false));
  983. break;
  984. }
  985. case QInputMethodEvent::Cursor: {
  986. frame->selection()->setCaretVisible(a.length); //if length is 0 cursor is invisible
  987. if (a.length > 0) {
  988. RenderObject* caretRenderer = frame->selection()->caretRenderer();
  989. if (caretRenderer) {
  990. QColor qcolor = a.value.value<QColor>();
  991. caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())));
  992. }
  993. }
  994. break;
  995. }
  996. case QInputMethodEvent::Selection: {
  997. hasSelection = true;
  998. // A selection in the inputMethodEvent is always reflected in the visible text
  999. if (node)
  1000. setSelectionRange(node, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
  1001. if (!ev->preeditString().isEmpty())
  1002. editor->setComposition(ev->preeditString(), underlines, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
  1003. else {
  1004. // If we are in the middle of a composition, an empty pre-edit string and a selection of zero
  1005. // cancels the current composition
  1006. if (editor->hasComposition() && (a.start + a.length == 0))
  1007. editor->setComposition(QString(), underlines, 0, 0);
  1008. }
  1009. break;
  1010. }
  1011. default:
  1012. break;
  1013. }
  1014. }
  1015. if (node && ev->replacementLength() > 0) {
  1016. int cursorPos = frame->selection()->extent().offsetInContainerNode();
  1017. int start = cursorPos + ev->replacementStart();
  1018. setSelectionRange(node, start, start + ev->replacementLength());
  1019. // Commit regardless of whether commitString is empty, to get rid of selection.
  1020. editor->confirmComposition(ev->commitString());
  1021. } else if (!ev->commitString().isEmpty()) {
  1022. if (editor->hasComposition())
  1023. editor->confirmComposition(ev->commitString());
  1024. else
  1025. editor->insertText(ev->commitString(), 0);
  1026. } else if (!hasSelection && !ev->preeditString().isEmpty())
  1027. editor->setComposition(ev->preeditString(), underlines, 0, 0);
  1028. else if (ev->preeditString().isEmpty() && editor->hasComposition())
  1029. editor->confirmComposition(String());
  1030. ev->accept();
  1031. }
  1032. #ifndef QT_NO_PROPERTIES
  1033. typedef struct {
  1034. const char* name;
  1035. double deferredRepaintDelay;
  1036. double initialDeferredRepaintDelayDuringLoading;
  1037. double maxDeferredRepaintDelayDuringLoading;
  1038. double deferredRepaintDelayIncrementDuringLoading;
  1039. } QRepaintThrottlingPreset;
  1040. void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event)
  1041. {
  1042. if (event->propertyName() == "_q_viewMode") {
  1043. page->setViewMode(Page::stringToViewMode(q->property("_q_viewMode").toString()));
  1044. } else if (event->propertyName() == "_q_HTMLTokenizerChunkSize") {
  1045. int chunkSize = q->property("_q_HTMLTokenizerChunkSize").toInt();
  1046. q->handle()->page->setCustomHTMLTokenizerChunkSize(chunkSize);
  1047. } else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") {
  1048. double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble();
  1049. q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay);
  1050. } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") {
  1051. double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble();
  1052. FrameView::setRepaintThrottlingDeferredRepaintDelay(p);
  1053. } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") {
  1054. double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble();
  1055. FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p);
  1056. } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") {
  1057. double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble();
  1058. FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p);
  1059. } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") {
  1060. double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble();
  1061. FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p);
  1062. } else if (event->propertyName() == "_q_RepaintThrottlingPreset") {
  1063. static const QRepaintThrottlingPreset presets[] = {
  1064. { "NoThrottling", 0, 0, 0, 0 },
  1065. { "Legacy", 0.025, 0, 2.5, 0.5 },
  1066. { "Minimal", 0.01, 0, 1, 0.2 },
  1067. { "Medium", 0.025, 1, 5, 0.5 },
  1068. { "Heavy", 0.1, 2, 10, 1 }
  1069. };
  1070. QString p = q->property("_q_RepaintThrottlingPreset").toString();
  1071. for (size_t i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) {
  1072. if (p == QLatin1String(presets[i].name)) {
  1073. FrameView::setRepaintThrottlingDeferredRepaintDelay(
  1074. presets[i].deferredRepaintDelay);
  1075. FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(
  1076. presets[i].initialDeferredRepaintDelayDuringLoading);
  1077. FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(
  1078. presets[i].maxDeferredRepaintDelayDuringLoading);
  1079. FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(
  1080. presets[i].deferredRepaintDelayIncrementDuringLoading);
  1081. break;
  1082. }
  1083. }
  1084. }
  1085. #if ENABLE(TILED_BACKING_STORE)
  1086. else if (event->propertyName() == "_q_TiledBackingStoreTileSize") {
  1087. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1088. if (!frame->tiledBackingStore())
  1089. return;
  1090. QSize tileSize = q->property("_q_TiledBackingStoreTileSize").toSize();
  1091. frame->tiledBackingStore()->setTileSize(tileSize);
  1092. } else if (event->propertyName() == "_q_TiledBackingStoreTileCreationDelay") {
  1093. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1094. if (!frame->tiledBackingStore())
  1095. return;
  1096. int tileCreationDelay = q->property("_q_TiledBackingStoreTileCreationDelay").toInt();
  1097. frame->tiledBackingStore()->setTileCreationDelay(static_cast<double>(tileCreationDelay) / 1000.);
  1098. } else if (event->propertyName() == "_q_TiledBackingStoreKeepAreaMultiplier") {
  1099. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1100. if (!frame->tiledBackingStore())
  1101. return;
  1102. FloatSize keepMultiplier;
  1103. FloatSize coverMultiplier;
  1104. frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1105. QSizeF qSize = q->property("_q_TiledBackingStoreKeepAreaMultiplier").toSizeF();
  1106. keepMultiplier = FloatSize(qSize.width(), qSize.height());
  1107. frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1108. } else if (event->propertyName() == "_q_TiledBackingStoreCoverAreaMultiplier") {
  1109. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1110. if (!frame->tiledBackingStore())
  1111. return;
  1112. FloatSize keepMultiplier;
  1113. FloatSize coverMultiplier;
  1114. frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1115. QSizeF qSize = q->property("_q_TiledBackingStoreCoverAreaMultiplier").toSizeF();
  1116. coverMultiplier = FloatSize(qSize.width(), qSize.height());
  1117. frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1118. }
  1119. #endif
  1120. else if (event->propertyName() == "_q_webInspectorServerPort") {
  1121. InspectorServerQt* inspectorServer = InspectorServerQt::server();
  1122. inspectorServer->listen(inspectorServerPort());
  1123. } else if (event->propertyName() == "_q_deadDecodedDataDeletionInterval") {
  1124. double interval = q->property("_q_deadDecodedDataDeletionInterval").toDouble();
  1125. memoryCache()->setDeadDecodedDataDeletionInterval(interval);
  1126. }
  1127. }
  1128. #endif
  1129. void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event)
  1130. {
  1131. WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
  1132. WebCore::Editor* editor = frame->editor();
  1133. if (editor->canEdit()) {
  1134. if (event->modifiers() == Qt::NoModifier
  1135. || event->modifiers() == Qt::ShiftModifier
  1136. || event->modifiers() == Qt::KeypadModifier) {
  1137. if (event->key() < Qt::Key_Escape) {
  1138. event->accept();
  1139. } else {
  1140. switch (event->key()) {
  1141. case Qt::Key_Return:
  1142. case Qt::Key_Enter:
  1143. case Qt::Key_Delete:
  1144. case Qt::Key_Home:
  1145. case Qt::Key_End:
  1146. case Qt::Key_Backspace:
  1147. case Qt::Key_Left:
  1148. case Qt::Key_Right:
  1149. case Qt::Key_Up:
  1150. case Qt::Key_Down:
  1151. case Qt::Key_Tab:
  1152. event->accept();
  1153. default:
  1154. break;
  1155. }
  1156. }
  1157. }
  1158. #ifndef QT_NO_SHORTCUT
  1159. else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction)
  1160. event->accept();
  1161. #endif
  1162. }
  1163. }
  1164. bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame)
  1165. {
  1166. ScrollDirection direction;
  1167. ScrollGranularity granularity;
  1168. #ifndef QT_NO_SHORTCUT
  1169. if (ev == QKeySequence::MoveToNextPage
  1170. || (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) {
  1171. granularity = ScrollByPage;
  1172. direction = ScrollDown;
  1173. } else if (ev == QKeySequence::MoveToPreviousPage
  1174. || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) {
  1175. granularity = ScrollByPage;
  1176. direction = ScrollUp;
  1177. } else
  1178. #endif // QT_NO_SHORTCUT
  1179. if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier)
  1180. || ev->key() == Qt::Key_Home) {
  1181. granularity = ScrollByDocument;
  1182. direction = ScrollUp;
  1183. } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier)
  1184. || ev->key() == Qt::Key_End) {
  1185. granularity = ScrollByDocument;
  1186. direction = ScrollDown;
  1187. } else {
  1188. switch (ev->key()) {
  1189. case Qt::Key_Up:
  1190. granularity = ScrollByLine;
  1191. direction = ScrollUp;
  1192. break;
  1193. case Qt::Key_Down:
  1194. granularity = ScrollByLine;
  1195. direction = ScrollDown;
  1196. break;
  1197. case Qt::Key_Left:
  1198. granularity = ScrollByLine;
  1199. direction = ScrollLeft;
  1200. break;
  1201. case Qt::Key_Right:
  1202. granularity = ScrollByLine;
  1203. direction = ScrollRight;
  1204. break;
  1205. default:
  1206. return false;
  1207. }
  1208. }
  1209. return frame->eventHandler()->scrollRecursively(direction, granularity);
  1210. }
  1211. void QWebPagePrivate::adjustPointForClicking(QMouseEvent*)
  1212. {
  1213. notImplemented();
  1214. }
  1215. #if !defined(QT_NO_GRAPHICSVIEW)
  1216. void QWebPagePrivate::adjustPointForClicking(QGraphicsScene