|
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 |
|
6 This library is free software; you can redistribute it and/or |
|
7 modify it under the terms of the GNU Library General Public |
|
8 License as published by the Free Software Foundation; either |
|
9 version 2 of the License, or (at your option) any later version. |
|
10 |
|
11 This library is distributed in the hope that it will be useful, |
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 Library General Public License for more details. |
|
15 |
|
16 You should have received a copy of the GNU Library General Public License |
|
17 along with this library; see the file COPYING.LIB. If not, write to |
|
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
|
19 Boston, MA 02110-1301, USA. |
|
20 */ |
|
21 |
|
22 #include "config.h" |
|
23 #include "qwebpage.h" |
|
24 #include "qwebview.h" |
|
25 #include "qwebframe.h" |
|
26 #include "qwebpage_p.h" |
|
27 #include "qwebframe_p.h" |
|
28 #include "qwebhistory.h" |
|
29 #include "qwebhistory_p.h" |
|
30 #include "qwebinspector.h" |
|
31 #include "qwebinspector_p.h" |
|
32 #include "qwebsettings.h" |
|
33 #include "qwebkitversion.h" |
|
34 |
|
35 #include "Chrome.h" |
|
36 #include "ContextMenuController.h" |
|
37 #include "Frame.h" |
|
38 #include "FrameTree.h" |
|
39 #include "FrameLoader.h" |
|
40 #include "FrameLoaderClientQt.h" |
|
41 #include "FrameView.h" |
|
42 #include "FormState.h" |
|
43 #include "ApplicationCacheStorage.h" |
|
44 #include "ChromeClientQt.h" |
|
45 #include "ContextMenu.h" |
|
46 #include "ContextMenuClientQt.h" |
|
47 #include "DocumentLoader.h" |
|
48 #include "DragClientQt.h" |
|
49 #include "DragController.h" |
|
50 #include "DragData.h" |
|
51 #include "EditorClientQt.h" |
|
52 #include "SchemeRegistry.h" |
|
53 #include "SecurityOrigin.h" |
|
54 #include "Settings.h" |
|
55 #include "Page.h" |
|
56 #include "Pasteboard.h" |
|
57 #include "FrameLoader.h" |
|
58 #include "FrameLoadRequest.h" |
|
59 #include "KURL.h" |
|
60 #include "Logging.h" |
|
61 #include "Image.h" |
|
62 #include "InspectorClientQt.h" |
|
63 #include "InspectorController.h" |
|
64 #include "FocusController.h" |
|
65 #include "Editor.h" |
|
66 #include "Scrollbar.h" |
|
67 #include "PlatformKeyboardEvent.h" |
|
68 #include "PlatformWheelEvent.h" |
|
69 #include "PluginDatabase.h" |
|
70 #include "ProgressTracker.h" |
|
71 #include "RefPtr.h" |
|
72 #include "RenderTextControl.h" |
|
73 #include "TextIterator.h" |
|
74 #include "HashMap.h" |
|
75 #include "HTMLFormElement.h" |
|
76 #include "HTMLInputElement.h" |
|
77 #include "HTMLNames.h" |
|
78 #include "HitTestResult.h" |
|
79 #include "WindowFeatures.h" |
|
80 #include "LocalizedStrings.h" |
|
81 #include "Cache.h" |
|
82 #include "runtime/InitializeThreading.h" |
|
83 #include "PageGroup.h" |
|
84 #include "NotificationPresenterClientQt.h" |
|
85 #include "PageClientQt.h" |
|
86 #include "WorkerThread.h" |
|
87 #include "wtf/Threading.h" |
|
88 |
|
89 #include <QApplication> |
|
90 #include <QBasicTimer> |
|
91 #include <QBitArray> |
|
92 #include <QDebug> |
|
93 #include <QDragEnterEvent> |
|
94 #include <QDragLeaveEvent> |
|
95 #include <QDragMoveEvent> |
|
96 #include <QDropEvent> |
|
97 #include <QFileDialog> |
|
98 #include <QHttpRequestHeader> |
|
99 #include <QInputDialog> |
|
100 #include <QLocale> |
|
101 #include <QMessageBox> |
|
102 #include <QNetworkProxy> |
|
103 #include <QUndoStack> |
|
104 #include <QUrl> |
|
105 #include <QPainter> |
|
106 #include <QClipboard> |
|
107 #include <QSslSocket> |
|
108 #include <QStyle> |
|
109 #include <QSysInfo> |
|
110 #include <QTextCharFormat> |
|
111 #include <QTextDocument> |
|
112 #include <QNetworkAccessManager> |
|
113 #include <QNetworkRequest> |
|
114 #if defined(Q_WS_X11) |
|
115 #include <QX11Info> |
|
116 #endif |
|
117 |
|
118 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) |
|
119 #include <QTouchEvent> |
|
120 #include "PlatformTouchEvent.h" |
|
121 #endif |
|
122 |
|
123 using namespace WebCore; |
|
124 |
|
125 bool QWebPagePrivate::drtRun = false; |
|
126 |
|
127 // Lookup table mapping QWebPage::WebActions to the associated Editor commands |
|
128 static const char* editorCommandWebActions[] = |
|
129 { |
|
130 0, // OpenLink, |
|
131 |
|
132 0, // OpenLinkInNewWindow, |
|
133 0, // OpenFrameInNewWindow, |
|
134 |
|
135 0, // DownloadLinkToDisk, |
|
136 0, // CopyLinkToClipboard, |
|
137 |
|
138 0, // OpenImageInNewWindow, |
|
139 0, // DownloadImageToDisk, |
|
140 0, // CopyImageToClipboard, |
|
141 |
|
142 0, // Back, |
|
143 0, // Forward, |
|
144 0, // Stop, |
|
145 0, // Reload, |
|
146 |
|
147 "Cut", // Cut, |
|
148 "Copy", // Copy, |
|
149 "Paste", // Paste, |
|
150 |
|
151 "Undo", // Undo, |
|
152 "Redo", // Redo, |
|
153 "MoveForward", // MoveToNextChar, |
|
154 "MoveBackward", // MoveToPreviousChar, |
|
155 "MoveWordForward", // MoveToNextWord, |
|
156 "MoveWordBackward", // MoveToPreviousWord, |
|
157 "MoveDown", // MoveToNextLine, |
|
158 "MoveUp", // MoveToPreviousLine, |
|
159 "MoveToBeginningOfLine", // MoveToStartOfLine, |
|
160 "MoveToEndOfLine", // MoveToEndOfLine, |
|
161 "MoveToBeginningOfParagraph", // MoveToStartOfBlock, |
|
162 "MoveToEndOfParagraph", // MoveToEndOfBlock, |
|
163 "MoveToBeginningOfDocument", // MoveToStartOfDocument, |
|
164 "MoveToEndOfDocument", // MoveToEndOfDocument, |
|
165 "MoveForwardAndModifySelection", // SelectNextChar, |
|
166 "MoveBackwardAndModifySelection", // SelectPreviousChar, |
|
167 "MoveWordForwardAndModifySelection", // SelectNextWord, |
|
168 "MoveWordBackwardAndModifySelection", // SelectPreviousWord, |
|
169 "MoveDownAndModifySelection", // SelectNextLine, |
|
170 "MoveUpAndModifySelection", // SelectPreviousLine, |
|
171 "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine, |
|
172 "MoveToEndOfLineAndModifySelection", // SelectEndOfLine, |
|
173 "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock, |
|
174 "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock, |
|
175 "MoveToBeginningOfDocumentAndModifySelection", //SelectStartOfDocument, |
|
176 "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument, |
|
177 "DeleteWordBackward", // DeleteStartOfWord, |
|
178 "DeleteWordForward", // DeleteEndOfWord, |
|
179 |
|
180 0, // SetTextDirectionDefault, |
|
181 0, // SetTextDirectionLeftToRight, |
|
182 0, // SetTextDirectionRightToLeft, |
|
183 |
|
184 "ToggleBold", // ToggleBold, |
|
185 "ToggleItalic", // ToggleItalic, |
|
186 "ToggleUnderline", // ToggleUnderline, |
|
187 |
|
188 0, // InspectElement, |
|
189 |
|
190 "InsertNewline", // InsertParagraphSeparator |
|
191 "InsertLineBreak", // InsertLineSeparator |
|
192 |
|
193 "SelectAll", // SelectAll |
|
194 0, // ReloadAndBypassCache, |
|
195 |
|
196 "PasteAndMatchStyle", // PasteAndMatchStyle |
|
197 "RemoveFormat", // RemoveFormat |
|
198 "Strikethrough", // ToggleStrikethrough, |
|
199 "Subscript", // ToggleSubscript |
|
200 "Superscript", // ToggleSuperscript |
|
201 "InsertUnorderedList", // InsertUnorderedList |
|
202 "InsertOrderedList", // InsertOrderedList |
|
203 "Indent", // Indent |
|
204 "Outdent", // Outdent, |
|
205 |
|
206 "AlignCenter", // AlignCenter, |
|
207 "AlignJustified", // AlignJustified, |
|
208 "AlignLeft", // AlignLeft, |
|
209 "AlignRight", // AlignRight, |
|
210 |
|
211 0 // WebActionCount |
|
212 }; |
|
213 |
|
214 // Lookup the appropriate editor command to use for WebAction \a action |
|
215 const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action) |
|
216 { |
|
217 if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*)))) |
|
218 return editorCommandWebActions[action]; |
|
219 return 0; |
|
220 } |
|
221 |
|
222 static inline DragOperation dropActionToDragOp(Qt::DropActions actions) |
|
223 { |
|
224 unsigned result = 0; |
|
225 if (actions & Qt::CopyAction) |
|
226 result |= DragOperationCopy; |
|
227 // DragOperationgeneric represents InternetExplorer's equivalent of Move operation, |
|
228 // hence it should be considered as "move" |
|
229 if (actions & Qt::MoveAction) |
|
230 result |= (DragOperationMove | DragOperationGeneric); |
|
231 if (actions & Qt::LinkAction) |
|
232 result |= DragOperationLink; |
|
233 return (DragOperation)result; |
|
234 } |
|
235 |
|
236 static inline Qt::DropAction dragOpToDropAction(unsigned actions) |
|
237 { |
|
238 Qt::DropAction result = Qt::IgnoreAction; |
|
239 if (actions & DragOperationCopy) |
|
240 result = Qt::CopyAction; |
|
241 else if (actions & DragOperationMove) |
|
242 result = Qt::MoveAction; |
|
243 // DragOperationgeneric represents InternetExplorer's equivalent of Move operation, |
|
244 // hence it should be considered as "move" |
|
245 else if (actions & DragOperationGeneric) |
|
246 result = Qt::MoveAction; |
|
247 else if (actions & DragOperationLink) |
|
248 result = Qt::LinkAction; |
|
249 return result; |
|
250 } |
|
251 |
|
252 QWebPagePrivate::QWebPagePrivate(QWebPage *qq) |
|
253 : q(qq) |
|
254 , client(0) |
|
255 #if QT_VERSION < 0x040600 |
|
256 , view(0) |
|
257 #endif |
|
258 , clickCausedFocus(false) |
|
259 , viewportSize(QSize(0, 0)) |
|
260 , inspectorFrontend(0) |
|
261 , inspector(0) |
|
262 , inspectorIsInternalOnly(false) |
|
263 { |
|
264 WebCore::InitializeLoggingChannelsIfNecessary(); |
|
265 JSC::initializeThreading(); |
|
266 WTF::initializeMainThread(); |
|
267 WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData); |
|
268 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) |
|
269 WebCore::Font::setCodePath(WebCore::Font::Complex); |
|
270 #endif |
|
271 |
|
272 chromeClient = new ChromeClientQt(q); |
|
273 contextMenuClient = new ContextMenuClientQt(); |
|
274 editorClient = new EditorClientQt(q); |
|
275 page = new Page(chromeClient, contextMenuClient, editorClient, |
|
276 new DragClientQt(q), new InspectorClientQt(q), 0, 0, 0, 0); |
|
277 |
|
278 settings = new QWebSettings(page->settings()); |
|
279 |
|
280 #ifndef QT_NO_UNDOSTACK |
|
281 undoStack = 0; |
|
282 #endif |
|
283 mainFrame = 0; |
|
284 networkManager = 0; |
|
285 pluginFactory = 0; |
|
286 insideOpenCall = false; |
|
287 forwardUnsupportedContent = false; |
|
288 editable = false; |
|
289 useFixedLayout = false; |
|
290 linkPolicy = QWebPage::DontDelegateLinks; |
|
291 #ifndef QT_NO_CONTEXTMENU |
|
292 currentContextMenu = 0; |
|
293 #endif |
|
294 smartInsertDeleteEnabled = true; |
|
295 selectTrailingWhitespaceEnabled = false; |
|
296 |
|
297 history.d = new QWebHistoryPrivate(page->backForwardList()); |
|
298 memset(actions, 0, sizeof(actions)); |
|
299 |
|
300 PageGroup::setShouldTrackVisitedLinks(true); |
|
301 |
|
302 #if ENABLE(NOTIFICATIONS) |
|
303 NotificationPresenterClientQt::notificationPresenter()->addClient(); |
|
304 #endif |
|
305 } |
|
306 |
|
307 QWebPagePrivate::~QWebPagePrivate() |
|
308 { |
|
309 #ifndef QT_NO_CONTEXTMENU |
|
310 delete currentContextMenu; |
|
311 #endif |
|
312 #ifndef QT_NO_UNDOSTACK |
|
313 delete undoStack; |
|
314 #endif |
|
315 delete settings; |
|
316 delete page; |
|
317 |
|
318 #if ENABLE(NOTIFICATIONS) |
|
319 NotificationPresenterClientQt::notificationPresenter()->removeClient(); |
|
320 #endif |
|
321 } |
|
322 |
|
323 WebCore::Page* QWebPagePrivate::core(QWebPage* page) |
|
324 { |
|
325 return page->d->page; |
|
326 } |
|
327 |
|
328 QWebPagePrivate* QWebPagePrivate::priv(QWebPage* page) |
|
329 { |
|
330 return page->d; |
|
331 } |
|
332 |
|
333 bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) |
|
334 { |
|
335 if (insideOpenCall |
|
336 && frame == mainFrame) |
|
337 return true; |
|
338 return q->acceptNavigationRequest(frame, request, type); |
|
339 } |
|
340 |
|
341 void QWebPagePrivate::createMainFrame() |
|
342 { |
|
343 if (!mainFrame) { |
|
344 QWebFrameData frameData(page); |
|
345 mainFrame = new QWebFrame(q, &frameData); |
|
346 |
|
347 emit q->frameCreated(mainFrame); |
|
348 } |
|
349 } |
|
350 |
|
351 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action) |
|
352 { |
|
353 switch (action) { |
|
354 case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink; |
|
355 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow; |
|
356 case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk; |
|
357 case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard; |
|
358 case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow; |
|
359 case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk; |
|
360 case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard; |
|
361 case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow; |
|
362 case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy; |
|
363 case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back; |
|
364 case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward; |
|
365 case WebCore::ContextMenuItemTagStop: return QWebPage::Stop; |
|
366 case WebCore::ContextMenuItemTagReload: return QWebPage::Reload; |
|
367 case WebCore::ContextMenuItemTagCut: return QWebPage::Cut; |
|
368 case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste; |
|
369 case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault; |
|
370 case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight; |
|
371 case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft; |
|
372 case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold; |
|
373 case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic; |
|
374 case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline; |
|
375 #if ENABLE(INSPECTOR) |
|
376 case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement; |
|
377 #endif |
|
378 default: break; |
|
379 } |
|
380 return QWebPage::NoWebAction; |
|
381 } |
|
382 |
|
383 #ifndef QT_NO_CONTEXTMENU |
|
384 QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, |
|
385 const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions) |
|
386 { |
|
387 if (!client) |
|
388 return 0; |
|
389 |
|
390 QMenu* menu = new QMenu(client->ownerWidget()); |
|
391 for (int i = 0; i < items->count(); ++i) { |
|
392 const ContextMenuItem &item = items->at(i); |
|
393 switch (item.type()) { |
|
394 case WebCore::CheckableActionType: /* fall through */ |
|
395 case WebCore::ActionType: { |
|
396 QWebPage::WebAction action = webActionForContextMenuAction(item.action()); |
|
397 QAction *a = q->action(action); |
|
398 if (a) { |
|
399 ContextMenuItem it(item); |
|
400 webcoreMenu->checkOrEnableIfNeeded(it); |
|
401 PlatformMenuItemDescription desc = it.releasePlatformDescription(); |
|
402 a->setEnabled(desc.enabled); |
|
403 a->setChecked(desc.checked); |
|
404 a->setCheckable(item.type() == WebCore::CheckableActionType); |
|
405 |
|
406 menu->addAction(a); |
|
407 visitedWebActions->setBit(action); |
|
408 } |
|
409 break; |
|
410 } |
|
411 case WebCore::SeparatorType: |
|
412 menu->addSeparator(); |
|
413 break; |
|
414 case WebCore::SubmenuType: { |
|
415 QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions); |
|
416 |
|
417 bool anyEnabledAction = false; |
|
418 |
|
419 QList<QAction *> actions = subMenu->actions(); |
|
420 for (int i = 0; i < actions.count(); ++i) { |
|
421 if (actions.at(i)->isVisible()) |
|
422 anyEnabledAction |= actions.at(i)->isEnabled(); |
|
423 } |
|
424 |
|
425 // don't show sub-menus with just disabled actions |
|
426 if (anyEnabledAction) { |
|
427 subMenu->setTitle(item.title()); |
|
428 menu->addAction(subMenu->menuAction()); |
|
429 } else |
|
430 delete subMenu; |
|
431 break; |
|
432 } |
|
433 } |
|
434 } |
|
435 return menu; |
|
436 } |
|
437 #endif // QT_NO_CONTEXTMENU |
|
438 |
|
439 #ifndef QT_NO_ACTION |
|
440 void QWebPagePrivate::_q_webActionTriggered(bool checked) |
|
441 { |
|
442 QAction *a = qobject_cast<QAction *>(q->sender()); |
|
443 if (!a) |
|
444 return; |
|
445 QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt()); |
|
446 q->triggerAction(action, checked); |
|
447 } |
|
448 #endif // QT_NO_ACTION |
|
449 |
|
450 void QWebPagePrivate::_q_cleanupLeakMessages() |
|
451 { |
|
452 #ifndef NDEBUG |
|
453 // Need this to make leak messages accurate. |
|
454 cache()->setCapacities(0, 0, 0); |
|
455 #endif |
|
456 } |
|
457 |
|
458 void QWebPagePrivate::updateAction(QWebPage::WebAction action) |
|
459 { |
|
460 #ifdef QT_NO_ACTION |
|
461 Q_UNUSED(action) |
|
462 #else |
|
463 QAction *a = actions[action]; |
|
464 if (!a || !mainFrame) |
|
465 return; |
|
466 |
|
467 WebCore::FrameLoader *loader = mainFrame->d->frame->loader(); |
|
468 WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor(); |
|
469 |
|
470 bool enabled = a->isEnabled(); |
|
471 bool checked = a->isChecked(); |
|
472 |
|
473 switch (action) { |
|
474 case QWebPage::Back: |
|
475 enabled = page->canGoBackOrForward(-1); |
|
476 break; |
|
477 case QWebPage::Forward: |
|
478 enabled = page->canGoBackOrForward(1); |
|
479 break; |
|
480 case QWebPage::Stop: |
|
481 enabled = loader->isLoading(); |
|
482 break; |
|
483 case QWebPage::Reload: |
|
484 case QWebPage::ReloadAndBypassCache: |
|
485 enabled = !loader->isLoading(); |
|
486 break; |
|
487 #ifndef QT_NO_UNDOSTACK |
|
488 case QWebPage::Undo: |
|
489 case QWebPage::Redo: |
|
490 // those two are handled by QUndoStack |
|
491 break; |
|
492 #endif // QT_NO_UNDOSTACK |
|
493 case QWebPage::SelectAll: // editor command is always enabled |
|
494 break; |
|
495 case QWebPage::SetTextDirectionDefault: |
|
496 case QWebPage::SetTextDirectionLeftToRight: |
|
497 case QWebPage::SetTextDirectionRightToLeft: |
|
498 enabled = editor->canEdit(); |
|
499 checked = false; |
|
500 break; |
|
501 default: { |
|
502 // see if it's an editor command |
|
503 const char* commandName = editorCommandForWebActions(action); |
|
504 |
|
505 // if it's an editor command, let it's logic determine state |
|
506 if (commandName) { |
|
507 Editor::Command command = editor->command(commandName); |
|
508 enabled = command.isEnabled(); |
|
509 if (enabled) |
|
510 checked = command.state() != FalseTriState; |
|
511 else |
|
512 checked = false; |
|
513 } |
|
514 break; |
|
515 } |
|
516 } |
|
517 |
|
518 a->setEnabled(enabled); |
|
519 |
|
520 if (a->isCheckable()) |
|
521 a->setChecked(checked); |
|
522 #endif // QT_NO_ACTION |
|
523 } |
|
524 |
|
525 void QWebPagePrivate::updateNavigationActions() |
|
526 { |
|
527 updateAction(QWebPage::Back); |
|
528 updateAction(QWebPage::Forward); |
|
529 updateAction(QWebPage::Stop); |
|
530 updateAction(QWebPage::Reload); |
|
531 updateAction(QWebPage::ReloadAndBypassCache); |
|
532 } |
|
533 |
|
534 void QWebPagePrivate::updateEditorActions() |
|
535 { |
|
536 updateAction(QWebPage::Cut); |
|
537 updateAction(QWebPage::Copy); |
|
538 updateAction(QWebPage::Paste); |
|
539 updateAction(QWebPage::MoveToNextChar); |
|
540 updateAction(QWebPage::MoveToPreviousChar); |
|
541 updateAction(QWebPage::MoveToNextWord); |
|
542 updateAction(QWebPage::MoveToPreviousWord); |
|
543 updateAction(QWebPage::MoveToNextLine); |
|
544 updateAction(QWebPage::MoveToPreviousLine); |
|
545 updateAction(QWebPage::MoveToStartOfLine); |
|
546 updateAction(QWebPage::MoveToEndOfLine); |
|
547 updateAction(QWebPage::MoveToStartOfBlock); |
|
548 updateAction(QWebPage::MoveToEndOfBlock); |
|
549 updateAction(QWebPage::MoveToStartOfDocument); |
|
550 updateAction(QWebPage::MoveToEndOfDocument); |
|
551 updateAction(QWebPage::SelectNextChar); |
|
552 updateAction(QWebPage::SelectPreviousChar); |
|
553 updateAction(QWebPage::SelectNextWord); |
|
554 updateAction(QWebPage::SelectPreviousWord); |
|
555 updateAction(QWebPage::SelectNextLine); |
|
556 updateAction(QWebPage::SelectPreviousLine); |
|
557 updateAction(QWebPage::SelectStartOfLine); |
|
558 updateAction(QWebPage::SelectEndOfLine); |
|
559 updateAction(QWebPage::SelectStartOfBlock); |
|
560 updateAction(QWebPage::SelectEndOfBlock); |
|
561 updateAction(QWebPage::SelectStartOfDocument); |
|
562 updateAction(QWebPage::SelectEndOfDocument); |
|
563 updateAction(QWebPage::DeleteStartOfWord); |
|
564 updateAction(QWebPage::DeleteEndOfWord); |
|
565 updateAction(QWebPage::SetTextDirectionDefault); |
|
566 updateAction(QWebPage::SetTextDirectionLeftToRight); |
|
567 updateAction(QWebPage::SetTextDirectionRightToLeft); |
|
568 updateAction(QWebPage::ToggleBold); |
|
569 updateAction(QWebPage::ToggleItalic); |
|
570 updateAction(QWebPage::ToggleUnderline); |
|
571 updateAction(QWebPage::InsertParagraphSeparator); |
|
572 updateAction(QWebPage::InsertLineSeparator); |
|
573 updateAction(QWebPage::PasteAndMatchStyle); |
|
574 updateAction(QWebPage::RemoveFormat); |
|
575 updateAction(QWebPage::ToggleStrikethrough); |
|
576 updateAction(QWebPage::ToggleSubscript); |
|
577 updateAction(QWebPage::ToggleSuperscript); |
|
578 updateAction(QWebPage::InsertUnorderedList); |
|
579 updateAction(QWebPage::InsertOrderedList); |
|
580 updateAction(QWebPage::Indent); |
|
581 updateAction(QWebPage::Outdent); |
|
582 updateAction(QWebPage::AlignCenter); |
|
583 updateAction(QWebPage::AlignJustified); |
|
584 updateAction(QWebPage::AlignLeft); |
|
585 updateAction(QWebPage::AlignRight); |
|
586 } |
|
587 |
|
588 void QWebPagePrivate::timerEvent(QTimerEvent *ev) |
|
589 { |
|
590 int timerId = ev->timerId(); |
|
591 if (timerId == tripleClickTimer.timerId()) |
|
592 tripleClickTimer.stop(); |
|
593 else |
|
594 q->timerEvent(ev); |
|
595 } |
|
596 |
|
597 void QWebPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev) |
|
598 { |
|
599 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
600 if (!frame->view()) |
|
601 return; |
|
602 |
|
603 bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0)); |
|
604 ev->setAccepted(accepted); |
|
605 } |
|
606 |
|
607 void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev) |
|
608 { |
|
609 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
610 if (!frame->view()) |
|
611 return; |
|
612 |
|
613 bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0)); |
|
614 ev->setAccepted(accepted); |
|
615 } |
|
616 |
|
617 void QWebPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev) |
|
618 { |
|
619 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
620 if (!frame->view()) |
|
621 return; |
|
622 |
|
623 RefPtr<WebCore::Node> oldNode; |
|
624 Frame* focusedFrame = page->focusController()->focusedFrame(); |
|
625 if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0) |
|
626 oldNode = focusedDocument->focusedNode(); |
|
627 |
|
628 if (tripleClickTimer.isActive() |
|
629 && (ev->pos().toPoint() - tripleClick).manhattanLength() |
|
630 < QApplication::startDragDistance()) { |
|
631 mouseTripleClickEvent(ev); |
|
632 return; |
|
633 } |
|
634 |
|
635 bool accepted = false; |
|
636 PlatformMouseEvent mev(ev, 1); |
|
637 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
638 if (mev.button() != NoButton) |
|
639 accepted = frame->eventHandler()->handleMousePressEvent(mev); |
|
640 ev->setAccepted(accepted); |
|
641 |
|
642 RefPtr<WebCore::Node> newNode; |
|
643 focusedFrame = page->focusController()->focusedFrame(); |
|
644 if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0) |
|
645 newNode = focusedDocument->focusedNode(); |
|
646 |
|
647 if (newNode && oldNode != newNode) |
|
648 clickCausedFocus = true; |
|
649 } |
|
650 |
|
651 void QWebPagePrivate::mousePressEvent(QMouseEvent *ev) |
|
652 { |
|
653 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
654 if (!frame->view()) |
|
655 return; |
|
656 |
|
657 RefPtr<WebCore::Node> oldNode; |
|
658 Frame* focusedFrame = page->focusController()->focusedFrame(); |
|
659 if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0) |
|
660 oldNode = focusedDocument->focusedNode(); |
|
661 |
|
662 if (tripleClickTimer.isActive() |
|
663 && (ev->pos() - tripleClick).manhattanLength() |
|
664 < QApplication::startDragDistance()) { |
|
665 mouseTripleClickEvent(ev); |
|
666 return; |
|
667 } |
|
668 |
|
669 bool accepted = false; |
|
670 PlatformMouseEvent mev(ev, 1); |
|
671 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
672 if (mev.button() != NoButton) |
|
673 accepted = frame->eventHandler()->handleMousePressEvent(mev); |
|
674 ev->setAccepted(accepted); |
|
675 |
|
676 RefPtr<WebCore::Node> newNode; |
|
677 focusedFrame = page->focusController()->focusedFrame(); |
|
678 if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0) |
|
679 newNode = focusedDocument->focusedNode(); |
|
680 |
|
681 if (newNode && oldNode != newNode) |
|
682 clickCausedFocus = true; |
|
683 } |
|
684 |
|
685 void QWebPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *ev) |
|
686 { |
|
687 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
688 if (!frame->view()) |
|
689 return; |
|
690 |
|
691 bool accepted = false; |
|
692 PlatformMouseEvent mev(ev, 2); |
|
693 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
694 if (mev.button() != NoButton) |
|
695 accepted = frame->eventHandler()->handleMousePressEvent(mev); |
|
696 ev->setAccepted(accepted); |
|
697 |
|
698 tripleClickTimer.start(QApplication::doubleClickInterval(), q); |
|
699 tripleClick = ev->pos().toPoint(); |
|
700 } |
|
701 |
|
702 void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev) |
|
703 { |
|
704 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
705 if (!frame->view()) |
|
706 return; |
|
707 |
|
708 bool accepted = false; |
|
709 PlatformMouseEvent mev(ev, 2); |
|
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()->handleMousePressEvent(mev); |
|
713 ev->setAccepted(accepted); |
|
714 |
|
715 tripleClickTimer.start(QApplication::doubleClickInterval(), q); |
|
716 tripleClick = ev->pos(); |
|
717 } |
|
718 |
|
719 void QWebPagePrivate::mouseTripleClickEvent(QGraphicsSceneMouseEvent *ev) |
|
720 { |
|
721 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
722 if (!frame->view()) |
|
723 return; |
|
724 |
|
725 bool accepted = false; |
|
726 PlatformMouseEvent mev(ev, 3); |
|
727 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
728 if (mev.button() != NoButton) |
|
729 accepted = frame->eventHandler()->handleMousePressEvent(mev); |
|
730 ev->setAccepted(accepted); |
|
731 } |
|
732 |
|
733 void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) |
|
734 { |
|
735 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
736 if (!frame->view()) |
|
737 return; |
|
738 |
|
739 bool accepted = false; |
|
740 PlatformMouseEvent mev(ev, 3); |
|
741 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
742 if (mev.button() != NoButton) |
|
743 accepted = frame->eventHandler()->handleMousePressEvent(mev); |
|
744 ev->setAccepted(accepted); |
|
745 } |
|
746 |
|
747 void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button) |
|
748 { |
|
749 #ifndef QT_NO_CLIPBOARD |
|
750 if (QApplication::clipboard()->supportsSelection()) { |
|
751 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); |
|
752 Pasteboard::generalPasteboard()->setSelectionMode(true); |
|
753 WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame(); |
|
754 if (button == Qt::LeftButton) { |
|
755 if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) { |
|
756 focusFrame->editor()->copy(); |
|
757 ev->setAccepted(true); |
|
758 } |
|
759 } else if (button == Qt::MidButton) { |
|
760 if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) { |
|
761 focusFrame->editor()->paste(); |
|
762 ev->setAccepted(true); |
|
763 } |
|
764 } |
|
765 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode); |
|
766 } |
|
767 #endif |
|
768 } |
|
769 |
|
770 void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) |
|
771 { |
|
772 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
773 if (!frame->view()) |
|
774 return; |
|
775 |
|
776 bool accepted = false; |
|
777 PlatformMouseEvent mev(ev, 0); |
|
778 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
779 if (mev.button() != NoButton) |
|
780 accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); |
|
781 ev->setAccepted(accepted); |
|
782 |
|
783 handleClipboard(ev, ev->button()); |
|
784 handleSoftwareInputPanel(ev->button()); |
|
785 } |
|
786 |
|
787 void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button) |
|
788 { |
|
789 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) |
|
790 Frame* frame = page->focusController()->focusedFrame(); |
|
791 if (!frame) |
|
792 return; |
|
793 |
|
794 if (client && client->inputMethodEnabled() |
|
795 && frame->document()->focusedNode() |
|
796 && button == Qt::LeftButton && qApp->autoSipEnabled()) { |
|
797 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( |
|
798 client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); |
|
799 if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) { |
|
800 QEvent event(QEvent::RequestSoftwareInputPanel); |
|
801 QApplication::sendEvent(client->ownerWidget(), &event); |
|
802 } |
|
803 } |
|
804 |
|
805 clickCausedFocus = false; |
|
806 #endif |
|
807 } |
|
808 |
|
809 void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) |
|
810 { |
|
811 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
812 if (!frame->view()) |
|
813 return; |
|
814 |
|
815 bool accepted = false; |
|
816 PlatformMouseEvent mev(ev, 0); |
|
817 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton |
|
818 if (mev.button() != NoButton) |
|
819 accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); |
|
820 ev->setAccepted(accepted); |
|
821 |
|
822 handleClipboard(ev, ev->button()); |
|
823 handleSoftwareInputPanel(ev->button()); |
|
824 } |
|
825 |
|
826 #ifndef QT_NO_CONTEXTMENU |
|
827 void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos) |
|
828 { |
|
829 QMenu *menu = q->createStandardContextMenu(); |
|
830 if (menu) { |
|
831 menu->exec(globalPos); |
|
832 delete menu; |
|
833 } |
|
834 } |
|
835 #endif // QT_NO_CONTEXTMENU |
|
836 |
|
837 /*! |
|
838 \since 4.5 |
|
839 This function creates the standard context menu which is shown when |
|
840 the user clicks on the web page with the right mouse button. It is |
|
841 called from the default contextMenuEvent() handler. The popup menu's |
|
842 ownership is transferred to the caller. |
|
843 */ |
|
844 QMenu *QWebPage::createStandardContextMenu() |
|
845 { |
|
846 #ifndef QT_NO_CONTEXTMENU |
|
847 QMenu *menu = d->currentContextMenu; |
|
848 d->currentContextMenu = 0; |
|
849 return menu; |
|
850 #else |
|
851 return 0; |
|
852 #endif |
|
853 } |
|
854 |
|
855 #ifndef QT_NO_WHEELEVENT |
|
856 void QWebPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev) |
|
857 { |
|
858 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
859 if (!frame->view()) |
|
860 return; |
|
861 |
|
862 WebCore::PlatformWheelEvent pev(ev); |
|
863 bool accepted = frame->eventHandler()->handleWheelEvent(pev); |
|
864 ev->setAccepted(accepted); |
|
865 } |
|
866 |
|
867 void QWebPagePrivate::wheelEvent(QWheelEvent *ev) |
|
868 { |
|
869 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
870 if (!frame->view()) |
|
871 return; |
|
872 |
|
873 WebCore::PlatformWheelEvent pev(ev); |
|
874 bool accepted = frame->eventHandler()->handleWheelEvent(pev); |
|
875 ev->setAccepted(accepted); |
|
876 } |
|
877 #endif // QT_NO_WHEELEVENT |
|
878 |
|
879 #ifndef QT_NO_SHORTCUT |
|
880 QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event) |
|
881 { |
|
882 static struct { |
|
883 QKeySequence::StandardKey standardKey; |
|
884 QWebPage::WebAction action; |
|
885 } editorActions[] = { |
|
886 { QKeySequence::Cut, QWebPage::Cut }, |
|
887 { QKeySequence::Copy, QWebPage::Copy }, |
|
888 { QKeySequence::Paste, QWebPage::Paste }, |
|
889 { QKeySequence::Undo, QWebPage::Undo }, |
|
890 { QKeySequence::Redo, QWebPage::Redo }, |
|
891 { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar }, |
|
892 { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar }, |
|
893 { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord }, |
|
894 { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord }, |
|
895 { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine }, |
|
896 { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine }, |
|
897 { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine }, |
|
898 { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine }, |
|
899 { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock }, |
|
900 { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock }, |
|
901 { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument }, |
|
902 { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument }, |
|
903 { QKeySequence::SelectNextChar, QWebPage::SelectNextChar }, |
|
904 { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar }, |
|
905 { QKeySequence::SelectNextWord, QWebPage::SelectNextWord }, |
|
906 { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord }, |
|
907 { QKeySequence::SelectNextLine, QWebPage::SelectNextLine }, |
|
908 { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine }, |
|
909 { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine }, |
|
910 { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine }, |
|
911 { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock }, |
|
912 { QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock }, |
|
913 { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument }, |
|
914 { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument }, |
|
915 { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord }, |
|
916 { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord }, |
|
917 { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator }, |
|
918 { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator }, |
|
919 { QKeySequence::SelectAll, QWebPage::SelectAll }, |
|
920 { QKeySequence::UnknownKey, QWebPage::NoWebAction } |
|
921 }; |
|
922 |
|
923 for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i) |
|
924 if (event == editorActions[i].standardKey) |
|
925 return editorActions[i].action; |
|
926 |
|
927 return QWebPage::NoWebAction; |
|
928 } |
|
929 #endif // QT_NO_SHORTCUT |
|
930 |
|
931 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) |
|
932 { |
|
933 bool handled = false; |
|
934 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); |
|
935 // we forward the key event to WebCore first to handle potential DOM |
|
936 // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent |
|
937 // to trigger editor commands via triggerAction(). |
|
938 if (!handled) |
|
939 handled = frame->eventHandler()->keyEvent(ev); |
|
940 if (!handled) { |
|
941 handled = true; |
|
942 if (!handleScrolling(ev, frame)) { |
|
943 switch (ev->key()) { |
|
944 case Qt::Key_Back: |
|
945 q->triggerAction(QWebPage::Back); |
|
946 break; |
|
947 case Qt::Key_Forward: |
|
948 q->triggerAction(QWebPage::Forward); |
|
949 break; |
|
950 case Qt::Key_Stop: |
|
951 q->triggerAction(QWebPage::Stop); |
|
952 break; |
|
953 case Qt::Key_Refresh: |
|
954 q->triggerAction(QWebPage::Reload); |
|
955 break; |
|
956 case Qt::Key_Backspace: |
|
957 if (ev->modifiers() == Qt::ShiftModifier) |
|
958 q->triggerAction(QWebPage::Forward); |
|
959 else |
|
960 q->triggerAction(QWebPage::Back); |
|
961 break; |
|
962 default: |
|
963 handled = false; |
|
964 break; |
|
965 } |
|
966 } |
|
967 } |
|
968 |
|
969 ev->setAccepted(handled); |
|
970 } |
|
971 |
|
972 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev) |
|
973 { |
|
974 if (ev->isAutoRepeat()) { |
|
975 ev->setAccepted(true); |
|
976 return; |
|
977 } |
|
978 |
|
979 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); |
|
980 bool handled = frame->eventHandler()->keyEvent(ev); |
|
981 ev->setAccepted(handled); |
|
982 } |
|
983 |
|
984 void QWebPagePrivate::focusInEvent(QFocusEvent*) |
|
985 { |
|
986 FocusController *focusController = page->focusController(); |
|
987 focusController->setActive(true); |
|
988 focusController->setFocused(true); |
|
989 if (!focusController->focusedFrame()) |
|
990 focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame)); |
|
991 } |
|
992 |
|
993 void QWebPagePrivate::focusOutEvent(QFocusEvent*) |
|
994 { |
|
995 // only set the focused frame inactive so that we stop painting the caret |
|
996 // and the focus frame. But don't tell the focus controller so that upon |
|
997 // focusInEvent() we can re-activate the frame. |
|
998 FocusController *focusController = page->focusController(); |
|
999 // Call setFocused first so that window.onblur doesn't get called twice |
|
1000 focusController->setFocused(false); |
|
1001 focusController->setActive(false); |
|
1002 } |
|
1003 |
|
1004 void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) |
|
1005 { |
|
1006 #ifndef QT_NO_DRAGANDDROP |
|
1007 DragData dragData(ev->mimeData(), ev->pos().toPoint(), |
|
1008 QCursor::pos(), dropActionToDragOp(ev->possibleActions())); |
|
1009 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); |
|
1010 ev->setDropAction(action); |
|
1011 if (action != Qt::IgnoreAction) |
|
1012 ev->acceptProposedAction(); |
|
1013 #endif |
|
1014 } |
|
1015 |
|
1016 void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) |
|
1017 { |
|
1018 #ifndef QT_NO_DRAGANDDROP |
|
1019 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), |
|
1020 dropActionToDragOp(ev->possibleActions())); |
|
1021 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); |
|
1022 ev->setDropAction(action); |
|
1023 // We must accept this event in order to receive the drag move events that are sent |
|
1024 // while the drag and drop action is in progress. |
|
1025 ev->acceptProposedAction(); |
|
1026 #endif |
|
1027 } |
|
1028 |
|
1029 void QWebPagePrivate::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev) |
|
1030 { |
|
1031 #ifndef QT_NO_DRAGANDDROP |
|
1032 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); |
|
1033 page->dragController()->dragExited(&dragData); |
|
1034 ev->accept(); |
|
1035 #endif |
|
1036 } |
|
1037 |
|
1038 void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent* ev) |
|
1039 { |
|
1040 #ifndef QT_NO_DRAGANDDROP |
|
1041 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); |
|
1042 page->dragController()->dragExited(&dragData); |
|
1043 ev->accept(); |
|
1044 #endif |
|
1045 } |
|
1046 |
|
1047 void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) |
|
1048 { |
|
1049 #ifndef QT_NO_DRAGANDDROP |
|
1050 DragData dragData(ev->mimeData(), ev->pos().toPoint(), |
|
1051 QCursor::pos(), dropActionToDragOp(ev->possibleActions())); |
|
1052 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); |
|
1053 ev->setDropAction(action); |
|
1054 if (action != Qt::IgnoreAction) |
|
1055 ev->acceptProposedAction(); |
|
1056 #endif |
|
1057 } |
|
1058 |
|
1059 void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) |
|
1060 { |
|
1061 #ifndef QT_NO_DRAGANDDROP |
|
1062 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), |
|
1063 dropActionToDragOp(ev->possibleActions())); |
|
1064 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); |
|
1065 m_lastDropAction = action; |
|
1066 ev->setDropAction(action); |
|
1067 // We must accept this event in order to receive the drag move events that are sent |
|
1068 // while the drag and drop action is in progress. |
|
1069 ev->acceptProposedAction(); |
|
1070 #endif |
|
1071 } |
|
1072 |
|
1073 void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) |
|
1074 { |
|
1075 #ifndef QT_NO_DRAGANDDROP |
|
1076 DragData dragData(ev->mimeData(), ev->pos().toPoint(), |
|
1077 QCursor::pos(), dropActionToDragOp(ev->possibleActions())); |
|
1078 if (page->dragController()->performDrag(&dragData)) |
|
1079 ev->acceptProposedAction(); |
|
1080 #endif |
|
1081 } |
|
1082 |
|
1083 void QWebPagePrivate::dropEvent(QDropEvent* ev) |
|
1084 { |
|
1085 #ifndef QT_NO_DRAGANDDROP |
|
1086 // Overwrite the defaults set by QDragManager::defaultAction() |
|
1087 ev->setDropAction(m_lastDropAction); |
|
1088 DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), |
|
1089 dropActionToDragOp(Qt::DropAction(ev->dropAction()))); |
|
1090 if (page->dragController()->performDrag(&dragData)) |
|
1091 ev->acceptProposedAction(); |
|
1092 #endif |
|
1093 } |
|
1094 |
|
1095 void QWebPagePrivate::leaveEvent(QEvent*) |
|
1096 { |
|
1097 // Fake a mouse move event just outside of the widget, since all |
|
1098 // the interesting mouse-out behavior like invalidating scrollbars |
|
1099 // is handled by the WebKit event handler's mouseMoved function. |
|
1100 QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); |
|
1101 mouseMoveEvent(&fakeEvent); |
|
1102 } |
|
1103 |
|
1104 /*! |
|
1105 \property QWebPage::palette |
|
1106 \brief the page's palette |
|
1107 |
|
1108 The base brush of the palette is used to draw the background of the main frame. |
|
1109 |
|
1110 By default, this property contains the application's default palette. |
|
1111 */ |
|
1112 void QWebPage::setPalette(const QPalette &pal) |
|
1113 { |
|
1114 d->palette = pal; |
|
1115 if (!d->mainFrame || !d->mainFrame->d->frame->view()) |
|
1116 return; |
|
1117 |
|
1118 QBrush brush = pal.brush(QPalette::Base); |
|
1119 QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor(); |
|
1120 QWebFramePrivate::core(d->mainFrame)->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha()); |
|
1121 } |
|
1122 |
|
1123 QPalette QWebPage::palette() const |
|
1124 { |
|
1125 return d->palette; |
|
1126 } |
|
1127 |
|
1128 void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) |
|
1129 { |
|
1130 WebCore::Frame *frame = page->focusController()->focusedOrMainFrame(); |
|
1131 WebCore::Editor *editor = frame->editor(); |
|
1132 #if QT_VERSION >= 0x040600 |
|
1133 QInputMethodEvent::Attribute selection(QInputMethodEvent::Selection, 0, 0, QVariant()); |
|
1134 #endif |
|
1135 |
|
1136 if (!editor->canEdit()) { |
|
1137 ev->ignore(); |
|
1138 return; |
|
1139 } |
|
1140 |
|
1141 RenderObject* renderer = 0; |
|
1142 RenderTextControl* renderTextControl = 0; |
|
1143 |
|
1144 if (frame->selection()->rootEditableElement()) |
|
1145 renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); |
|
1146 |
|
1147 if (renderer && renderer->isTextControl()) |
|
1148 renderTextControl = toRenderTextControl(renderer); |
|
1149 |
|
1150 Vector<CompositionUnderline> underlines; |
|
1151 bool hasSelection = false; |
|
1152 |
|
1153 for (int i = 0; i < ev->attributes().size(); ++i) { |
|
1154 const QInputMethodEvent::Attribute& a = ev->attributes().at(i); |
|
1155 switch (a.type) { |
|
1156 case QInputMethodEvent::TextFormat: { |
|
1157 QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat(); |
|
1158 QColor qcolor = textCharFormat.underlineColor(); |
|
1159 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)); |
|
1160 break; |
|
1161 } |
|
1162 case QInputMethodEvent::Cursor: { |
|
1163 frame->selection()->setCaretVisible(a.length); //if length is 0 cursor is invisible |
|
1164 if (a.length > 0) { |
|
1165 RenderObject* caretRenderer = frame->selection()->caretRenderer(); |
|
1166 if (caretRenderer) { |
|
1167 QColor qcolor = a.value.value<QColor>(); |
|
1168 caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha()))); |
|
1169 } |
|
1170 } |
|
1171 break; |
|
1172 } |
|
1173 #if QT_VERSION >= 0x040600 |
|
1174 case QInputMethodEvent::Selection: { |
|
1175 selection = a; |
|
1176 hasSelection = true; |
|
1177 break; |
|
1178 } |
|
1179 #endif |
|
1180 } |
|
1181 } |
|
1182 |
|
1183 if (!ev->commitString().isEmpty()) |
|
1184 editor->confirmComposition(ev->commitString()); |
|
1185 else { |
|
1186 // 1. empty preedit with a selection attribute, and start/end of 0 cancels composition |
|
1187 // 2. empty preedit with a selection attribute, and start/end of non-0 updates selection of current preedit text |
|
1188 // 3. populated preedit with a selection attribute, and start/end of 0 or non-0 updates selection of supplied preedit text |
|
1189 // 4. otherwise event is updating supplied pre-edit text |
|
1190 QString preedit = ev->preeditString(); |
|
1191 #if QT_VERSION >= 0x040600 |
|
1192 if (hasSelection) { |
|
1193 QString text = (renderTextControl) ? QString(renderTextControl->text()) : QString(); |
|
1194 if (preedit.isEmpty() && selection.start + selection.length > 0) |
|
1195 preedit = text; |
|
1196 editor->setComposition(preedit, underlines, |
|
1197 (selection.length < 0) ? selection.start + selection.length : selection.start, |
|
1198 (selection.length < 0) ? selection.start : selection.start + selection.length); |
|
1199 } else |
|
1200 #endif |
|
1201 editor->setComposition(preedit, underlines, preedit.length(), 0); |
|
1202 } |
|
1203 |
|
1204 ev->accept(); |
|
1205 } |
|
1206 |
|
1207 #ifndef QT_NO_PROPERTIES |
|
1208 typedef struct { |
|
1209 const char* name; |
|
1210 double deferredRepaintDelay; |
|
1211 double initialDeferredRepaintDelayDuringLoading; |
|
1212 double maxDeferredRepaintDelayDuringLoading; |
|
1213 double deferredRepaintDelayIncrementDuringLoading; |
|
1214 } QRepaintThrottlingPreset; |
|
1215 |
|
1216 void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event) |
|
1217 { |
|
1218 if (event->propertyName() == "_q_viewMode") { |
|
1219 QString mode = q->property("_q_viewMode").toString(); |
|
1220 if (mode != viewMode) { |
|
1221 viewMode = mode; |
|
1222 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame()); |
|
1223 WebCore::FrameView* view = frame->view(); |
|
1224 frame->document()->updateStyleSelector(); |
|
1225 view->layout(); |
|
1226 } |
|
1227 } else if (event->propertyName() == "_q_HTMLTokenizerChunkSize") { |
|
1228 int chunkSize = q->property("_q_HTMLTokenizerChunkSize").toInt(); |
|
1229 q->handle()->page->setCustomHTMLTokenizerChunkSize(chunkSize); |
|
1230 } else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") { |
|
1231 double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble(); |
|
1232 q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay); |
|
1233 } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") { |
|
1234 double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble(); |
|
1235 FrameView::setRepaintThrottlingDeferredRepaintDelay(p); |
|
1236 } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") { |
|
1237 double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble(); |
|
1238 FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p); |
|
1239 } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") { |
|
1240 double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble(); |
|
1241 FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p); |
|
1242 } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") { |
|
1243 double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble(); |
|
1244 FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p); |
|
1245 } else if (event->propertyName() == "_q_RepaintThrottlingPreset") { |
|
1246 static const QRepaintThrottlingPreset presets[] = { |
|
1247 { "NoThrottling", 0, 0, 0, 0 }, |
|
1248 { "Legacy", 0.025, 0, 2.5, 0.5 }, |
|
1249 { "Minimal", 0.01, 0, 1, 0.2 }, |
|
1250 { "Medium", 0.025, 1, 5, 0.5 }, |
|
1251 { "Heavy", 0.1, 2, 10, 1 } |
|
1252 }; |
|
1253 |
|
1254 QString p = q->property("_q_RepaintThrottlingPreset").toString(); |
|
1255 for(int i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) { |
|
1256 if(p == presets[i].name) { |
|
1257 FrameView::setRepaintThrottlingDeferredRepaintDelay( |
|
1258 presets[i].deferredRepaintDelay); |
|
1259 FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading( |
|
1260 presets[i].initialDeferredRepaintDelayDuringLoading); |
|
1261 FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading( |
|
1262 presets[i].maxDeferredRepaintDelayDuringLoading); |
|
1263 FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading( |
|
1264 presets[i].deferredRepaintDelayIncrementDuringLoading); |
|
1265 break; |
|
1266 } |
|
1267 } |
|
1268 } |
|
1269 #if ENABLE(TILED_BACKING_STORE) |
|
1270 else if (event->propertyName() == "_q_TiledBackingStoreTileSize") { |
|
1271 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame()); |
|
1272 if (!frame->tiledBackingStore()) |
|
1273 return; |
|
1274 QSize tileSize = q->property("_q_TiledBackingStoreTileSize").toSize(); |
|
1275 frame->tiledBackingStore()->setTileSize(tileSize); |
|
1276 } else if (event->propertyName() == "_q_TiledBackingStoreTileCreationDelay") { |
|
1277 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame()); |
|
1278 if (!frame->tiledBackingStore()) |
|
1279 return; |
|
1280 int tileCreationDelay = q->property("_q_TiledBackingStoreTileCreationDelay").toInt(); |
|
1281 frame->tiledBackingStore()->setTileCreationDelay(static_cast<double>(tileCreationDelay) / 1000.); |
|
1282 } else if (event->propertyName() == "_q_TiledBackingStoreKeepAreaMultiplier") { |
|
1283 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame()); |
|
1284 if (!frame->tiledBackingStore()) |
|
1285 return; |
|
1286 FloatSize keepMultiplier; |
|
1287 FloatSize coverMultiplier; |
|
1288 frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier); |
|
1289 QSizeF qSize = q->property("_q_TiledBackingStoreKeepAreaMultiplier").toSizeF(); |
|
1290 keepMultiplier = FloatSize(qSize.width(), qSize.height()); |
|
1291 frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier); |
|
1292 } else if (event->propertyName() == "_q_TiledBackingStoreCoverAreaMultiplier") { |
|
1293 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame()); |
|
1294 if (!frame->tiledBackingStore()) |
|
1295 return; |
|
1296 FloatSize keepMultiplier; |
|
1297 FloatSize coverMultiplier; |
|
1298 frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier); |
|
1299 QSizeF qSize = q->property("_q_TiledBackingStoreCoverAreaMultiplier").toSizeF(); |
|
1300 coverMultiplier = FloatSize(qSize.width(), qSize.height()); |
|
1301 frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier); |
|
1302 } |
|
1303 #endif |
|
1304 } |
|
1305 #endif |
|
1306 |
|
1307 void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event) |
|
1308 { |
|
1309 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); |
|
1310 WebCore::Editor* editor = frame->editor(); |
|
1311 if (editor->canEdit()) { |
|
1312 if (event->modifiers() == Qt::NoModifier |
|
1313 || event->modifiers() == Qt::ShiftModifier |
|
1314 || event->modifiers() == Qt::KeypadModifier) { |
|
1315 if (event->key() < Qt::Key_Escape) { |
|
1316 event->accept(); |
|
1317 } else { |
|
1318 switch (event->key()) { |
|
1319 case Qt::Key_Return: |
|
1320 case Qt::Key_Enter: |
|
1321 case Qt::Key_Delete: |
|
1322 case Qt::Key_Home: |
|
1323 case Qt::Key_End: |
|
1324 case Qt::Key_Backspace: |
|
1325 case Qt::Key_Left: |
|
1326 case Qt::Key_Right: |
|
1327 case Qt::Key_Up: |
|
1328 case Qt::Key_Down: |
|
1329 case Qt::Key_Tab: |
|
1330 event->accept(); |
|
1331 default: |
|
1332 break; |
|
1333 } |
|
1334 } |
|
1335 } |
|
1336 #ifndef QT_NO_SHORTCUT |
|
1337 else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction) |
|
1338 event->accept(); |
|
1339 #endif |
|
1340 } |
|
1341 } |
|
1342 |
|
1343 bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) |
|
1344 { |
|
1345 ScrollDirection direction; |
|
1346 ScrollGranularity granularity; |
|
1347 |
|
1348 #ifndef QT_NO_SHORTCUT |
|
1349 if (ev == QKeySequence::MoveToNextPage |
|
1350 || (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) { |
|
1351 granularity = ScrollByPage; |
|
1352 direction = ScrollDown; |
|
1353 } else if (ev == QKeySequence::MoveToPreviousPage |
|
1354 || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) { |
|
1355 granularity = ScrollByPage; |
|
1356 direction = ScrollUp; |
|
1357 } else |
|
1358 #endif // QT_NO_SHORTCUT |
|
1359 if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier) |
|
1360 || ev->key() == Qt::Key_Home) { |
|
1361 granularity = ScrollByDocument; |
|
1362 direction = ScrollUp; |
|
1363 } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier) |
|
1364 || ev->key() == Qt::Key_End) { |
|
1365 granularity = ScrollByDocument; |
|
1366 direction = ScrollDown; |
|
1367 } else { |
|
1368 switch (ev->key()) { |
|
1369 case Qt::Key_Up: |
|
1370 granularity = ScrollByLine; |
|
1371 direction = ScrollUp; |
|
1372 break; |
|
1373 case Qt::Key_Down: |
|
1374 granularity = ScrollByLine; |
|
1375 direction = ScrollDown; |
|
1376 break; |
|
1377 case Qt::Key_Left: |
|
1378 granularity = ScrollByLine; |
|
1379 direction = ScrollLeft; |
|
1380 break; |
|
1381 case Qt::Key_Right: |
|
1382 granularity = ScrollByLine; |
|
1383 direction = ScrollRight; |
|
1384 break; |
|
1385 default: |
|
1386 return false; |
|
1387 } |
|
1388 } |
|
1389 |
|
1390 return frame->eventHandler()->scrollRecursively(direction, granularity); |
|
1391 } |
|
1392 |
|
1393 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) |
|
1394 bool QWebPagePrivate::touchEvent(QTouchEvent* event) |
|
1395 { |
|
1396 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); |
|
1397 if (!frame->view()) |
|
1398 return false; |
|
1399 |
|
1400 // Always accept the QTouchEvent so that we'll receive also TouchUpdate and TouchEnd events |
|
1401 event->setAccepted(true); |
|
1402 |
|
1403 // Return whether the default action was cancelled in the JS event handler |
|
1404 return frame->eventHandler()->handleTouchEvent(PlatformTouchEvent(event)); |
|
1405 } |
|
1406 #endif |
|
1407 |
|
1408 /*! |
|
1409 This method is used by the input method to query a set of properties of the page |
|
1410 to be able to support complex input method operations as support for surrounding |
|
1411 text and reconversions. |
|
1412 |
|
1413 \a property specifies which property is queried. |
|
1414 |
|
1415 \sa QWidget::inputMethodEvent(), QInputMethodEvent, QInputContext |
|
1416 */ |
|
1417 QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const |
|
1418 { |
|
1419 Frame* frame = d->page->focusController()->focusedFrame(); |
|
1420 if (!frame) |
|
1421 return QVariant(); |
|
1422 |
|
1423 WebCore::Editor* editor = frame->editor(); |
|
1424 |
|
1425 RenderObject* renderer = 0; |
|
1426 RenderTextControl* renderTextControl = 0; |
|
1427 |
|
1428 if (frame->selection()->rootEditableElement()) |
|
1429 renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); |
|
1430 |
|
1431 if (renderer && renderer->isTextControl()) |
|
1432 renderTextControl = toRenderTextControl(renderer); |
|
1433 |
|
1434 switch (property) { |
|
1435 case Qt::ImMicroFocus: { |
|
1436 WebCore::FrameView* view = frame->view(); |
|
1437 if (view && view->needsLayout()) { |
|
1438 // We can't access absoluteCaretBounds() while the view needs to layout. |
|
1439 return QVariant(); |
|
1440 } |
|
1441 return QVariant(view->contentsToWindow(frame->selection()->absoluteCaretBounds())); |
|
1442 } |
|
1443 case Qt::ImFont: { |
|
1444 if (renderTextControl) { |
|
1445 RenderStyle* renderStyle = renderTextControl->style(); |
|
1446 return QVariant(QFont(renderStyle->font().font())); |
|
1447 } |
|
1448 return QVariant(QFont()); |
|
1449 } |
|
1450 case Qt::ImCursorPosition: { |
|
1451 if (renderTextControl) { |
|
1452 if (editor->hasComposition()) { |
|
1453 RefPtr<Range> range = editor->compositionRange(); |
|
1454 return QVariant(renderTextControl->selectionEnd() - TextIterator::rangeLength(range.get())); |
|
1455 } |
|
1456 return QVariant(frame->selection()->extent().offsetInContainerNode()); |
|
1457 } |
|
1458 return QVariant(); |
|
1459 } |
|
1460 case Qt::ImSurroundingText: { |
|
1461 if (renderTextControl) { |
|
1462 QString text = renderTextControl->text(); |
|
1463 RefPtr<Range> range = editor->compositionRange(); |
|
1464 if (range) { |
|
1465 text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get())); |
|
1466 } |
|
1467 return QVariant(text); |
|
1468 } |
|
1469 return QVariant(); |
|
1470 } |
|
1471 case Qt::ImCurrentSelection: { |
|
1472 if (renderTextControl) { |
|
1473 int start = renderTextControl->selectionStart(); |
|
1474 int end = renderTextControl->selectionEnd(); |
|
1475 if (end > start) |
|
1476 return QVariant(QString(renderTextControl->text()).mid(start,end-start)); |
|
1477 } |
|
1478 return QVariant(); |
|
1479 |
|
1480 } |
|
1481 #if QT_VERSION >= 0x040600 |
|
1482 case Qt::ImAnchorPosition: { |
|
1483 if (renderTextControl) { |
|
1484 if (editor->hasComposition()) { |
|
1485 RefPtr<Range> range = editor->compositionRange(); |
|
1486 return QVariant(renderTextControl->selectionStart() - TextIterator::rangeLength(range.get())); |
|
1487 } |
|
1488 return QVariant(frame->selection()->base().offsetInContainerNode()); |
|
1489 } |
|
1490 return QVariant(); |
|
1491 } |
|
1492 case Qt::ImMaximumTextLength: { |
|
1493 if (frame->selection()->isContentEditable()) { |
|
1494 if (frame->document() && frame->document()->focusedNode()) { |
|
1495 if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { |
|
1496 HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); |
|
1497 return QVariant(inputElement->maxLength()); |
|
1498 } |
|
1499 } |
|
1500 return QVariant(InputElement::s_maximumLength); |
|
1501 } |
|
1502 return QVariant(0); |
|
1503 } |
|
1504 #endif |
|
1505 default: |
|
1506 return QVariant(); |
|
1507 } |
|
1508 } |
|
1509 |
|
1510 /*! |
|
1511 \internal |
|
1512 */ |
|
1513 void QWebPagePrivate::setInspector(QWebInspector* insp) |
|
1514 { |
|
1515 if (inspector) |
|
1516 inspector->d->setFrontend(0); |
|
1517 |
|
1518 if (inspectorIsInternalOnly) { |
|
1519 QWebInspector* inspToDelete = inspector; |
|
1520 inspector = 0; |
|
1521 inspectorIsInternalOnly = false; |
|
1522 delete inspToDelete; // Delete after to prevent infinite recursion |
|
1523 } |
|
1524 |
|
1525 inspector = insp; |
|
1526 |
|
1527 // Give inspector frontend web view if previously created |
|
1528 if (inspector && inspectorFrontend) |
|
1529 inspector->d->setFrontend(inspectorFrontend); |
|
1530 } |
|
1531 |
|
1532 /*! |
|
1533 \internal |
|
1534 Returns the inspector and creates it if it wasn't created yet. |
|
1535 The instance created here will not be available through QWebPage's API. |
|
1536 */ |
|
1537 QWebInspector* QWebPagePrivate::getOrCreateInspector() |
|
1538 { |
|
1539 #if ENABLE(INSPECTOR) |
|
1540 if (!inspector) { |
|
1541 QWebInspector* insp = new QWebInspector; |
|
1542 insp->setPage(q); |
|
1543 inspectorIsInternalOnly = true; |
|
1544 |
|
1545 Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q) |
|
1546 } |
|
1547 #endif |
|
1548 return inspector; |
|
1549 } |
|
1550 |
|
1551 /*! \internal */ |
|
1552 InspectorController* QWebPagePrivate::inspectorController() |
|
1553 { |
|
1554 #if ENABLE(INSPECTOR) |
|
1555 return page->inspectorController(); |
|
1556 #else |
|
1557 return 0; |
|
1558 #endif |
|
1559 } |
|
1560 |
|
1561 |
|
1562 /*! |
|
1563 \enum QWebPage::FindFlag |
|
1564 |
|
1565 This enum describes the options available to the findText() function. The options |
|
1566 can be OR-ed together from the following list: |
|
1567 |
|
1568 \value FindBackward Searches backwards instead of forwards. |
|
1569 \value FindCaseSensitively By default findText() works case insensitive. Specifying this option |
|
1570 changes the behaviour to a case sensitive find operation. |
|
1571 \value FindWrapsAroundDocument Makes findText() restart from the beginning of the document if the end |
|
1572 was reached and the text was not found. |
|
1573 \value HighlightAllOccurrences Highlights all existing occurrences of a specific string. |
|
1574 */ |
|
1575 |
|
1576 /*! |
|
1577 \enum QWebPage::LinkDelegationPolicy |
|
1578 |
|
1579 This enum defines the delegation policies a webpage can have when activating links and emitting |
|
1580 the linkClicked() signal. |
|
1581 |
|
1582 \value DontDelegateLinks No links are delegated. Instead, QWebPage tries to handle them all. |
|
1583 \value DelegateExternalLinks When activating links that point to documents not stored on the |
|
1584 local filesystem or an equivalent - such as the Qt resource system - then linkClicked() is emitted. |
|
1585 \value DelegateAllLinks Whenever a link is activated the linkClicked() signal is emitted. |
|
1586 |
|
1587 \sa QWebPage::linkDelegationPolicy |
|
1588 */ |
|
1589 |
|
1590 /*! |
|
1591 \enum QWebPage::NavigationType |
|
1592 |
|
1593 This enum describes the types of navigation available when browsing through hyperlinked |
|
1594 documents. |
|
1595 |
|
1596 \value NavigationTypeLinkClicked The user clicked on a link or pressed return on a focused link. |
|
1597 \value NavigationTypeFormSubmitted The user activated a submit button for an HTML form. |
|
1598 \value NavigationTypeBackOrForward Navigation to a previously shown document in the back or forward history is requested. |
|
1599 \value NavigationTypeReload The user activated the reload action. |
|
1600 \value NavigationTypeFormResubmitted An HTML form was submitted a second time. |
|
1601 \value NavigationTypeOther A navigation to another document using a method not listed above. |
|
1602 |
|
1603 \sa acceptNavigationRequest() |
|
1604 */ |
|
1605 |
|
1606 /*! |
|
1607 \enum QWebPage::WebAction |
|
1608 |
|
1609 This enum describes the types of action which can be performed on the web page. |
|
1610 |
|
1611 Actions only have an effect when they are applicable. The availability of |
|
1612 actions can be be determined by checking \l{QAction::}{isEnabled()} on the |
|
1613 action returned by action(). |
|
1614 |
|
1615 One method of enabling the text editing, cursor movement, and text selection actions |
|
1616 is by setting \l contentEditable to true. |
|
1617 |
|
1618 \value NoWebAction No action is triggered. |
|
1619 \value OpenLink Open the current link. |
|
1620 \value OpenLinkInNewWindow Open the current link in a new window. |
|
1621 \value OpenFrameInNewWindow Replicate the current frame in a new window. |
|
1622 \value DownloadLinkToDisk Download the current link to the disk. |
|
1623 \value CopyLinkToClipboard Copy the current link to the clipboard. |
|
1624 \value OpenImageInNewWindow Open the highlighted image in a new window. |
|
1625 \value DownloadImageToDisk Download the highlighted image to the disk. |
|
1626 \value CopyImageToClipboard Copy the highlighted image to the clipboard. |
|
1627 \value Back Navigate back in the history of navigated links. |
|
1628 \value Forward Navigate forward in the history of navigated links. |
|
1629 \value Stop Stop loading the current page. |
|
1630 \value StopScheduledPageRefresh Stop all pending page refresh/redirect requests. |
|
1631 \value Reload Reload the current page. |
|
1632 \value ReloadAndBypassCache Reload the current page, but do not use any local cache. (Added in Qt 4.6) |
|
1633 \value Cut Cut the content currently selected into the clipboard. |
|
1634 \value Copy Copy the content currently selected into the clipboard. |
|
1635 \value Paste Paste content from the clipboard. |
|
1636 \value Undo Undo the last editing action. |
|
1637 \value Redo Redo the last editing action. |
|
1638 \value MoveToNextChar Move the cursor to the next character. |
|
1639 \value MoveToPreviousChar Move the cursor to the previous character. |
|
1640 \value MoveToNextWord Move the cursor to the next word. |
|
1641 \value MoveToPreviousWord Move the cursor to the previous word. |
|
1642 \value MoveToNextLine Move the cursor to the next line. |
|
1643 \value MoveToPreviousLine Move the cursor to the previous line. |
|
1644 \value MoveToStartOfLine Move the cursor to the start of the line. |
|
1645 \value MoveToEndOfLine Move the cursor to the end of the line. |
|
1646 \value MoveToStartOfBlock Move the cursor to the start of the block. |
|
1647 \value MoveToEndOfBlock Move the cursor to the end of the block. |
|
1648 \value MoveToStartOfDocument Move the cursor to the start of the document. |
|
1649 \value MoveToEndOfDocument Move the cursor to the end of the document. |
|
1650 \value SelectNextChar Select to the next character. |
|
1651 \value SelectPreviousChar Select to the previous character. |
|
1652 \value SelectNextWord Select to the next word. |
|
1653 \value SelectPreviousWord Select to the previous word. |
|
1654 \value SelectNextLine Select to the next line. |
|
1655 \value SelectPreviousLine Select to the previous line. |
|
1656 \value SelectStartOfLine Select to the start of the line. |
|
1657 \value SelectEndOfLine Select to the end of the line. |
|
1658 \value SelectStartOfBlock Select to the start of the block. |
|
1659 \value SelectEndOfBlock Select to the end of the block. |
|
1660 \value SelectStartOfDocument Select to the start of the document. |
|
1661 \value SelectEndOfDocument Select to the end of the document. |
|
1662 \value DeleteStartOfWord Delete to the start of the word. |
|
1663 \value DeleteEndOfWord Delete to the end of the word. |
|
1664 \value SetTextDirectionDefault Set the text direction to the default direction. |
|
1665 \value SetTextDirectionLeftToRight Set the text direction to left-to-right. |
|
1666 \value SetTextDirectionRightToLeft Set the text direction to right-to-left. |
|
1667 \value ToggleBold Toggle the formatting between bold and normal weight. |
|
1668 \value ToggleItalic Toggle the formatting between italic and normal style. |
|
1669 \value ToggleUnderline Toggle underlining. |
|
1670 \value InspectElement Show the Web Inspector with the currently highlighted HTML element. |
|
1671 \value InsertParagraphSeparator Insert a new paragraph. |
|
1672 \value InsertLineSeparator Insert a new line. |
|
1673 \value SelectAll Selects all content. |
|
1674 \value PasteAndMatchStyle Paste content from the clipboard with current style. |
|
1675 \value RemoveFormat Removes formatting and style. |
|
1676 \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style. |
|
1677 \value ToggleSubscript Toggle the formatting between subscript and baseline. |
|
1678 \value ToggleSuperscript Toggle the formatting between supercript and baseline. |
|
1679 \value InsertUnorderedList Toggles the selection between an ordered list and a normal block. |
|
1680 \value InsertOrderedList Toggles the selection between an ordered list and a normal block. |
|
1681 \value Indent Increases the indentation of the currently selected format block by one increment. |
|
1682 \value Outdent Decreases the indentation of the currently selected format block by one increment. |
|
1683 \value AlignCenter Applies center alignment to content. |
|
1684 \value AlignJustified Applies full justification to content. |
|
1685 \value AlignLeft Applies left justification to content. |
|
1686 \value AlignRight Applies right justification to content. |
|
1687 |
|
1688 |
|
1689 \omitvalue WebActionCount |
|
1690 |
|
1691 */ |
|
1692 |
|
1693 /*! |
|
1694 \enum QWebPage::WebWindowType |
|
1695 |
|
1696 This enum describes the types of window that can be created by the createWindow() function. |
|
1697 |
|
1698 \value WebBrowserWindow The window is a regular web browser window. |
|
1699 \value WebModalDialog The window acts as modal dialog. |
|
1700 */ |
|
1701 |
|
1702 |
|
1703 /*! |
|
1704 \class QWebPage::ViewportHints |
|
1705 \since 4.7 |
|
1706 \brief The QWebPage::ViewportHints class describes hints that can be applied to a viewport. |
|
1707 |
|
1708 QWebPage::ViewportHints provides a description of a viewport, such as viewport geometry, |
|
1709 initial scale factor with limits, plus information about whether a user should be able |
|
1710 to scale the contents in the viewport or not, ie. by zooming. |
|
1711 |
|
1712 ViewportHints can be set by a web author using the viewport meta tag extension, documented |
|
1713 at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}. |
|
1714 |
|
1715 All values might not be set, as such when dealing with the hints, the developer needs to |
|
1716 check whether the values are valid. Negative values denote an invalid qreal value. |
|
1717 |
|
1718 \inmodule QtWebKit |
|
1719 */ |
|
1720 |
|
1721 /*! |
|
1722 Constructs an empty QWebPage::ViewportHints. |
|
1723 */ |
|
1724 QWebPage::ViewportHints::ViewportHints() |
|
1725 : d(0) |
|
1726 , m_initialScaleFactor(-1.0) |
|
1727 , m_minimumScaleFactor(-1.0) |
|
1728 , m_maximumScaleFactor(-1.0) |
|
1729 , m_isUserScalable(true) |
|
1730 , m_isValid(false) |
|
1731 { |
|
1732 |
|
1733 } |
|
1734 |
|
1735 /*! |
|
1736 Constructs a QWebPage::ViewportHints which is a copy from \a other . |
|
1737 */ |
|
1738 QWebPage::ViewportHints::ViewportHints(const QWebPage::ViewportHints& other) |
|
1739 : d(other.d) |
|
1740 , m_initialScaleFactor(other.m_initialScaleFactor) |
|
1741 , m_minimumScaleFactor(other.m_minimumScaleFactor) |
|
1742 , m_maximumScaleFactor(other.m_maximumScaleFactor) |
|
1743 , m_isUserScalable(other.m_isUserScalable) |
|
1744 , m_isValid(other.m_isValid) |
|
1745 , m_size(other.m_size) |
|
1746 { |
|
1747 |
|
1748 } |
|
1749 |
|
1750 /*! |
|
1751 Destroys the QWebPage::ViewportHints. |
|
1752 */ |
|
1753 QWebPage::ViewportHints::~ViewportHints() |
|
1754 { |
|
1755 |
|
1756 } |
|
1757 |
|
1758 /*! |
|
1759 Assigns the given QWebPage::ViewportHints to this viewport hints and returns a |
|
1760 reference to this. |
|
1761 */ |
|
1762 QWebPage::ViewportHints& QWebPage::ViewportHints::operator=(const QWebPage::ViewportHints& other) |
|
1763 { |
|
1764 if (this != &other) { |
|
1765 d = other.d; |
|
1766 m_initialScaleFactor = other.m_initialScaleFactor; |
|
1767 m_minimumScaleFactor = other.m_minimumScaleFactor; |
|
1768 m_maximumScaleFactor = other.m_maximumScaleFactor; |
|
1769 m_isUserScalable = other.m_isUserScalable; |
|
1770 m_isValid = other.m_isValid; |
|
1771 m_size = other.m_size; |
|
1772 } |
|
1773 |
|
1774 return *this; |
|
1775 } |
|
1776 |
|
1777 /*! \fn inline bool QWebPage::ViewportHints::isValid() const |
|
1778 Returns whether this is a valid ViewportHints or not. |
|
1779 |
|
1780 An invalid ViewportHints will have an empty QSize, negative values for scale factors and |
|
1781 true for the boolean isUserScalable. |
|
1782 */ |
|
1783 |
|
1784 /*! \fn inline QSize QWebPage::ViewportHints::size() const |
|
1785 Returns the size of the viewport. |
|
1786 */ |
|
1787 |
|
1788 /*! \fn inline qreal QWebPage::ViewportHints::initialScaleFactor() const |
|
1789 Returns the initial scale of the viewport as a multiplier. |
|
1790 */ |
|
1791 |
|
1792 /*! \fn inline qreal QWebPage::ViewportHints::minimumScaleFactor() const |
|
1793 Returns the minimum scale value of the viewport as a multiplier. |
|
1794 */ |
|
1795 |
|
1796 /*! \fn inline qreal QWebPage::ViewportHints::maximumScaleFactor() const |
|
1797 Returns the maximum scale value of the viewport as a multiplier. |
|
1798 */ |
|
1799 |
|
1800 /*! \fn inline bool QWebPage::ViewportHints::isUserScalable() const |
|
1801 Determines whether or not the scale can be modified by the user. |
|
1802 */ |
|
1803 |
|
1804 |
|
1805 /*! |
|
1806 \class QWebPage |
|
1807 \since 4.4 |
|
1808 \brief The QWebPage class provides an object to view and edit web documents. |
|
1809 |
|
1810 \inmodule QtWebKit |
|
1811 |
|
1812 QWebPage holds a main frame responsible for web content, settings, the history |
|
1813 of navigated links and actions. This class can be used, together with QWebFrame, |
|
1814 to provide functionality like QWebView in a widget-less environment. |
|
1815 |
|
1816 QWebPage's API is very similar to QWebView, as you are still provided with |
|
1817 common functions like action() (known as |
|
1818 \l{QWebView::pageAction()}{pageAction}() in QWebView), triggerAction(), |
|
1819 findText() and settings(). More QWebView-like functions can be found in the |
|
1820 main frame of QWebPage, obtained via the mainFrame() function. For example, |
|
1821 the \l{QWebFrame::load()}{load}(), \l{QWebFrame::setUrl()}{setUrl}() and |
|
1822 \l{QWebFrame::setHtml()}{setHtml}() functions for QWebPage can be accessed |
|
1823 using QWebFrame. |
|
1824 |
|
1825 The loadStarted() signal is emitted when the page begins to load.The |
|
1826 loadProgress() signal, on the other hand, is emitted whenever an element |
|
1827 of the web page completes loading, such as an embedded image, a script, |
|
1828 etc. Finally, the loadFinished() signal is emitted when the page has |
|
1829 loaded completely. Its argument, either true or false, indicates whether |
|
1830 or not the load operation succeeded. |
|
1831 |
|
1832 \section1 Using QWebPage in a Widget-less Environment |
|
1833 |
|
1834 Before you begin painting a QWebPage object, you need to set the size of |
|
1835 the viewport by calling setViewportSize(). Then, you invoke the main |
|
1836 frame's render function (QWebFrame::render()). An example of this |
|
1837 is shown in the code snippet below. |
|
1838 |
|
1839 Suppose we have a \c Thumbnail class as follows: |
|
1840 |
|
1841 \snippet webkitsnippets/webpage/main.cpp 0 |
|
1842 |
|
1843 The \c Thumbnail's constructor takes in a \a url. We connect our QWebPage |
|
1844 object's \l{QWebPage::}{loadFinished()} signal to our private slot, |
|
1845 \c render(). |
|
1846 |
|
1847 \snippet webkitsnippets/webpage/main.cpp 1 |
|
1848 |
|
1849 The \c render() function shows how we can paint a thumbnail using a |
|
1850 QWebPage object. |
|
1851 |
|
1852 \snippet webkitsnippets/webpage/main.cpp 2 |
|
1853 |
|
1854 We begin by setting the \l{QWebPage::viewportSize()}{viewportSize} and |
|
1855 then we instantiate a QImage object, \c image, with the same size as our |
|
1856 \l{QWebPage::viewportSize()}{viewportSize}. This image is then sent |
|
1857 as a parameter to \c painter. Next, we render the contents of the main |
|
1858 frame and its subframes into \c painter. Finally, we save the scaled image. |
|
1859 |
|
1860 \sa QWebFrame |
|
1861 */ |
|
1862 |
|
1863 /*! |
|
1864 Constructs an empty QWebPage with parent \a parent. |
|
1865 */ |
|
1866 QWebPage::QWebPage(QObject *parent) |
|
1867 : QObject(parent) |
|
1868 , d(new QWebPagePrivate(this)) |
|
1869 { |
|
1870 setView(qobject_cast<QWidget*>(parent)); |
|
1871 |
|
1872 connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int))); |
|
1873 #ifndef NDEBUG |
|
1874 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages())); |
|
1875 #endif |
|
1876 } |
|
1877 |
|
1878 /*! |
|
1879 Destroys the web page. |
|
1880 */ |
|
1881 QWebPage::~QWebPage() |
|
1882 { |
|
1883 d->createMainFrame(); |
|
1884 FrameLoader *loader = d->mainFrame->d->frame->loader(); |
|
1885 if (loader) |
|
1886 loader->detachFromParent(); |
|
1887 if (d->inspector) { |
|
1888 // Since we have to delete an internal inspector, |
|
1889 // call setInspector(0) directly to prevent potential crashes |
|
1890 if (d->inspectorIsInternalOnly) |
|
1891 d->setInspector(0); |
|
1892 else |
|
1893 d->inspector->setPage(0); |
|
1894 } |
|
1895 delete d; |
|
1896 } |
|
1897 |
|
1898 /*! |
|
1899 Returns the main frame of the page. |
|
1900 |
|
1901 The main frame provides access to the hierarchy of sub-frames and is also needed if you |
|
1902 want to explicitly render a web page into a given painter. |
|
1903 |
|
1904 \sa currentFrame() |
|
1905 */ |
|
1906 QWebFrame *QWebPage::mainFrame() const |
|
1907 { |
|
1908 d->createMainFrame(); |
|
1909 return d->mainFrame; |
|
1910 } |
|
1911 |
|
1912 /*! |
|
1913 Returns the frame currently active. |
|
1914 |
|
1915 \sa mainFrame(), frameCreated() |
|
1916 */ |
|
1917 QWebFrame *QWebPage::currentFrame() const |
|
1918 { |
|
1919 d->createMainFrame(); |
|
1920 return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame(); |
|
1921 } |
|
1922 |
|
1923 |
|
1924 /*! |
|
1925 \since 4.6 |
|
1926 |
|
1927 Returns the frame at the given point \a pos, or 0 if there is no frame at |
|
1928 that position. |
|
1929 |
|
1930 \sa mainFrame(), currentFrame() |
|
1931 */ |
|
1932 QWebFrame* QWebPage::frameAt(const QPoint& pos) const |
|
1933 { |
|
1934 QWebFrame* webFrame = mainFrame(); |
|
1935 if (!webFrame->geometry().contains(pos)) |
|
1936 return 0; |
|
1937 QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos); |
|
1938 return hitTestResult.frame(); |
|
1939 } |
|
1940 |
|
1941 /*! |
|
1942 Returns a pointer to the view's history of navigated web pages. |
|
1943 */ |
|
1944 QWebHistory *QWebPage::history() const |
|
1945 { |
|
1946 d->createMainFrame(); |
|
1947 return &d->history; |
|
1948 } |
|
1949 |
|
1950 /*! |
|
1951 Sets the \a view that is associated with the web page. |
|
1952 |
|
1953 \sa view() |
|
1954 */ |
|
1955 void QWebPage::setView(QWidget* view) |
|
1956 { |
|
1957 if (this->view() == view) |
|
1958 return; |
|
1959 |
|
1960 d->view = view; |
|
1961 setViewportSize(view ? view->size() : QSize(0, 0)); |
|
1962 |
|
1963 // If we have no client, we install a special client delegating |
|
1964 // the responsibility to the QWidget. This is the code path |
|
1965 // handling a.o. the "legacy" QWebView. |
|
1966 // |
|
1967 // If such a special delegate already exist, we substitute the view. |
|
1968 |
|
1969 if (d->client) { |
|
1970 if (d->client->isQWidgetClient()) |
|
1971 static_cast<PageClientQWidget*>(d->client)->view = view; |
|
1972 return; |
|
1973 } |
|
1974 |
|
1975 if (view) |
|
1976 d->client = new PageClientQWidget(view); |
|
1977 } |
|
1978 |
|
1979 /*! |
|
1980 Returns the view widget that is associated with the web page. |
|
1981 |
|
1982 \sa setView() |
|
1983 */ |
|
1984 QWidget *QWebPage::view() const |
|
1985 { |
|
1986 #if QT_VERSION < 0x040600 |
|
1987 return d->view; |
|
1988 #else |
|
1989 return d->view.data(); |
|
1990 #endif |
|
1991 } |
|
1992 |
|
1993 /*! |
|
1994 This function is called whenever a JavaScript program tries to print a \a message to the web browser's console. |
|
1995 |
|
1996 For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber. |
|
1997 |
|
1998 The default implementation prints nothing. |
|
1999 */ |
|
2000 void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) |
|
2001 { |
|
2002 Q_UNUSED(sourceID) |
|
2003 |
|
2004 // Catch plugin logDestroy message for LayoutTests/plugins/open-and-close-window-with-plugin.html |
|
2005 // At this point DRT's WebPage has already been destroyed |
|
2006 if (QWebPagePrivate::drtRun) { |
|
2007 if (message == "PLUGIN: NPP_Destroy") |
|
2008 fprintf (stdout, "CONSOLE MESSAGE: line %d: %s\n", lineNumber, message.toUtf8().constData()); |
|
2009 } |
|
2010 } |
|
2011 |
|
2012 /*! |
|
2013 This function is called whenever a JavaScript program running inside \a frame calls the alert() function with |
|
2014 the message \a msg. |
|
2015 |
|
2016 The default implementation shows the message, \a msg, with QMessageBox::information. |
|
2017 */ |
|
2018 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) |
|
2019 { |
|
2020 Q_UNUSED(frame) |
|
2021 #ifndef QT_NO_MESSAGEBOX |
|
2022 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
2023 QMessageBox::information(parent, tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Ok); |
|
2024 #endif |
|
2025 } |
|
2026 |
|
2027 /*! |
|
2028 This function is called whenever a JavaScript program running inside \a frame calls the confirm() function |
|
2029 with the message, \a msg. Returns true if the user confirms the message; otherwise returns false. |
|
2030 |
|
2031 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. |
|
2032 */ |
|
2033 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) |
|
2034 { |
|
2035 Q_UNUSED(frame) |
|
2036 #ifdef QT_NO_MESSAGEBOX |
|
2037 return true; |
|
2038 #else |
|
2039 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
2040 return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Yes, QMessageBox::No); |
|
2041 #endif |
|
2042 } |
|
2043 |
|
2044 /*! |
|
2045 This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input. |
|
2046 The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue. |
|
2047 |
|
2048 If the prompt was cancelled by the user the implementation should return false; otherwise the |
|
2049 result should be written to \a result and true should be returned. If the prompt was not cancelled by the |
|
2050 user, the implementation should return true and the result string must not be null. |
|
2051 |
|
2052 The default implementation uses QInputDialog::getText(). |
|
2053 */ |
|
2054 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result) |
|
2055 { |
|
2056 Q_UNUSED(frame) |
|
2057 bool ok = false; |
|
2058 #ifndef QT_NO_INPUTDIALOG |
|
2059 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
2060 QString x = QInputDialog::getText(parent, tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QLineEdit::Normal, defaultValue, &ok); |
|
2061 if (ok && result) |
|
2062 *result = x; |
|
2063 #endif |
|
2064 return ok; |
|
2065 } |
|
2066 |
|
2067 /*! |
|
2068 \fn bool QWebPage::shouldInterruptJavaScript() |
|
2069 \since 4.6 |
|
2070 This function is called when a JavaScript program is running for a long period of time. |
|
2071 |
|
2072 If the user wanted to stop the JavaScript the implementation should return true; otherwise false. |
|
2073 |
|
2074 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. |
|
2075 |
|
2076 \warning Because of binary compatibility constraints, this function is not virtual. If you want to |
|
2077 provide your own implementation in a QWebPage subclass, reimplement the shouldInterruptJavaScript() |
|
2078 slot in your subclass instead. QtWebKit will dynamically detect the slot and call it. |
|
2079 */ |
|
2080 bool QWebPage::shouldInterruptJavaScript() |
|
2081 { |
|
2082 #ifdef QT_NO_MESSAGEBOX |
|
2083 return false; |
|
2084 #else |
|
2085 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
2086 return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No); |
|
2087 #endif |
|
2088 } |
|
2089 |
|
2090 /*! |
|
2091 \fn bool QWebPage::allowGeolocationRequest() |
|
2092 \since 4.7 |
|
2093 |
|
2094 This function is called whenever a JavaScript program running inside \a frame tries to access user location through navigator.geolocation. |
|
2095 |
|
2096 If the user wants to allow access to location then it should return true; otherwise false. |
|
2097 |
|
2098 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. |
|
2099 |
|
2100 \warning Because of binary compatibility constraints, this function is not virtual. If you want to |
|
2101 provide your own implementation in a QWebPage subclass, reimplement the allowGeolocationRequest() |
|
2102 slot in your subclass instead. QtWebKit will dynamically detect the slot and call it. |
|
2103 */ |
|
2104 bool QWebPage::allowGeolocationRequest(QWebFrame *frame) |
|
2105 { |
|
2106 #ifdef QT_NO_MESSAGEBOX |
|
2107 return false; |
|
2108 #else |
|
2109 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
2110 return QMessageBox::Yes == QMessageBox::information(parent, tr("Location Request by- %1").arg(frame->url().host()), tr("The page wants to access your location information. Do you want to allow the request?"), QMessageBox::Yes, QMessageBox::No); |
|
2111 #endif |
|
2112 } |
|
2113 |
|
2114 void QWebPage::setUserPermission(QWebFrame* frame, PermissionDomain domain, PermissionPolicy policy) |
|
2115 { |
|
2116 switch (domain) { |
|
2117 case NotificationsPermissionDomain: |
|
2118 #if ENABLE(NOTIFICATIONS) |
|
2119 if (policy == PermissionGranted) |
|
2120 NotificationPresenterClientQt::notificationPresenter()->allowNotificationForFrame(frame); |
|
2121 #endif |
|
2122 break; |
|
2123 default: |
|
2124 break; |
|
2125 } |
|
2126 } |
|
2127 |
|
2128 /*! |
|
2129 This function is called whenever WebKit wants to create a new window of the given \a type, for |
|
2130 example when a JavaScript program requests to open a document in a new window. |
|
2131 |
|
2132 If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned. |
|
2133 |
|
2134 If the view associated with the web page is a QWebView object, then the default implementation forwards |
|
2135 the request to QWebView's createWindow() function; otherwise it returns a null pointer. |
|
2136 |
|
2137 If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window. |
|
2138 |
|
2139 \sa acceptNavigationRequest() |
|
2140 */ |
|
2141 QWebPage *QWebPage::createWindow(WebWindowType type) |
|
2142 { |
|
2143 QWebView *webView = qobject_cast<QWebView*>(view()); |
|
2144 if (webView) { |
|
2145 QWebView *newView = webView->createWindow(type); |
|
2146 if (newView) |
|
2147 return newView->page(); |
|
2148 } |
|
2149 return 0; |
|
2150 } |
|
2151 |
|
2152 /*! |
|
2153 This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". It is |
|
2154 called regardless of the value of QWebSettings::PluginsEnabled. The \a classid, \a url, \a paramNames and \a paramValues |
|
2155 correspond to the HTML object element attributes and child elements to configure the embeddable object. |
|
2156 */ |
|
2157 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) |
|
2158 { |
|
2159 Q_UNUSED(classid) |
|
2160 Q_UNUSED(url) |
|
2161 Q_UNUSED(paramNames) |
|
2162 Q_UNUSED(paramValues) |
|
2163 return 0; |
|
2164 } |
|
2165 |
|
2166 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame) |
|
2167 { |
|
2168 WebCore::ResourceRequest rr(url, frame->loader()->outgoingReferrer()); |
|
2169 return WebCore::FrameLoadRequest(rr); |
|
2170 } |
|
2171 |
|
2172 static void openNewWindow(const QUrl& url, WebCore::Frame* frame) |
|
2173 { |
|
2174 if (Page* oldPage = frame->page()) { |
|
2175 WindowFeatures features; |
|
2176 if (Page* newPage = oldPage->chrome()->createWindow(frame, |
|
2177 frameLoadRequest(url, frame), features)) |
|
2178 newPage->chrome()->show(); |
|
2179 } |
|
2180 } |
|
2181 |
|
2182 static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list) |
|
2183 { |
|
2184 list << frame->childFrames(); |
|
2185 QListIterator<QWebFrame*> it(frame->childFrames()); |
|
2186 while (it.hasNext()) { |
|
2187 collectChildFrames(it.next(), list); |
|
2188 } |
|
2189 } |
|
2190 |
|
2191 /*! |
|
2192 This function can be called to trigger the specified \a action. |
|
2193 It is also called by QtWebKit if the user triggers the action, for example |
|
2194 through a context menu item. |
|
2195 |
|
2196 If \a action is a checkable action then \a checked specified whether the action |
|
2197 is toggled or not. |
|
2198 |
|
2199 \sa action() |
|
2200 */ |
|
2201 void QWebPage::triggerAction(WebAction action, bool) |
|
2202 { |
|
2203 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame(); |
|
2204 if (!frame) |
|
2205 return; |
|
2206 WebCore::Editor *editor = frame->editor(); |
|
2207 const char *command = 0; |
|
2208 |
|
2209 switch (action) { |
|
2210 case OpenLink: |
|
2211 if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) { |
|
2212 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame; |
|
2213 targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()), |
|
2214 /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0, |
|
2215 /*FormState*/ 0, SendReferrer); |
|
2216 break; |
|
2217 } |
|
2218 // fall through |
|
2219 case OpenLinkInNewWindow: |
|
2220 openNewWindow(d->hitTestResult.linkUrl(), frame); |
|
2221 break; |
|
2222 case OpenFrameInNewWindow: { |
|
2223 KURL url = frame->loader()->documentLoader()->unreachableURL(); |
|
2224 if (url.isEmpty()) |
|
2225 url = frame->loader()->documentLoader()->url(); |
|
2226 openNewWindow(url, frame); |
|
2227 break; |
|
2228 } |
|
2229 case CopyLinkToClipboard: { |
|
2230 #if defined(Q_WS_X11) |
|
2231 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); |
|
2232 Pasteboard::generalPasteboard()->setSelectionMode(true); |
|
2233 editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText()); |
|
2234 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode); |
|
2235 #endif |
|
2236 editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText()); |
|
2237 break; |
|
2238 } |
|
2239 case OpenImageInNewWindow: |
|
2240 openNewWindow(d->hitTestResult.imageUrl(), frame); |
|
2241 break; |
|
2242 case DownloadImageToDisk: |
|
2243 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.imageUrl(), frame->loader()->outgoingReferrer())); |
|
2244 break; |
|
2245 case DownloadLinkToDisk: |
|
2246 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.linkUrl(), frame->loader()->outgoingReferrer())); |
|
2247 break; |
|
2248 #ifndef QT_NO_CLIPBOARD |
|
2249 case CopyImageToClipboard: |
|
2250 QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap()); |
|
2251 break; |
|
2252 #endif |
|
2253 case Back: |
|
2254 d->page->goBack(); |
|
2255 break; |
|
2256 case Forward: |
|
2257 d->page->goForward(); |
|
2258 break; |
|
2259 case Stop: |
|
2260 mainFrame()->d->frame->loader()->stopForUserCancel(); |
|
2261 break; |
|
2262 case Reload: |
|
2263 mainFrame()->d->frame->loader()->reload(/*endtoendreload*/false); |
|
2264 break; |
|
2265 case ReloadAndBypassCache: |
|
2266 mainFrame()->d->frame->loader()->reload(/*endtoendreload*/true); |
|
2267 break; |
|
2268 case SetTextDirectionDefault: |
|
2269 editor->setBaseWritingDirection(NaturalWritingDirection); |
|
2270 break; |
|
2271 case SetTextDirectionLeftToRight: |
|
2272 editor->setBaseWritingDirection(LeftToRightWritingDirection); |
|
2273 break; |
|
2274 case SetTextDirectionRightToLeft: |
|
2275 editor->setBaseWritingDirection(RightToLeftWritingDirection); |
|
2276 break; |
|
2277 case InspectElement: { |
|
2278 #if ENABLE(INSPECTOR) |
|
2279 if (!d->hitTestResult.isNull()) { |
|
2280 d->getOrCreateInspector(); // Make sure the inspector is created |
|
2281 d->inspector->show(); // The inspector is expected to be shown on inspection |
|
2282 d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get()); |
|
2283 } |
|
2284 #endif |
|
2285 break; |
|
2286 } |
|
2287 case StopScheduledPageRefresh: { |
|
2288 QWebFrame* topFrame = mainFrame(); |
|
2289 topFrame->d->frame->redirectScheduler()->cancel(); |
|
2290 QList<QWebFrame*> childFrames; |
|
2291 collectChildFrames(topFrame, childFrames); |
|
2292 QListIterator<QWebFrame*> it(childFrames); |
|
2293 while (it.hasNext()) |
|
2294 it.next()->d->frame->redirectScheduler()->cancel(); |
|
2295 break; |
|
2296 } |
|
2297 default: |
|
2298 command = QWebPagePrivate::editorCommandForWebActions(action); |
|
2299 break; |
|
2300 } |
|
2301 |
|
2302 if (command) |
|
2303 editor->command(command).execute(); |
|
2304 } |
|
2305 |
|
2306 QSize QWebPage::viewportSize() const |
|
2307 { |
|
2308 if (d->mainFrame && d->mainFrame->d->frame->view()) |
|
2309 return d->mainFrame->d->frame->view()->frameRect().size(); |
|
2310 |
|
2311 return d->viewportSize; |
|
2312 } |
|
2313 |
|
2314 /*! |
|
2315 \property QWebPage::viewportSize |
|
2316 \brief the size of the viewport |
|
2317 |
|
2318 The size affects for example the visibility of scrollbars |
|
2319 if the document is larger than the viewport. |
|
2320 |
|
2321 By default, for a newly-created Web page, this property contains a size with |
|
2322 zero width and height. |
|
2323 |
|
2324 \sa QWebFrame::render(), preferredContentsSize |
|
2325 */ |
|
2326 void QWebPage::setViewportSize(const QSize &size) const |
|
2327 { |
|
2328 d->viewportSize = size; |
|
2329 |
|
2330 QWebFrame *frame = mainFrame(); |
|
2331 if (frame->d->frame && frame->d->frame->view()) { |
|
2332 WebCore::FrameView* view = frame->d->frame->view(); |
|
2333 view->setFrameRect(QRect(QPoint(0, 0), size)); |
|
2334 view->adjustViewSize(); |
|
2335 } |
|
2336 } |
|
2337 |
|
2338 QSize QWebPage::preferredContentsSize() const |
|
2339 { |
|
2340 QWebFrame* frame = d->mainFrame; |
|
2341 if (frame) { |
|
2342 WebCore::FrameView* view = frame->d->frame->view(); |
|
2343 if (view && view->useFixedLayout()) |
|
2344 return d->mainFrame->d->frame->view()->fixedLayoutSize(); |
|
2345 } |
|
2346 |
|
2347 return d->fixedLayoutSize; |
|
2348 } |
|
2349 |
|
2350 /*! |
|
2351 \property QWebPage::preferredContentsSize |
|
2352 \since 4.6 |
|
2353 \brief a custom size used for laying out the page contents. |
|
2354 |
|
2355 By default all pages are laid out using the viewport of the page as the base. |
|
2356 |
|
2357 As pages mostly are designed for desktop usage, they often do not layout properly |
|
2358 on small devices as the contents require a certain view width. For this reason |
|
2359 it is common to use a different layout size and then scale the contents to fit |
|
2360 within the actual view. |
|
2361 |
|
2362 If this property is set to a valid size, this size is used for all layout needs |
|
2363 instead of the size of the viewport. |
|
2364 |
|
2365 Setting an invalid size, makes the page fall back to using the viewport size for layout. |
|
2366 |
|
2367 \sa viewportSize |
|
2368 */ |
|
2369 void QWebPage::setPreferredContentsSize(const QSize& size) const |
|
2370 { |
|
2371 // FIXME: Rename this method to setCustomLayoutSize |
|
2372 |
|
2373 d->fixedLayoutSize = size; |
|
2374 |
|
2375 QWebFrame* frame = mainFrame(); |
|
2376 if (!frame->d->frame || !frame->d->frame->view()) |
|
2377 return; |
|
2378 |
|
2379 WebCore::FrameView* view = frame->d->frame->view(); |
|
2380 |
|
2381 if (size.isValid()) { |
|
2382 view->setUseFixedLayout(true); |
|
2383 view->setFixedLayoutSize(size); |
|
2384 } else if (view->useFixedLayout()) |
|
2385 view->setUseFixedLayout(false); |
|
2386 |
|
2387 if (frame->d->initialLayoutComplete) |
|
2388 view->layout(); |
|
2389 } |
|
2390 |
|
2391 /*! |
|
2392 \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) |
|
2393 |
|
2394 This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of |
|
2395 the specified navigation type \a type. |
|
2396 |
|
2397 If \a frame is a null pointer then navigation to a new window is requested. If the request is |
|
2398 accepted createWindow() will be called. |
|
2399 |
|
2400 The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true |
|
2401 to let QWebPage handle the navigation itself. |
|
2402 |
|
2403 \sa createWindow() |
|
2404 */ |
|
2405 bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) |
|
2406 { |
|
2407 Q_UNUSED(frame) |
|
2408 if (type == NavigationTypeLinkClicked) { |
|
2409 switch (d->linkPolicy) { |
|
2410 case DontDelegateLinks: |
|
2411 return true; |
|
2412 |
|
2413 case DelegateExternalLinks: |
|
2414 if (WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(request.url().scheme())) |
|
2415 return true; |
|
2416 emit linkClicked(request.url()); |
|
2417 return false; |
|
2418 |
|
2419 case DelegateAllLinks: |
|
2420 emit linkClicked(request.url()); |
|
2421 return false; |
|
2422 } |
|
2423 } |
|
2424 return true; |
|
2425 } |
|
2426 |
|
2427 /*! |
|
2428 \property QWebPage::selectedText |
|
2429 \brief the text currently selected |
|
2430 |
|
2431 By default, this property contains an empty string. |
|
2432 |
|
2433 \sa selectionChanged() |
|
2434 */ |
|
2435 QString QWebPage::selectedText() const |
|
2436 { |
|
2437 d->createMainFrame(); |
|
2438 return d->page->focusController()->focusedOrMainFrame()->selectedText(); |
|
2439 } |
|
2440 |
|
2441 #ifndef QT_NO_ACTION |
|
2442 /*! |
|
2443 Returns a QAction for the specified WebAction \a action. |
|
2444 |
|
2445 The action is owned by the QWebPage but you can customize the look by |
|
2446 changing its properties. |
|
2447 |
|
2448 QWebPage also takes care of implementing the action, so that upon |
|
2449 triggering the corresponding action is performed on the page. |
|
2450 |
|
2451 \sa triggerAction() |
|
2452 */ |
|
2453 QAction *QWebPage::action(WebAction action) const |
|
2454 { |
|
2455 if (action == QWebPage::NoWebAction) return 0; |
|
2456 if (d->actions[action]) |
|
2457 return d->actions[action]; |
|
2458 |
|
2459 QString text; |
|
2460 QIcon icon; |
|
2461 QStyle *style = d->client ? d->client->style() : qApp->style(); |
|
2462 bool checkable = false; |
|
2463 |
|
2464 switch (action) { |
|
2465 case OpenLink: |
|
2466 text = contextMenuItemTagOpenLink(); |
|
2467 break; |
|
2468 case OpenLinkInNewWindow: |
|
2469 text = contextMenuItemTagOpenLinkInNewWindow(); |
|
2470 break; |
|
2471 case OpenFrameInNewWindow: |
|
2472 text = contextMenuItemTagOpenFrameInNewWindow(); |
|
2473 break; |
|
2474 |
|
2475 case DownloadLinkToDisk: |
|
2476 text = contextMenuItemTagDownloadLinkToDisk(); |
|
2477 break; |
|
2478 case CopyLinkToClipboard: |
|
2479 text = contextMenuItemTagCopyLinkToClipboard(); |
|
2480 break; |
|
2481 |
|
2482 case OpenImageInNewWindow: |
|
2483 text = contextMenuItemTagOpenImageInNewWindow(); |
|
2484 break; |
|
2485 case DownloadImageToDisk: |
|
2486 text = contextMenuItemTagDownloadImageToDisk(); |
|
2487 break; |
|
2488 case CopyImageToClipboard: |
|
2489 text = contextMenuItemTagCopyImageToClipboard(); |
|
2490 break; |
|
2491 |
|
2492 case Back: |
|
2493 text = contextMenuItemTagGoBack(); |
|
2494 icon = style->standardIcon(QStyle::SP_ArrowBack); |
|
2495 break; |
|
2496 case Forward: |
|
2497 text = contextMenuItemTagGoForward(); |
|
2498 icon = style->standardIcon(QStyle::SP_ArrowForward); |
|
2499 break; |
|
2500 case Stop: |
|
2501 text = contextMenuItemTagStop(); |
|
2502 icon = style->standardIcon(QStyle::SP_BrowserStop); |
|
2503 break; |
|
2504 case Reload: |
|
2505 text = contextMenuItemTagReload(); |
|
2506 icon = style->standardIcon(QStyle::SP_BrowserReload); |
|
2507 break; |
|
2508 |
|
2509 case Cut: |
|
2510 text = contextMenuItemTagCut(); |
|
2511 break; |
|
2512 case Copy: |
|
2513 text = contextMenuItemTagCopy(); |
|
2514 break; |
|
2515 case Paste: |
|
2516 text = contextMenuItemTagPaste(); |
|
2517 break; |
|
2518 #ifndef QT_NO_UNDOSTACK |
|
2519 case Undo: { |
|
2520 QAction *a = undoStack()->createUndoAction(d->q); |
|
2521 d->actions[action] = a; |
|
2522 return a; |
|
2523 } |
|
2524 case Redo: { |
|
2525 QAction *a = undoStack()->createRedoAction(d->q); |
|
2526 d->actions[action] = a; |
|
2527 return a; |
|
2528 } |
|
2529 #endif // QT_NO_UNDOSTACK |
|
2530 case MoveToNextChar: |
|
2531 text = tr("Move the cursor to the next character"); |
|
2532 break; |
|
2533 case MoveToPreviousChar: |
|
2534 text = tr("Move the cursor to the previous character"); |
|
2535 break; |
|
2536 case MoveToNextWord: |
|
2537 text = tr("Move the cursor to the next word"); |
|
2538 break; |
|
2539 case MoveToPreviousWord: |
|
2540 text = tr("Move the cursor to the previous word"); |
|
2541 break; |
|
2542 case MoveToNextLine: |
|
2543 text = tr("Move the cursor to the next line"); |
|
2544 break; |
|
2545 case MoveToPreviousLine: |
|
2546 text = tr("Move the cursor to the previous line"); |
|
2547 break; |
|
2548 case MoveToStartOfLine: |
|
2549 text = tr("Move the cursor to the start of the line"); |
|
2550 break; |
|
2551 case MoveToEndOfLine: |
|
2552 text = tr("Move the cursor to the end of the line"); |
|
2553 break; |
|
2554 case MoveToStartOfBlock: |
|
2555 text = tr("Move the cursor to the start of the block"); |
|
2556 break; |
|
2557 case MoveToEndOfBlock: |
|
2558 text = tr("Move the cursor to the end of the block"); |
|
2559 break; |
|
2560 case MoveToStartOfDocument: |
|
2561 text = tr("Move the cursor to the start of the document"); |
|
2562 break; |
|
2563 case MoveToEndOfDocument: |
|
2564 text = tr("Move the cursor to the end of the document"); |
|
2565 break; |
|
2566 case SelectAll: |
|
2567 text = tr("Select all"); |
|
2568 break; |
|
2569 case SelectNextChar: |
|
2570 text = tr("Select to the next character"); |
|
2571 break; |
|
2572 case SelectPreviousChar: |
|
2573 text = tr("Select to the previous character"); |
|
2574 break; |
|
2575 case SelectNextWord: |
|
2576 text = tr("Select to the next word"); |
|
2577 break; |
|
2578 case SelectPreviousWord: |
|
2579 text = tr("Select to the previous word"); |
|
2580 break; |
|
2581 case SelectNextLine: |
|
2582 text = tr("Select to the next line"); |
|
2583 break; |
|
2584 case SelectPreviousLine: |
|
2585 text = tr("Select to the previous line"); |
|
2586 break; |
|
2587 case SelectStartOfLine: |
|
2588 text = tr("Select to the start of the line"); |
|
2589 break; |
|
2590 case SelectEndOfLine: |
|
2591 text = tr("Select to the end of the line"); |
|
2592 break; |
|
2593 case SelectStartOfBlock: |
|
2594 text = tr("Select to the start of the block"); |
|
2595 break; |
|
2596 case SelectEndOfBlock: |
|
2597 text = tr("Select to the end of the block"); |
|
2598 break; |
|
2599 case SelectStartOfDocument: |
|
2600 text = tr("Select to the start of the document"); |
|
2601 break; |
|
2602 case SelectEndOfDocument: |
|
2603 text = tr("Select to the end of the document"); |
|
2604 break; |
|
2605 case DeleteStartOfWord: |
|
2606 text = tr("Delete to the start of the word"); |
|
2607 break; |
|
2608 case DeleteEndOfWord: |
|
2609 text = tr("Delete to the end of the word"); |
|
2610 break; |
|
2611 |
|
2612 case SetTextDirectionDefault: |
|
2613 text = contextMenuItemTagDefaultDirection(); |
|
2614 break; |
|
2615 case SetTextDirectionLeftToRight: |
|
2616 text = contextMenuItemTagLeftToRight(); |
|
2617 checkable = true; |
|
2618 break; |
|
2619 case SetTextDirectionRightToLeft: |
|
2620 text = contextMenuItemTagRightToLeft(); |
|
2621 checkable = true; |
|
2622 break; |
|
2623 |
|
2624 case ToggleBold: |
|
2625 text = contextMenuItemTagBold(); |
|
2626 checkable = true; |
|
2627 break; |
|
2628 case ToggleItalic: |
|
2629 text = contextMenuItemTagItalic(); |
|
2630 checkable = true; |
|
2631 break; |
|
2632 case ToggleUnderline: |
|
2633 text = contextMenuItemTagUnderline(); |
|
2634 checkable = true; |
|
2635 break; |
|
2636 |
|
2637 case InspectElement: |
|
2638 text = contextMenuItemTagInspectElement(); |
|
2639 break; |
|
2640 |
|
2641 case InsertParagraphSeparator: |
|
2642 text = tr("Insert a new paragraph"); |
|
2643 break; |
|
2644 case InsertLineSeparator: |
|
2645 text = tr("Insert a new line"); |
|
2646 break; |
|
2647 |
|
2648 case PasteAndMatchStyle: |
|
2649 text = tr("Paste and Match Style"); |
|
2650 break; |
|
2651 case RemoveFormat: |
|
2652 text = tr("Remove formatting"); |
|
2653 break; |
|
2654 |
|
2655 case ToggleStrikethrough: |
|
2656 text = tr("Strikethrough"); |
|
2657 checkable = true; |
|
2658 break; |
|
2659 case ToggleSubscript: |
|
2660 text = tr("Subscript"); |
|
2661 checkable = true; |
|
2662 break; |
|
2663 case ToggleSuperscript: |
|
2664 text = tr("Superscript"); |
|
2665 checkable = true; |
|
2666 break; |
|
2667 case InsertUnorderedList: |
|
2668 text = tr("Insert Bulleted List"); |
|
2669 checkable = true; |
|
2670 break; |
|
2671 case InsertOrderedList: |
|
2672 text = tr("Insert Numbered List"); |
|
2673 checkable = true; |
|
2674 break; |
|
2675 case Indent: |
|
2676 text = tr("Indent"); |
|
2677 break; |
|
2678 case Outdent: |
|
2679 text = tr("Outdent"); |
|
2680 break; |
|
2681 case AlignCenter: |
|
2682 text = tr("Center"); |
|
2683 break; |
|
2684 case AlignJustified: |
|
2685 text = tr("Justify"); |
|
2686 break; |
|
2687 case AlignLeft: |
|
2688 text = tr("Align Left"); |
|
2689 break; |
|
2690 case AlignRight: |
|
2691 text = tr("Align Right"); |
|
2692 break; |
|
2693 |
|
2694 case NoWebAction: |
|
2695 return 0; |
|
2696 } |
|
2697 |
|
2698 if (text.isEmpty()) |
|
2699 return 0; |
|
2700 |
|
2701 QAction *a = new QAction(d->q); |
|
2702 a->setText(text); |
|
2703 a->setData(action); |
|
2704 a->setCheckable(checkable); |
|
2705 a->setIcon(icon); |
|
2706 |
|
2707 connect(a, SIGNAL(triggered(bool)), |
|
2708 this, SLOT(_q_webActionTriggered(bool))); |
|
2709 |
|
2710 d->actions[action] = a; |
|
2711 d->updateAction(action); |
|
2712 return a; |
|
2713 } |
|
2714 #endif // QT_NO_ACTION |
|
2715 |
|
2716 /*! |
|
2717 \property QWebPage::modified |
|
2718 \brief whether the page contains unsubmitted form data, or the contents have been changed. |
|
2719 |
|
2720 By default, this property is false. |
|
2721 |
|
2722 \sa contentsChanged(), contentEditable, undoStack() |
|
2723 */ |
|
2724 bool QWebPage::isModified() const |
|
2725 { |
|
2726 #ifdef QT_NO_UNDOSTACK |
|
2727 return false; |
|
2728 #else |
|
2729 if (!d->undoStack) |
|
2730 return false; |
|
2731 return d->undoStack->canUndo(); |
|
2732 #endif // QT_NO_UNDOSTACK |
|
2733 } |
|
2734 |
|
2735 #ifndef QT_NO_UNDOSTACK |
|
2736 /*! |
|
2737 Returns a pointer to the undo stack used for editable content. |
|
2738 |
|
2739 \sa modified |
|
2740 */ |
|
2741 QUndoStack *QWebPage::undoStack() const |
|
2742 { |
|
2743 if (!d->undoStack) |
|
2744 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this)); |
|
2745 |
|
2746 return d->undoStack; |
|
2747 } |
|
2748 #endif // QT_NO_UNDOSTACK |
|
2749 |
|
2750 /*! \reimp |
|
2751 */ |
|
2752 bool QWebPage::event(QEvent *ev) |
|
2753 { |
|
2754 switch (ev->type()) { |
|
2755 case QEvent::Timer: |
|
2756 d->timerEvent(static_cast<QTimerEvent*>(ev)); |
|
2757 break; |
|
2758 case QEvent::MouseMove: |
|
2759 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev)); |
|
2760 break; |
|
2761 case QEvent::GraphicsSceneMouseMove: |
|
2762 d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); |
|
2763 break; |
|
2764 case QEvent::MouseButtonPress: |
|
2765 d->mousePressEvent(static_cast<QMouseEvent*>(ev)); |
|
2766 break; |
|
2767 case QEvent::GraphicsSceneMousePress: |
|
2768 d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); |
|
2769 break; |
|
2770 case QEvent::MouseButtonDblClick: |
|
2771 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev)); |
|
2772 break; |
|
2773 case QEvent::GraphicsSceneMouseDoubleClick: |
|
2774 d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); |
|
2775 break; |
|
2776 case QEvent::MouseButtonRelease: |
|
2777 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev)); |
|
2778 break; |
|
2779 case QEvent::GraphicsSceneMouseRelease: |
|
2780 d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); |
|
2781 break; |
|
2782 #ifndef QT_NO_CONTEXTMENU |
|
2783 case QEvent::ContextMenu: |
|
2784 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos()); |
|
2785 break; |
|
2786 case QEvent::GraphicsSceneContextMenu: |
|
2787 d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos()); |
|
2788 break; |
|
2789 #endif |
|
2790 #ifndef QT_NO_WHEELEVENT |
|
2791 case QEvent::Wheel: |
|
2792 d->wheelEvent(static_cast<QWheelEvent*>(ev)); |
|
2793 break; |
|
2794 case QEvent::GraphicsSceneWheel: |
|
2795 d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev)); |
|
2796 break; |
|
2797 #endif |
|
2798 case QEvent::KeyPress: |
|
2799 d->keyPressEvent(static_cast<QKeyEvent*>(ev)); |
|
2800 break; |
|
2801 case QEvent::KeyRelease: |
|
2802 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev)); |
|
2803 break; |
|
2804 case QEvent::FocusIn: |
|
2805 d->focusInEvent(static_cast<QFocusEvent*>(ev)); |
|
2806 break; |
|
2807 case QEvent::FocusOut: |
|
2808 d->focusOutEvent(static_cast<QFocusEvent*>(ev)); |
|
2809 break; |
|
2810 #ifndef QT_NO_DRAGANDDROP |
|
2811 case QEvent::DragEnter: |
|
2812 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev)); |
|
2813 break; |
|
2814 case QEvent::GraphicsSceneDragEnter: |
|
2815 d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); |
|
2816 break; |
|
2817 case QEvent::DragLeave: |
|
2818 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev)); |
|
2819 break; |
|
2820 case QEvent::GraphicsSceneDragLeave: |
|
2821 d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); |
|
2822 break; |
|
2823 case QEvent::DragMove: |
|
2824 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev)); |
|
2825 break; |
|
2826 case QEvent::GraphicsSceneDragMove: |
|
2827 d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); |
|
2828 break; |
|
2829 case QEvent::Drop: |
|
2830 d->dropEvent(static_cast<QDropEvent*>(ev)); |
|
2831 break; |
|
2832 case QEvent::GraphicsSceneDrop: |
|
2833 d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); |
|
2834 break; |
|
2835 #endif |
|
2836 case QEvent::InputMethod: |
|
2837 d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev)); |
|
2838 case QEvent::ShortcutOverride: |
|
2839 d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev)); |
|
2840 break; |
|
2841 case QEvent::Leave: |
|
2842 d->leaveEvent(ev); |
|
2843 break; |
|
2844 #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) |
|
2845 case QEvent::TouchBegin: |
|
2846 case QEvent::TouchUpdate: |
|
2847 case QEvent::TouchEnd: |
|
2848 // Return whether the default action was cancelled in the JS event handler |
|
2849 return d->touchEvent(static_cast<QTouchEvent*>(ev)); |
|
2850 #endif |
|
2851 #ifndef QT_NO_PROPERTIES |
|
2852 case QEvent::DynamicPropertyChange: |
|
2853 d->dynamicPropertyChangeEvent(static_cast<QDynamicPropertyChangeEvent*>(ev)); |
|
2854 break; |
|
2855 #endif |
|
2856 default: |
|
2857 return QObject::event(ev); |
|
2858 } |
|
2859 |
|
2860 return true; |
|
2861 } |
|
2862 |
|
2863 /*! |
|
2864 Similar to QWidget::focusNextPrevChild() it focuses the next focusable web element |
|
2865 if \a next is true; otherwise the previous element is focused. |
|
2866 |
|
2867 Returns true if it can find a new focusable element, or false if it can't. |
|
2868 */ |
|
2869 bool QWebPage::focusNextPrevChild(bool next) |
|
2870 { |
|
2871 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier)); |
|
2872 d->keyPressEvent(&ev); |
|
2873 bool hasFocusedNode = false; |
|
2874 Frame *frame = d->page->focusController()->focusedFrame(); |
|
2875 if (frame) { |
|
2876 Document *document = frame->document(); |
|
2877 hasFocusedNode = document && document->focusedNode(); |
|
2878 } |
|
2879 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode; |
|
2880 return hasFocusedNode; |
|
2881 } |
|
2882 |
|
2883 /*! |
|
2884 \property QWebPage::contentEditable |
|
2885 \brief whether the content in this QWebPage is editable or not |
|
2886 \since 4.5 |
|
2887 |
|
2888 If this property is enabled the contents of the page can be edited by the user through a visible |
|
2889 cursor. If disabled (the default) only HTML elements in the web page with their |
|
2890 \c{contenteditable} attribute set are editable. |
|
2891 |
|
2892 \sa modified, contentsChanged(), WebAction |
|
2893 */ |
|
2894 void QWebPage::setContentEditable(bool editable) |
|
2895 { |
|
2896 if (d->editable != editable) { |
|
2897 d->editable = editable; |
|
2898 d->page->setTabKeyCyclesThroughElements(!editable); |
|
2899 if (d->mainFrame) { |
|
2900 WebCore::Frame* frame = d->mainFrame->d->frame; |
|
2901 if (editable) { |
|
2902 frame->applyEditingStyleToBodyElement(); |
|
2903 // FIXME: mac port calls this if there is no selectedDOMRange |
|
2904 //frame->setSelectionFromNone(); |
|
2905 } |
|
2906 } |
|
2907 |
|
2908 d->updateEditorActions(); |
|
2909 } |
|
2910 } |
|
2911 |
|
2912 bool QWebPage::isContentEditable() const |
|
2913 { |
|
2914 return d->editable; |
|
2915 } |
|
2916 |
|
2917 /*! |
|
2918 \property QWebPage::forwardUnsupportedContent |
|
2919 \brief whether QWebPage should forward unsupported content |
|
2920 |
|
2921 If enabled, the unsupportedContent() signal is emitted with a network reply that |
|
2922 can be used to read the content. |
|
2923 |
|
2924 If disabled, the download of such content is aborted immediately. |
|
2925 |
|
2926 By default unsupported content is not forwarded. |
|
2927 */ |
|
2928 |
|
2929 void QWebPage::setForwardUnsupportedContent(bool forward) |
|
2930 { |
|
2931 d->forwardUnsupportedContent = forward; |
|
2932 } |
|
2933 |
|
2934 bool QWebPage::forwardUnsupportedContent() const |
|
2935 { |
|
2936 return d->forwardUnsupportedContent; |
|
2937 } |
|
2938 |
|
2939 /*! |
|
2940 \property QWebPage::linkDelegationPolicy |
|
2941 \brief how QWebPage should delegate the handling of links through the |
|
2942 linkClicked() signal |
|
2943 |
|
2944 The default is to delegate no links. |
|
2945 */ |
|
2946 |
|
2947 void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy) |
|
2948 { |
|
2949 d->linkPolicy = policy; |
|
2950 } |
|
2951 |
|
2952 QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const |
|
2953 { |
|
2954 return d->linkPolicy; |
|
2955 } |
|
2956 |
|
2957 #ifndef QT_NO_CONTEXTMENU |
|
2958 /*! |
|
2959 Filters the context menu event, \a event, through handlers for scrollbars and |
|
2960 custom event handlers in the web page. Returns true if the event was handled; |
|
2961 otherwise false. |
|
2962 |
|
2963 A web page may swallow a context menu event through a custom event handler, allowing for context |
|
2964 menus to be implemented in HTML/JavaScript. This is used by \l{http://maps.google.com/}{Google |
|
2965 Maps}, for example. |
|
2966 */ |
|
2967 bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event) |
|
2968 { |
|
2969 d->page->contextMenuController()->clearContextMenu(); |
|
2970 |
|
2971 if (QWebFrame* webFrame = frameAt(event->pos())) { |
|
2972 Frame* frame = QWebFramePrivate::core(webFrame); |
|
2973 if (Scrollbar* scrollbar = frame->view()->scrollbarAtPoint(PlatformMouseEvent(event, 1).pos())) |
|
2974 return scrollbar->contextMenu(PlatformMouseEvent(event, 1)); |
|
2975 } |
|
2976 |
|
2977 WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame(); |
|
2978 focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(event, 1)); |
|
2979 ContextMenu *menu = d->page->contextMenuController()->contextMenu(); |
|
2980 // If the website defines its own handler then sendContextMenuEvent takes care of |
|
2981 // calling/showing it and the context menu pointer will be zero. This is the case |
|
2982 // on maps.google.com for example. |
|
2983 |
|
2984 return !menu; |
|
2985 } |
|
2986 #endif // QT_NO_CONTEXTMENU |
|
2987 |
|
2988 /*! |
|
2989 Updates the page's actions depending on the position \a pos. For example if \a pos is over an image |
|
2990 element the CopyImageToClipboard action is enabled. |
|
2991 */ |
|
2992 void QWebPage::updatePositionDependentActions(const QPoint &pos) |
|
2993 { |
|
2994 #ifndef QT_NO_ACTION |
|
2995 // First we disable all actions, but keep track of which ones were originally enabled. |
|
2996 QBitArray originallyEnabledWebActions(QWebPage::WebActionCount); |
|
2997 for (int i = ContextMenuItemTagNoAction; i < ContextMenuItemBaseApplicationTag; ++i) { |
|
2998 QWebPage::WebAction action = webActionForContextMenuAction(WebCore::ContextMenuAction(i)); |
|
2999 if (QAction *a = this->action(action)) { |
|
3000 originallyEnabledWebActions.setBit(action, a->isEnabled()); |
|
3001 a->setEnabled(false); |
|
3002 } |
|
3003 } |
|
3004 #endif // QT_NO_ACTION |
|
3005 |
|
3006 d->createMainFrame(); |
|
3007 WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame(); |
|
3008 HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), /*allowShadowContent*/ false); |
|
3009 |
|
3010 if (result.scrollbar()) |
|
3011 d->hitTestResult = QWebHitTestResult(); |
|
3012 else |
|
3013 d->hitTestResult = QWebHitTestResult(new QWebHitTestResultPrivate(result)); |
|
3014 WebCore::ContextMenu menu(result); |
|
3015 menu.populate(); |
|
3016 |
|
3017 #if ENABLE(INSPECTOR) |
|
3018 if (d->page->inspectorController()->enabled()) |
|
3019 menu.addInspectElementItem(); |
|
3020 #endif |
|
3021 |
|
3022 QBitArray visitedWebActions(QWebPage::WebActionCount); |
|
3023 |
|
3024 #ifndef QT_NO_CONTEXTMENU |
|
3025 delete d->currentContextMenu; |
|
3026 |
|
3027 // Then we let createContextMenu() enable the actions that are put into the menu |
|
3028 d->currentContextMenu = d->createContextMenu(&menu, menu.platformDescription(), &visitedWebActions); |
|
3029 #endif // QT_NO_CONTEXTMENU |
|
3030 |
|
3031 #ifndef QT_NO_ACTION |
|
3032 // Finally, we restore the original enablement for the actions that were not put into the menu. |
|
3033 originallyEnabledWebActions &= ~visitedWebActions; // Mask out visited actions (they're part of the menu) |
|
3034 for (int i = 0; i < QWebPage::WebActionCount; ++i) { |
|
3035 if (originallyEnabledWebActions.at(i)) { |
|
3036 if (QAction *a = this->action(QWebPage::WebAction(i))) |
|
3037 a->setEnabled(true); |
|
3038 } |
|
3039 } |
|
3040 #endif // QT_NO_ACTION |
|
3041 |
|
3042 // This whole process ensures that any actions put into to the context menu has the right |
|
3043 // enablement, while also keeping the correct enablement for actions that were left out of |
|
3044 // the menu. |
|
3045 |
|
3046 } |
|
3047 |
|
3048 |
|
3049 |
|
3050 /*! |
|
3051 \enum QWebPage::Extension |
|
3052 |
|
3053 This enum describes the types of extensions that the page can support. Before using these extensions, you |
|
3054 should verify that the extension is supported by calling supportsExtension(). |
|
3055 |
|
3056 \value ChooseMultipleFilesExtension Whether the web page supports multiple file selection. |
|
3057 This extension is invoked when the web content requests one or more file names, for example |
|
3058 as a result of the user clicking on a "file upload" button in a HTML form where multiple |
|
3059 file selection is allowed. |
|
3060 |
|
3061 \value ErrorPageExtension Whether the web page can provide an error page when loading fails. |
|
3062 (introduced in Qt 4.6) |
|
3063 |
|
3064 \sa ChooseMultipleFilesExtensionOption, ChooseMultipleFilesExtensionReturn, ErrorPageExtensionOption, ErrorPageExtensionReturn |
|
3065 */ |
|
3066 |
|
3067 /*! |
|
3068 \enum QWebPage::ErrorDomain |
|
3069 \since 4.6 |
|
3070 |
|
3071 This enum describes the domain of an ErrorPageExtensionOption object (i.e. the layer in which the error occurred). |
|
3072 |
|
3073 \value QtNetwork The error occurred in the QtNetwork layer; the error code is of type QNetworkReply::NetworkError. |
|
3074 \value Http The error occurred in the HTTP layer; the error code is a HTTP status code (see QNetworkRequest::HttpStatusCodeAttribute). |
|
3075 \value WebKit The error is an internal WebKit error. |
|
3076 */ |
|
3077 |
|
3078 /*! |
|
3079 \class QWebPage::ExtensionOption |
|
3080 \since 4.4 |
|
3081 \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support. |
|
3082 |
|
3083 \inmodule QtWebKit |
|
3084 |
|
3085 \sa QWebPage::extension() QWebPage::ExtensionReturn |
|
3086 */ |
|
3087 |
|
3088 |
|
3089 /*! |
|
3090 \class QWebPage::ExtensionReturn |
|
3091 \since 4.4 |
|
3092 \brief The ExtensionReturn class provides an output result from a QWebPage's extension. |
|
3093 |
|
3094 \inmodule QtWebKit |
|
3095 |
|
3096 \sa QWebPage::extension() QWebPage::ExtensionOption |
|
3097 */ |
|
3098 |
|
3099 /*! |
|
3100 \class QWebPage::ErrorPageExtensionOption |
|
3101 \since 4.6 |
|
3102 \brief The ErrorPageExtensionOption class describes the option |
|
3103 for the error page extension. |
|
3104 |
|
3105 \inmodule QtWebKit |
|
3106 |
|
3107 The ErrorPageExtensionOption class holds the \a url for which an error occurred as well as |
|
3108 the associated \a frame. |
|
3109 |
|
3110 The error itself is reported by an error \a domain, the \a error code as well as \a errorString. |
|
3111 |
|
3112 \sa QWebPage::extension() QWebPage::ErrorPageExtensionReturn |
|
3113 */ |
|
3114 |
|
3115 /*! |
|
3116 \variable QWebPage::ErrorPageExtensionOption::url |
|
3117 \brief the url for which an error occurred |
|
3118 */ |
|
3119 |
|
3120 /*! |
|
3121 \variable QWebPage::ErrorPageExtensionOption::frame |
|
3122 \brief the frame associated with the error |
|
3123 */ |
|
3124 |
|
3125 /*! |
|
3126 \variable QWebPage::ErrorPageExtensionOption::domain |
|
3127 \brief the domain that reported the error |
|
3128 */ |
|
3129 |
|
3130 /*! |
|
3131 \variable QWebPage::ErrorPageExtensionOption::error |
|
3132 \brief the error code. Interpretation of the value depends on the \a domain |
|
3133 \sa QWebPage::ErrorDomain |
|
3134 */ |
|
3135 |
|
3136 /*! |
|
3137 \variable QWebPage::ErrorPageExtensionOption::errorString |
|
3138 \brief a string that describes the error |
|
3139 */ |
|
3140 |
|
3141 /*! |
|
3142 \class QWebPage::ErrorPageExtensionReturn |
|
3143 \since 4.6 |
|
3144 \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the |
|
3145 frame for which the error occured. |
|
3146 |
|
3147 \inmodule QtWebKit |
|
3148 |
|
3149 The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are |
|
3150 optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which |
|
3151 is assumed to be UTF-8 if not indicated otherwise. |
|
3152 |
|
3153 The error page is stored in the \a content byte array, as HTML content. In order to convert a |
|
3154 QString to a byte array, the QString::toUtf8() method can be used. |
|
3155 |
|
3156 External objects such as stylesheets or images referenced in the HTML are located relative to |
|
3157 \a baseUrl. |
|
3158 |
|
3159 \sa QWebPage::extension() QWebPage::ErrorPageExtensionOption, QString::toUtf8() |
|
3160 */ |
|
3161 |
|
3162 /*! |
|
3163 \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn() |
|
3164 |
|
3165 Constructs a new error page object. |
|
3166 */ |
|
3167 |
|
3168 |
|
3169 /*! |
|
3170 \variable QWebPage::ErrorPageExtensionReturn::contentType |
|
3171 \brief the error page's content type |
|
3172 */ |
|
3173 |
|
3174 /*! |
|
3175 \variable QWebPage::ErrorPageExtensionReturn::encoding |
|
3176 \brief the error page encoding |
|
3177 */ |
|
3178 |
|
3179 /*! |
|
3180 \variable QWebPage::ErrorPageExtensionReturn::baseUrl |
|
3181 \brief the base url |
|
3182 |
|
3183 External objects such as stylesheets or images referenced in the HTML are located relative to this url. |
|
3184 */ |
|
3185 |
|
3186 /*! |
|
3187 \variable QWebPage::ErrorPageExtensionReturn::content |
|
3188 \brief the HTML content of the error page |
|
3189 */ |
|
3190 |
|
3191 /*! |
|
3192 \class QWebPage::ChooseMultipleFilesExtensionOption |
|
3193 \since 4.5 |
|
3194 \brief The ChooseMultipleFilesExtensionOption class describes the option |
|
3195 for the multiple files selection extension. |
|
3196 |
|
3197 \inmodule QtWebKit |
|
3198 |
|
3199 The ChooseMultipleFilesExtensionOption class holds the frame originating the request |
|
3200 and the suggested filenames which might be provided. |
|
3201 |
|
3202 \sa QWebPage::extension() QWebPage::chooseFile(), QWebPage::ChooseMultipleFilesExtensionReturn |
|
3203 */ |
|
3204 |
|
3205 /*! |
|
3206 \variable QWebPage::ChooseMultipleFilesExtensionOption::parentFrame |
|
3207 \brief The frame in which the request originated |
|
3208 */ |
|
3209 |
|
3210 /*! |
|
3211 \variable QWebPage::ChooseMultipleFilesExtensionOption::suggestedFileNames |
|
3212 \brief The suggested filenames |
|
3213 */ |
|
3214 |
|
3215 /*! |
|
3216 \variable QWebPage::ChooseMultipleFilesExtensionReturn::fileNames |
|
3217 \brief The selected filenames |
|
3218 */ |
|
3219 |
|
3220 /*! |
|
3221 \class QWebPage::ChooseMultipleFilesExtensionReturn |
|
3222 \since 4.5 |
|
3223 \brief The ChooseMultipleFilesExtensionReturn describes the return value |
|
3224 for the multiple files selection extension. |
|
3225 |
|
3226 \inmodule QtWebKit |
|
3227 |
|
3228 The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user |
|
3229 when the extension is invoked. |
|
3230 |
|
3231 \sa QWebPage::extension() QWebPage::ChooseMultipleFilesExtensionOption |
|
3232 */ |
|
3233 |
|
3234 /*! |
|
3235 This virtual function can be reimplemented in a QWebPage subclass to provide support for extensions. The \a option |
|
3236 argument is provided as input to the extension; the output results can be stored in \a output. |
|
3237 |
|
3238 The behavior of this function is determined by \a extension. The \a option |
|
3239 and \a output values are typically casted to the corresponding types (for |
|
3240 example, ChooseMultipleFilesExtensionOption and |
|
3241 ChooseMultipleFilesExtensionReturn for ChooseMultipleFilesExtension). |
|
3242 |
|
3243 You can call supportsExtension() to check if an extension is supported by the page. |
|
3244 |
|
3245 Returns true if the extension was called successfully; otherwise returns false. |
|
3246 |
|
3247 \sa supportsExtension(), Extension |
|
3248 */ |
|
3249 bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) |
|
3250 { |
|
3251 #ifndef QT_NO_FILEDIALOG |
|
3252 if (extension == ChooseMultipleFilesExtension) { |
|
3253 // FIXME: do not ignore suggestedFiles |
|
3254 QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames; |
|
3255 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
3256 QStringList names = QFileDialog::getOpenFileNames(parent, QString::null); |
|
3257 static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names; |
|
3258 return true; |
|
3259 } |
|
3260 #endif |
|
3261 |
|
3262 return false; |
|
3263 } |
|
3264 |
|
3265 /*! |
|
3266 This virtual function returns true if the web page supports \a extension; otherwise false is returned. |
|
3267 |
|
3268 \sa extension() |
|
3269 */ |
|
3270 bool QWebPage::supportsExtension(Extension extension) const |
|
3271 { |
|
3272 #ifndef QT_NO_FILEDIALOG |
|
3273 return extension == ChooseMultipleFilesExtension; |
|
3274 #else |
|
3275 Q_UNUSED(extension); |
|
3276 return false; |
|
3277 #endif |
|
3278 } |
|
3279 |
|
3280 /*! |
|
3281 Finds the specified string, \a subString, in the page, using the given \a options. |
|
3282 |
|
3283 If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences |
|
3284 that exist in the page. All subsequent calls will extend the highlight, rather than |
|
3285 replace it, with occurrences of the new string. |
|
3286 |
|
3287 If the HighlightAllOccurrences flag is not passed, the function will select an occurrence |
|
3288 and all subsequent calls will replace the current occurrence with the next one. |
|
3289 |
|
3290 To clear the selection, just pass an empty string. |
|
3291 |
|
3292 Returns true if \a subString was found; otherwise returns false. |
|
3293 */ |
|
3294 bool QWebPage::findText(const QString &subString, FindFlags options) |
|
3295 { |
|
3296 ::TextCaseSensitivity caseSensitivity = ::TextCaseInsensitive; |
|
3297 if (options & FindCaseSensitively) |
|
3298 caseSensitivity = ::TextCaseSensitive; |
|
3299 |
|
3300 if (options & HighlightAllOccurrences) { |
|
3301 if (subString.isEmpty()) { |
|
3302 d->page->unmarkAllTextMatches(); |
|
3303 return true; |
|
3304 } else |
|
3305 return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0); |
|
3306 } else { |
|
3307 if (subString.isEmpty()) { |
|
3308 d->page->mainFrame()->selection()->clear(); |
|
3309 Frame* frame = d->page->mainFrame()->tree()->firstChild(); |
|
3310 while (frame) { |
|
3311 frame->selection()->clear(); |
|
3312 frame = frame->tree()->traverseNextWithWrap(false); |
|
3313 } |
|
3314 } |
|
3315 ::FindDirection direction = ::FindDirectionForward; |
|
3316 if (options & FindBackward) |
|
3317 direction = ::FindDirectionBackward; |
|
3318 |
|
3319 const bool shouldWrap = options & FindWrapsAroundDocument; |
|
3320 |
|
3321 return d->page->findString(subString, caseSensitivity, direction, shouldWrap); |
|
3322 } |
|
3323 } |
|
3324 |
|
3325 /*! |
|
3326 Returns a pointer to the page's settings object. |
|
3327 |
|
3328 \sa QWebSettings::globalSettings() |
|
3329 */ |
|
3330 QWebSettings *QWebPage::settings() const |
|
3331 { |
|
3332 return d->settings; |
|
3333 } |
|
3334 |
|
3335 /*! |
|
3336 This function is called when the web content requests a file name, for example |
|
3337 as a result of the user clicking on a "file upload" button in a HTML form. |
|
3338 |
|
3339 A suggested filename may be provided in \a suggestedFile. The frame originating the |
|
3340 request is provided as \a parentFrame. |
|
3341 |
|
3342 \sa ChooseMultipleFilesExtension |
|
3343 */ |
|
3344 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile) |
|
3345 { |
|
3346 Q_UNUSED(parentFrame) |
|
3347 #ifndef QT_NO_FILEDIALOG |
|
3348 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; |
|
3349 return QFileDialog::getOpenFileName(parent, QString::null, suggestedFile); |
|
3350 #else |
|
3351 return QString::null; |
|
3352 #endif |
|
3353 } |
|
3354 |
|
3355 /*! |
|
3356 Sets the QNetworkAccessManager \a manager responsible for serving network requests for this |
|
3357 QWebPage. |
|
3358 |
|
3359 \note It is currently not supported to change the network access manager after the |
|
3360 QWebPage has used it. The results of doing this are undefined. |
|
3361 |
|
3362 \sa networkAccessManager() |
|
3363 */ |
|
3364 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager) |
|
3365 { |
|
3366 if (manager == d->networkManager) |
|
3367 return; |
|
3368 if (d->networkManager && d->networkManager->parent() == this) |
|
3369 delete d->networkManager; |
|
3370 d->networkManager = manager; |
|
3371 } |
|
3372 |
|
3373 /*! |
|
3374 Returns the QNetworkAccessManager that is responsible for serving network |
|
3375 requests for this QWebPage. |
|
3376 |
|
3377 \sa setNetworkAccessManager() |
|
3378 */ |
|
3379 QNetworkAccessManager *QWebPage::networkAccessManager() const |
|
3380 { |
|
3381 if (!d->networkManager) { |
|
3382 QWebPage *that = const_cast<QWebPage *>(this); |
|
3383 that->d->networkManager = new QNetworkAccessManager(that); |
|
3384 } |
|
3385 return d->networkManager; |
|
3386 } |
|
3387 |
|
3388 /*! |
|
3389 Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this |
|
3390 QWebPage. |
|
3391 |
|
3392 Note: The plugin factory is only used if the QWebSettings::PluginsEnabled attribute is enabled. |
|
3393 |
|
3394 \sa pluginFactory() |
|
3395 */ |
|
3396 void QWebPage::setPluginFactory(QWebPluginFactory *factory) |
|
3397 { |
|
3398 d->pluginFactory = factory; |
|
3399 } |
|
3400 |
|
3401 /*! |
|
3402 Returns the QWebPluginFactory that is responsible for creating plugins embedded into |
|
3403 this QWebPage. If no plugin factory is installed a null pointer is returned. |
|
3404 |
|
3405 \sa setPluginFactory() |
|
3406 */ |
|
3407 QWebPluginFactory *QWebPage::pluginFactory() const |
|
3408 { |
|
3409 return d->pluginFactory; |
|
3410 } |
|
3411 |
|
3412 /*! |
|
3413 This function is called when a user agent for HTTP requests is needed. You can reimplement this |
|
3414 function to dynamically return different user agents for different URLs, based on the \a url parameter. |
|
3415 |
|
3416 The default implementation returns the following value: |
|
3417 |
|
3418 "Mozilla/5.0 (%Platform%; %Security%; %Subplatform%; %Locale%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%" |
|
3419 |
|
3420 On mobile platforms such as Symbian S60 and Maemo, "Mobile Safari" is used instead of "Safari". |
|
3421 |
|
3422 In this string the following values are replaced at run-time: |
|
3423 \list |
|
3424 \o %Platform% and %Subplatform% are expanded to the windowing system and the operation system. |
|
3425 \o %Security% expands to U if SSL is enabled, otherwise N. SSL is enabled if QSslSocket::supportsSsl() returns true. |
|
3426 \o %Locale% is replaced with QLocale::name(). The locale is determined from the view of the QWebPage. If no view is set on the QWebPage, |
|
3427 then a default constructed QLocale is used instead. |
|
3428 \o %WebKitVersion% is the version of WebKit the application was compiled against. |
|
3429 \o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version. |
|
3430 \endlist |
|
3431 */ |
|
3432 QString QWebPage::userAgentForUrl(const QUrl&) const |
|
3433 { |
|
3434 // splitting the string in three and user QStringBuilder is better than using QString::arg() |
|
3435 static QString firstPart; |
|
3436 static QString secondPart; |
|
3437 static QString thirdPart; |
|
3438 |
|
3439 if (firstPart.isNull() || secondPart.isNull() || thirdPart.isNull()) { |
|
3440 QString firstPartTemp; |
|
3441 firstPartTemp.reserve(150); |
|
3442 firstPartTemp += QString::fromLatin1("Mozilla/5.0 (" |
|
3443 |
|
3444 // Platform |
|
3445 #ifdef Q_WS_MAC |
|
3446 "Macintosh" |
|
3447 #elif defined Q_WS_QWS |
|
3448 "QtEmbedded" |
|
3449 #elif defined Q_WS_WIN |
|
3450 "Windows" |
|
3451 #elif defined Q_WS_X11 |
|
3452 "X11" |
|
3453 #elif defined Q_OS_SYMBIAN |
|
3454 "Symbian" |
|
3455 #else |
|
3456 "Unknown" |
|
3457 #endif |
|
3458 ); |
|
3459 |
|
3460 #if defined Q_OS_SYMBIAN |
|
3461 QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); |
|
3462 switch (symbianVersion) { |
|
3463 case QSysInfo::SV_9_2: |
|
3464 firstPartTemp += QString::fromLatin1("OS/9.2"); |
|
3465 break; |
|
3466 case QSysInfo::SV_9_3: |
|
3467 firstPartTemp += QString::fromLatin1("OS/9.3"); |
|
3468 break; |
|
3469 case QSysInfo::SV_9_4: |
|
3470 firstPartTemp += QString::fromLatin1("OS/9.4"); |
|
3471 break; |
|
3472 case QSysInfo::SV_SF_2: |
|
3473 firstPartTemp += QString::fromLatin1("/2"); |
|
3474 break; |
|
3475 case QSysInfo::SV_SF_3: |
|
3476 firstPartTemp += QString::fromLatin1("/3"); |
|
3477 break; |
|
3478 case QSysInfo::SV_SF_4: |
|
3479 firstPartTemp += QString::fromLatin1("/4"); |
|
3480 default: |
|
3481 break; |
|
3482 } |
|
3483 #endif |
|
3484 |
|
3485 firstPartTemp += QString::fromLatin1("; "); |
|
3486 |
|
3487 // SSL support |
|
3488 #if !defined(QT_NO_OPENSSL) |
|
3489 // we could check QSslSocket::supportsSsl() here, but this makes |
|
3490 // OpenSSL, certificates etc being loaded in all cases were QWebPage |
|
3491 // is used. This loading is not needed for non-https. |
|
3492 firstPartTemp += QString::fromLatin1("U; "); |
|
3493 // this may lead to a false positive: We indicate SSL since it is |
|
3494 // compiled in even though supportsSsl() might return false |
|
3495 #else |
|
3496 firstPartTemp += QString::fromLatin1("N; "); |
|
3497 #endif |
|
3498 |
|
3499 // Operating system |
|
3500 #ifdef Q_OS_AIX |
|
3501 firstPartTemp += QString::fromLatin1("AIX"); |
|
3502 #elif defined Q_OS_WIN32 |
|
3503 |
|
3504 switch (QSysInfo::WindowsVersion) { |
|
3505 case QSysInfo::WV_32s: |
|
3506 firstPartTemp += QString::fromLatin1("Windows 3.1"); |
|
3507 break; |
|
3508 case QSysInfo::WV_95: |
|
3509 firstPartTemp += QString::fromLatin1("Windows 95"); |
|
3510 break; |
|
3511 case QSysInfo::WV_98: |
|
3512 firstPartTemp += QString::fromLatin1("Windows 98"); |
|
3513 break; |
|
3514 case QSysInfo::WV_Me: |
|
3515 firstPartTemp += QString::fromLatin1("Windows 98; Win 9x 4.90"); |
|
3516 break; |
|
3517 case QSysInfo::WV_NT: |
|
3518 firstPartTemp += QString::fromLatin1("WinNT4.0"); |
|
3519 break; |
|
3520 case QSysInfo::WV_2000: |
|
3521 firstPartTemp += QString::fromLatin1("Windows NT 5.0"); |
|
3522 break; |
|
3523 case QSysInfo::WV_XP: |
|
3524 firstPartTemp += QString::fromLatin1("Windows NT 5.1"); |
|
3525 break; |
|
3526 case QSysInfo::WV_2003: |
|
3527 firstPartTemp += QString::fromLatin1("Windows NT 5.2"); |
|
3528 break; |
|
3529 case QSysInfo::WV_VISTA: |
|
3530 firstPartTemp += QString::fromLatin1("Windows NT 6.0"); |
|
3531 break; |
|
3532 case QSysInfo::WV_WINDOWS7: |
|
3533 firstPartTemp += QString::fromLatin1("Windows NT 6.1"); |
|
3534 break; |
|
3535 case QSysInfo::WV_CE: |
|
3536 firstPartTemp += QString::fromLatin1("Windows CE"); |
|
3537 break; |
|
3538 case QSysInfo::WV_CENET: |
|
3539 firstPartTemp += QString::fromLatin1("Windows CE .NET"); |
|
3540 break; |
|
3541 case QSysInfo::WV_CE_5: |
|
3542 firstPartTemp += QString::fromLatin1("Windows CE 5.x"); |
|
3543 break; |
|
3544 case QSysInfo::WV_CE_6: |
|
3545 firstPartTemp += QString::fromLatin1("Windows CE 6.x"); |
|
3546 break; |
|
3547 } |
|
3548 |
|
3549 #elif defined Q_OS_DARWIN |
|
3550 #ifdef __i386__ || __x86_64__ |
|
3551 firstPartTemp += QString::fromLatin1("Intel Mac OS X"); |
|
3552 #else |
|
3553 firstPartTemp += QString::fromLatin1("PPC Mac OS X"); |
|
3554 #endif |
|
3555 |
|
3556 #elif defined Q_OS_BSDI |
|
3557 firstPartTemp += QString::fromLatin1("BSD"); |
|
3558 #elif defined Q_OS_BSD4 |
|
3559 firstPartTemp += QString::fromLatin1("BSD Four"); |
|
3560 #elif defined Q_OS_CYGWIN |
|
3561 firstPartTemp += QString::fromLatin1("Cygwin"); |
|
3562 #elif defined Q_OS_DGUX |
|
3563 firstPartTemp += QString::fromLatin1("DG/UX"); |
|
3564 #elif defined Q_OS_DYNIX |
|
3565 firstPartTemp += QString::fromLatin1("DYNIX/ptx"); |
|
3566 #elif defined Q_OS_FREEBSD |
|
3567 firstPartTemp += QString::fromLatin1("FreeBSD"); |
|
3568 #elif defined Q_OS_HPUX |
|
3569 firstPartTemp += QString::fromLatin1("HP-UX"); |
|
3570 #elif defined Q_OS_HURD |
|
3571 firstPartTemp += QString::fromLatin1("GNU Hurd"); |
|
3572 #elif defined Q_OS_IRIX |
|
3573 firstPartTemp += QString::fromLatin1("SGI Irix"); |
|
3574 #elif defined Q_OS_LINUX |
|
3575 |
|
3576 #if defined(__x86_64__) |
|
3577 firstPartTemp += QString::fromLatin1("Linux x86_64"); |
|
3578 #elif defined(__i386__) |
|
3579 firstPartTemp += QString::fromLatin1("Linux i686"); |
|
3580 #else |
|
3581 firstPartTemp += QString::fromLatin1("Linux"); |
|
3582 #endif |
|
3583 |
|
3584 #elif defined Q_OS_LYNX |
|
3585 firstPartTemp += QString::fromLatin1("LynxOS"); |
|
3586 #elif defined Q_OS_NETBSD |
|
3587 firstPartTemp += QString::fromLatin1("NetBSD"); |
|
3588 #elif defined Q_OS_OS2 |
|
3589 firstPartTemp += QString::fromLatin1("OS/2"); |
|
3590 #elif defined Q_OS_OPENBSD |
|
3591 firstPartTemp += QString::fromLatin1("OpenBSD"); |
|
3592 #elif defined Q_OS_OS2EMX |
|
3593 firstPartTemp += QString::fromLatin1("OS/2"); |
|
3594 #elif defined Q_OS_OSF |
|
3595 firstPartTemp += QString::fromLatin1("HP Tru64 UNIX"); |
|
3596 #elif defined Q_OS_QNX6 |
|
3597 firstPartTemp += QString::fromLatin1("QNX RTP Six"); |
|
3598 #elif defined Q_OS_QNX |
|
3599 firstPartTemp += QString::fromLatin1("QNX"); |
|
3600 #elif defined Q_OS_RELIANT |
|
3601 firstPartTemp += QString::fromLatin1("Reliant UNIX"); |
|
3602 #elif defined Q_OS_SCO |
|
3603 firstPartTemp += QString::fromLatin1("SCO OpenServer"); |
|
3604 #elif defined Q_OS_SOLARIS |
|
3605 firstPartTemp += QString::fromLatin1("Sun Solaris"); |
|
3606 #elif defined Q_OS_ULTRIX |
|
3607 firstPartTemp += QString::fromLatin1("DEC Ultrix"); |
|
3608 #elif defined Q_OS_SYMBIAN |
|
3609 firstPartTemp += QLatin1Char(' '); |
|
3610 QSysInfo::S60Version s60Version = QSysInfo::s60Version(); |
|
3611 switch (s60Version) { |
|
3612 case QSysInfo::SV_S60_3_1: |
|
3613 firstPartTemp += QString::fromLatin1("Series60/3.1"); |
|
3614 break; |
|
3615 case QSysInfo::SV_S60_3_2: |
|
3616 firstPartTemp += QString::fromLatin1("Series60/3.2"); |
|
3617 break; |
|
3618 case QSysInfo::SV_S60_5_0: |
|
3619 firstPartTemp += QString::fromLatin1("Series60/5.0"); |
|
3620 break; |
|
3621 default: |
|
3622 break; |
|
3623 } |
|
3624 #elif defined Q_OS_UNIX |
|
3625 firstPartTemp += QString::fromLatin1("UNIX BSD/SYSV system"); |
|
3626 #elif defined Q_OS_UNIXWARE |
|
3627 firstPartTemp += QString::fromLatin1("UnixWare Seven, Open UNIX Eight"); |
|
3628 #else |
|
3629 firstPartTemp += QString::fromLatin1("Unknown"); |
|
3630 #endif |
|
3631 |
|
3632 // language is the split |
|
3633 firstPartTemp += QString::fromLatin1("; "); |
|
3634 firstPartTemp.squeeze(); |
|
3635 firstPart = firstPartTemp; |
|
3636 |
|
3637 QString secondPartTemp; |
|
3638 secondPartTemp.reserve(150); |
|
3639 secondPartTemp += QString::fromLatin1(") "); |
|
3640 |
|
3641 // webkit/qt version |
|
3642 secondPartTemp += QString::fromLatin1("AppleWebKit/"); |
|
3643 secondPartTemp += qWebKitVersion(); |
|
3644 secondPartTemp += QString::fromLatin1(" (KHTML, like Gecko) "); |
|
3645 |
|
3646 |
|
3647 // Application name split the third part |
|
3648 secondPartTemp.squeeze(); |
|
3649 secondPart = secondPartTemp; |
|
3650 |
|
3651 QString thirdPartTemp; |
|
3652 thirdPartTemp.reserve(150); |
|
3653 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) |
|
3654 thirdPartTemp += QLatin1String(" Mobile Safari/"); |
|
3655 #else |
|
3656 thirdPartTemp += QLatin1String(" Safari/"); |
|
3657 #endif |
|
3658 thirdPartTemp += qWebKitVersion(); |
|
3659 thirdPartTemp.squeeze(); |
|
3660 thirdPart = thirdPartTemp; |
|
3661 Q_ASSERT(!firstPart.isNull()); |
|
3662 Q_ASSERT(!secondPart.isNull()); |
|
3663 Q_ASSERT(!thirdPart.isNull()); |
|
3664 } |
|
3665 |
|
3666 // Language |
|
3667 QString languageName; |
|
3668 if (d->client && d->client->ownerWidget()) |
|
3669 languageName = d->client->ownerWidget()->locale().name(); |
|
3670 else |
|
3671 languageName = QLocale().name(); |
|
3672 languageName.replace(QLatin1Char('_'), QLatin1Char('-')); |
|
3673 |
|
3674 // Application name/version |
|
3675 QString appName = QCoreApplication::applicationName(); |
|
3676 if (!appName.isEmpty()) { |
|
3677 QString appVer = QCoreApplication::applicationVersion(); |
|
3678 if (!appVer.isEmpty()) |
|
3679 appName.append(QLatin1Char('/') + appVer); |
|
3680 } else { |
|
3681 // Qt version |
|
3682 appName = QString::fromLatin1("Qt/") + QString::fromLatin1(qVersion()); |
|
3683 } |
|
3684 |
|
3685 return firstPart + languageName + secondPart + appName + thirdPart; |
|
3686 } |
|
3687 |
|
3688 |
|
3689 void QWebPagePrivate::_q_onLoadProgressChanged(int) |
|
3690 { |
|
3691 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad(); |
|
3692 m_bytesReceived = page->progress()->totalBytesReceived(); |
|
3693 } |
|
3694 |
|
3695 |
|
3696 /*! |
|
3697 Returns the total number of bytes that were received from the network to render the current page, |
|
3698 including extra content such as embedded images. |
|
3699 |
|
3700 \sa bytesReceived() |
|
3701 */ |
|
3702 quint64 QWebPage::totalBytes() const |
|
3703 { |
|
3704 return d->m_totalBytes; |
|
3705 } |
|
3706 |
|
3707 |
|
3708 /*! |
|
3709 Returns the number of bytes that were received from the network to render the current page. |
|
3710 |
|
3711 \sa totalBytes(), loadProgress() |
|
3712 */ |
|
3713 quint64 QWebPage::bytesReceived() const |
|
3714 { |
|
3715 return d->m_bytesReceived; |
|
3716 } |
|
3717 |
|
3718 /*! |
|
3719 \since 4.7 |
|
3720 \fn void QWebPage::viewportChangeRequested(const QWebPage::ViewportHints& hints) |
|
3721 |
|
3722 This signal is emitted before any layout of the contents, giving you the viewport \a arguments |
|
3723 the web page would like you to use when laying out its contents, including elements fixed to the |
|
3724 viewport. This viewport might be larger that your actual viewport, meaning that a initialScaleFactor |
|
3725 should be applied. When no scale is given, it is assumed that the contents should be scaled |
|
3726 such that the width of the scaled contents fits within the actual viewport. |
|
3727 |
|
3728 The minimum and maximum allowed scale represents the min and max values that the page |
|
3729 allows for scaling, and thus, affects the ability to zoom in on the page. |
|
3730 |
|
3731 Invalid values are supplied for the values not explicitly set by the web author; thus an |
|
3732 invalid viewport size, and negative values for scale factor and limits. The boolean |
|
3733 ViewportHints::isUserScalable is set to true. |
|
3734 |
|
3735 Page authors can provide the supplied values by using the viewport meta tag. More information |
|
3736 about this can be found at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}. |
|
3737 |
|
3738 \sa QWebPage::ViewportHints, setPreferredContentsSize(), QGraphicsWebView::setScale() |
|
3739 */ |
|
3740 |
|
3741 /*! |
|
3742 \fn void QWebPage::loadStarted() |
|
3743 |
|
3744 This signal is emitted when a new load of the page is started. |
|
3745 |
|
3746 \sa loadFinished() |
|
3747 */ |
|
3748 |
|
3749 /*! |
|
3750 \fn void QWebPage::loadProgress(int progress) |
|
3751 |
|
3752 This signal is emitted when the global progress status changes. |
|
3753 The current value is provided by \a progress and scales from 0 to 100, |
|
3754 which is the default range of QProgressBar. |
|
3755 It accumulates changes from all the child frames. |
|
3756 |
|
3757 \sa bytesReceived() |
|
3758 */ |
|
3759 |
|
3760 /*! |
|
3761 \fn void QWebPage::loadFinished(bool ok) |
|
3762 |
|
3763 This signal is emitted when a load of the page is finished. |
|
3764 \a ok will indicate whether the load was successful or any error occurred. |
|
3765 |
|
3766 \sa loadStarted(), ErrorPageExtension |
|
3767 */ |
|
3768 |
|
3769 /*! |
|
3770 \fn void QWebPage::linkHovered(const QString &link, const QString &title, const QString &textContent) |
|
3771 |
|
3772 This signal is emitted when the mouse hovers over a link. |
|
3773 |
|
3774 \a link contains the link url. |
|
3775 \a title is the link element's title, if it is specified in the markup. |
|
3776 \a textContent provides text within the link element, e.g., text inside an HTML anchor tag. |
|
3777 |
|
3778 When the mouse leaves the link element the signal is emitted with empty parameters. |
|
3779 |
|
3780 \sa linkClicked() |
|
3781 */ |
|
3782 |
|
3783 /*! |
|
3784 \fn void QWebPage::statusBarMessage(const QString& text) |
|
3785 |
|
3786 This signal is emitted when the statusbar \a text is changed by the page. |
|
3787 */ |
|
3788 |
|
3789 /*! |
|
3790 \fn void QWebPage::frameCreated(QWebFrame *frame) |
|
3791 |
|
3792 This signal is emitted whenever the page creates a new \a frame. |
|
3793 |
|
3794 \sa currentFrame() |
|
3795 */ |
|
3796 |
|
3797 /*! |
|
3798 \fn void QWebPage::selectionChanged() |
|
3799 |
|
3800 This signal is emitted whenever the selection changes, either interactively |
|
3801 or programmatically (e.g. by calling triggerAction() with a selection action). |
|
3802 |
|
3803 \sa selectedText() |
|
3804 */ |
|
3805 |
|
3806 /*! |
|
3807 \fn void QWebPage::contentsChanged() |
|
3808 \since 4.5 |
|
3809 |
|
3810 This signal is emitted whenever the text in form elements changes |
|
3811 as well as other editable content. |
|
3812 |
|
3813 \sa contentEditable, modified, QWebFrame::toHtml(), QWebFrame::toPlainText() |
|
3814 */ |
|
3815 |
|
3816 /*! |
|
3817 \fn void QWebPage::geometryChangeRequested(const QRect& geom) |
|
3818 |
|
3819 This signal is emitted whenever the document wants to change the position and size of the |
|
3820 page to \a geom. This can happen for example through JavaScript. |
|
3821 */ |
|
3822 |
|
3823 /*! |
|
3824 \fn void QWebPage::repaintRequested(const QRect& dirtyRect) |
|
3825 |
|
3826 This signal is emitted whenever this QWebPage should be updated and no view was set. |
|
3827 \a dirtyRect contains the area that needs to be updated. To paint the QWebPage get |
|
3828 the mainFrame() and call the render(QPainter*, const QRegion&) method with the |
|
3829 \a dirtyRect as the second parameter. |
|
3830 |
|
3831 \sa mainFrame() |
|
3832 \sa view() |
|
3833 */ |
|
3834 |
|
3835 /*! |
|
3836 \fn void QWebPage::scrollRequested(int dx, int dy, const QRect& rectToScroll) |
|
3837 |
|
3838 This signal is emitted whenever the content given by \a rectToScroll needs |
|
3839 to be scrolled \a dx and \a dy downwards and no view was set. |
|
3840 |
|
3841 \sa view() |
|
3842 */ |
|
3843 |
|
3844 /*! |
|
3845 \fn void QWebPage::windowCloseRequested() |
|
3846 |
|
3847 This signal is emitted whenever the page requests the web browser window to be closed, |
|
3848 for example through the JavaScript \c{window.close()} call. |
|
3849 */ |
|
3850 |
|
3851 /*! |
|
3852 \fn void QWebPage::printRequested(QWebFrame *frame) |
|
3853 |
|
3854 This signal is emitted whenever the page requests the web browser to print \a frame, |
|
3855 for example through the JavaScript \c{window.print()} call. |
|
3856 |
|
3857 \sa QWebFrame::print(), QPrintPreviewDialog |
|
3858 */ |
|
3859 |
|
3860 /*! |
|
3861 \fn void QWebPage::unsupportedContent(QNetworkReply *reply) |
|
3862 |
|
3863 This signal is emitted when WebKit cannot handle a link the user navigated to or a |
|
3864 web server's response includes a "Content-Disposition" header with the 'attachment' |
|
3865 directive. If "Content-Disposition" is present in \a reply, the web server is indicating |
|
3866 that the client should prompt the user to save the content regardless of content-type. |
|
3867 See RFC 2616 sections 19.5.1 for details about Content-Disposition. |
|
3868 |
|
3869 At signal emission time the meta-data of the QNetworkReply \a reply is available. |
|
3870 |
|
3871 \note This signal is only emitted if the forwardUnsupportedContent property is set to true. |
|
3872 |
|
3873 \sa downloadRequested() |
|
3874 */ |
|
3875 |
|
3876 /*! |
|
3877 \fn void QWebPage::downloadRequested(const QNetworkRequest &request) |
|
3878 |
|
3879 This signal is emitted when the user decides to download a link. The url of |
|
3880 the link as well as additional meta-information is contained in \a request. |
|
3881 |
|
3882 \sa unsupportedContent() |
|
3883 */ |
|
3884 |
|
3885 /*! |
|
3886 \fn void QWebPage::microFocusChanged() |
|
3887 |
|
3888 This signal is emitted when for example the position of the cursor in an editable form |
|
3889 element changes. It is used to inform input methods about the new on-screen position where |
|
3890 the user is able to enter text. This signal is usually connected to the |
|
3891 QWidget::updateMicroFocus() slot. |
|
3892 */ |
|
3893 |
|
3894 /*! |
|
3895 \fn void QWebPage::linkClicked(const QUrl &url) |
|
3896 |
|
3897 This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy |
|
3898 property is set to delegate the link handling for the specified \a url. |
|
3899 |
|
3900 By default no links are delegated and are handled by QWebPage instead. |
|
3901 |
|
3902 \note This signal possibly won't be emitted for clicked links which use |
|
3903 JavaScript to trigger navigation. |
|
3904 |
|
3905 \sa linkHovered() |
|
3906 */ |
|
3907 |
|
3908 /*! |
|
3909 \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible) |
|
3910 |
|
3911 This signal is emitted whenever the visibility of the toolbar in a web browser |
|
3912 window that hosts QWebPage should be changed to \a visible. |
|
3913 */ |
|
3914 |
|
3915 /*! |
|
3916 \fn void QWebPage::statusBarVisibilityChangeRequested(bool visible) |
|
3917 |
|
3918 This signal is emitted whenever the visibility of the statusbar in a web browser |
|
3919 window that hosts QWebPage should be changed to \a visible. |
|
3920 */ |
|
3921 |
|
3922 /*! |
|
3923 \fn void QWebPage::menuBarVisibilityChangeRequested(bool visible) |
|
3924 |
|
3925 This signal is emitted whenever the visibility of the menubar in a web browser |
|
3926 window that hosts QWebPage should be changed to \a visible. |
|
3927 */ |
|
3928 |
|
3929 /*! |
|
3930 \fn void QWebPage::databaseQuotaExceeded(QWebFrame* frame, QString databaseName); |
|
3931 \since 4.5 |
|
3932 |
|
3933 This signal is emitted whenever the web site shown in \a frame is asking to store data |
|
3934 to the database \a databaseName and the quota allocated to that web site is exceeded. |
|
3935 |
|
3936 \sa QWebDatabase |
|
3937 */ |
|
3938 |
|
3939 /*! |
|
3940 \since 4.5 |
|
3941 \fn void QWebPage::saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item); |
|
3942 |
|
3943 This signal is emitted shortly before the history of navigated pages |
|
3944 in \a frame is changed, for example when navigating back in the history. |
|
3945 |
|
3946 The provided QWebHistoryItem, \a item, holds the history entry of the frame before |
|
3947 the change. |
|
3948 |
|
3949 A potential use-case for this signal is to store custom data in |
|
3950 the QWebHistoryItem associated to the frame, using QWebHistoryItem::setUserData(). |
|
3951 */ |
|
3952 |
|
3953 /*! |
|
3954 \since 4.5 |
|
3955 \fn void QWebPage::restoreFrameStateRequested(QWebFrame* frame); |
|
3956 |
|
3957 This signal is emitted when the load of \a frame is finished and the application may now update its state accordingly. |
|
3958 */ |
|
3959 |
|
3960 /*! |
|
3961 \fn QWebPagePrivate* QWebPage::handle() const |
|
3962 \internal |
|
3963 */ |
|
3964 |
|
3965 #include "moc_qwebpage.cpp" |