[Qt] Remove the fix in QWebPage::javaScriptConsoleMessage introduced by (r61433)
[WebKit-https.git] / Source / WebKit / qt / WidgetApi / qwebpage.cpp
1 /*
2     Copyright (C) 2008, 2009, 2012 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
25 #include "DefaultFullScreenVideoHandler.h"
26 #include "InitWebKitQt.h"
27 #include "InspectorClientQt.h"
28 #include "InspectorClientWebPage.h"
29 #include "InspectorServerQt.h"
30 #include "PageClientQt.h"
31 #include "QGraphicsWidgetPluginImpl.h"
32 #include "QWebUndoCommand.h"
33 #include "QWidgetPluginImpl.h"
34 #include "QtFallbackWebPopup.h"
35 #include "QtPlatformPlugin.h"
36 #include "UndoStepQt.h"
37 #include "WebEventConversion.h"
38
39 #include "qwebframe.h"
40 #include "qwebframe_p.h"
41 #include "qwebhistory.h"
42 #include "qwebinspector.h"
43 #include "qwebinspector_p.h"
44 #include "qwebkitplatformplugin.h"
45 #include "qwebpage_p.h"
46 #include "qwebsettings.h"
47 #include "qwebview.h"
48
49 #include <QAction>
50 #include <QApplication>
51 #include <QBasicTimer>
52 #include <QBitArray>
53 #include <QClipboard>
54 #include <QColorDialog>
55 #include <QDebug>
56 #include <QDesktopWidget>
57 #include <QDragEnterEvent>
58 #include <QDragLeaveEvent>
59 #include <QDragMoveEvent>
60 #include <QDropEvent>
61 #include <QFileDialog>
62 #include <QGestureEvent>
63 #include <QInputDialog>
64 #include <QLabel>
65 #include <QMenu>
66 #include <QMessageBox>
67 #include <QNetworkAccessManager>
68 #include <QNetworkProxy>
69 #include <QNetworkRequest>
70 #include <QPainter>
71 #include <QSslSocket>
72 #include <QStyle>
73 #include <QSysInfo>
74 #if USE(QT_MOBILITY_SYSTEMINFO)
75 #include <qsysteminfo.h>
76 #endif
77 #include <QSystemTrayIcon>
78 #include <QTextCharFormat>
79 #include <QToolTip>
80 #include <QTouchEvent>
81 #include <QUndoStack>
82 #include <QUrl>
83 #if defined(Q_WS_X11)
84 #include <QX11Info>
85 #endif
86
87 using namespace WebCore;
88
89 // Lookup table mapping QWebPage::WebActions to the associated Editor commands
90 static const char* editorCommandWebActions[] =
91 {
92     0, // OpenLink,
93
94     0, // OpenLinkInNewWindow,
95     0, // OpenFrameInNewWindow,
96
97     0, // DownloadLinkToDisk,
98     0, // CopyLinkToClipboard,
99
100     0, // OpenImageInNewWindow,
101     0, // DownloadImageToDisk,
102     0, // CopyImageToClipboard,
103
104     0, // Back,
105     0, // Forward,
106     0, // Stop,
107     0, // Reload,
108
109     "Cut", // Cut,
110     "Copy", // Copy,
111     "Paste", // Paste,
112
113     "Undo", // Undo,
114     "Redo", // Redo,
115     "MoveForward", // MoveToNextChar,
116     "MoveBackward", // MoveToPreviousChar,
117     "MoveWordForward", // MoveToNextWord,
118     "MoveWordBackward", // MoveToPreviousWord,
119     "MoveDown", // MoveToNextLine,
120     "MoveUp", // MoveToPreviousLine,
121     "MoveToBeginningOfLine", // MoveToStartOfLine,
122     "MoveToEndOfLine", // MoveToEndOfLine,
123     "MoveToBeginningOfParagraph", // MoveToStartOfBlock,
124     "MoveToEndOfParagraph", // MoveToEndOfBlock,
125     "MoveToBeginningOfDocument", // MoveToStartOfDocument,
126     "MoveToEndOfDocument", // MoveToEndOfDocument,
127     "MoveForwardAndModifySelection", // SelectNextChar,
128     "MoveBackwardAndModifySelection", // SelectPreviousChar,
129     "MoveWordForwardAndModifySelection", // SelectNextWord,
130     "MoveWordBackwardAndModifySelection", // SelectPreviousWord,
131     "MoveDownAndModifySelection", // SelectNextLine,
132     "MoveUpAndModifySelection", // SelectPreviousLine,
133     "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine,
134     "MoveToEndOfLineAndModifySelection", // SelectEndOfLine,
135     "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock,
136     "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock,
137     "MoveToBeginningOfDocumentAndModifySelection", // SelectStartOfDocument,
138     "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument,
139     "DeleteWordBackward", // DeleteStartOfWord,
140     "DeleteWordForward", // DeleteEndOfWord,
141
142     0, // SetTextDirectionDefault,
143     0, // SetTextDirectionLeftToRight,
144     0, // SetTextDirectionRightToLeft,
145
146     "ToggleBold", // ToggleBold,
147     "ToggleItalic", // ToggleItalic,
148     "ToggleUnderline", // ToggleUnderline,
149
150     0, // InspectElement,
151
152     "InsertNewline", // InsertParagraphSeparator
153     "InsertLineBreak", // InsertLineSeparator
154
155     "SelectAll", // SelectAll
156     0, // ReloadAndBypassCache,
157
158     "PasteAndMatchStyle", // PasteAndMatchStyle
159     "RemoveFormat", // RemoveFormat
160     "Strikethrough", // ToggleStrikethrough,
161     "Subscript", // ToggleSubscript
162     "Superscript", // ToggleSuperscript
163     "InsertUnorderedList", // InsertUnorderedList
164     "InsertOrderedList", // InsertOrderedList
165     "Indent", // Indent
166     "Outdent", // Outdent,
167
168     "AlignCenter", // AlignCenter,
169     "AlignJustified", // AlignJustified,
170     "AlignLeft", // AlignLeft,
171     "AlignRight", // AlignRight,
172
173     0, // StopScheduledPageRefresh,
174
175     0, // CopyImageUrlToClipboard,
176
177     0, // OpenLinkInThisWindow,
178
179     0 // WebActionCount
180 };
181
182 // Lookup the appropriate editor command to use for WebAction \a action
183 const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action)
184 {
185     if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*))))
186         return editorCommandWebActions[action];
187     return 0;
188 }
189
190 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
191     : q(qq)
192 #ifndef QT_NO_UNDOSTACK
193     , undoStack(0)
194 #endif
195     , linkPolicy(QWebPage::DontDelegateLinks)
196     , m_viewportSize(QSize(0, 0))
197     , useFixedLayout(false)
198     , inspectorFrontend(0)
199     , inspector(0)
200     , inspectorIsInternalOnly(false)
201     , m_lastDropAction(Qt::IgnoreAction)
202 {
203     WebKit::initializeWebKitWidgets();
204     initializeWebCorePage();
205     memset(actions, 0, sizeof(actions));
206
207 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
208     addNotificationPresenterClient();
209 #ifndef QT_NO_SYSTEMTRAYICON
210     if (!hasSystemTrayIcon())
211         setSystemTrayIcon(new QSystemTrayIcon);
212 #endif // QT_NO_SYSTEMTRAYICON
213 #endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
214 }
215
216 QWebPagePrivate::~QWebPagePrivate()
217 {
218 #ifndef QT_NO_CONTEXTMENU
219     delete currentContextMenu.data();
220 #endif
221 #ifndef QT_NO_UNDOSTACK
222     delete undoStack;
223     undoStack = 0;
224 #endif
225     
226     if (inspector) {
227         // If the inspector is ours, delete it, otherwise just detach from it.
228         if (inspectorIsInternalOnly)
229             delete inspector;
230         else
231             inspector->setPage(0);
232     }
233     // Explicitly destruct the WebCore page at this point when the
234     // QWebPagePrivate / QWebPageAdapater vtables are still intact,
235     // in order for various destruction callbacks out of WebCore to
236     // work.
237     deletePage();
238 }
239
240 void QWebPagePrivate::show()
241 {
242     if (!view)
243         return;
244     view->window()->show();
245 }
246
247 void QWebPagePrivate::setFocus()
248 {
249     if (!view)
250         return;
251     view->setFocus();
252 }
253
254 void QWebPagePrivate::unfocus()
255 {
256     if (!view)
257         return;
258     view->clearFocus();
259 }
260
261 void QWebPagePrivate::setWindowRect(const QRect &rect)
262 {
263     emit q->geometryChangeRequested(rect);
264 }
265
266 QSize QWebPagePrivate::viewportSize() const
267 {
268     return q->viewportSize();
269 }
270
271 QWebPageAdapter *QWebPagePrivate::createWindow(bool dialog)
272 {
273     QWebPage *newPage = q->createWindow(dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
274     if (!newPage)
275         return 0;
276     // Make sure the main frame exists, as WebCore expects it when returning from this ChromeClient::createWindow()
277     newPage->d->createMainFrame();
278     return newPage->d;
279 }
280
281 void QWebPagePrivate::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID)
282 {
283     q->javaScriptConsoleMessage(message, lineNumber, sourceID);
284 }
285
286 void QWebPagePrivate::javaScriptAlert(QWebFrameAdapter* frame, const QString& msg)
287 {
288     q->javaScriptAlert(QWebFramePrivate::kit(frame), msg);
289 }
290
291 bool QWebPagePrivate::javaScriptConfirm(QWebFrameAdapter* frame, const QString& msg)
292 {
293     return q->javaScriptConfirm(QWebFramePrivate::kit(frame), msg);
294 }
295
296 bool QWebPagePrivate::javaScriptPrompt(QWebFrameAdapter *frame, const QString &msg, const QString &defaultValue, QString *result)
297 {
298     return q->javaScriptPrompt(QWebFramePrivate::kit(frame), msg, defaultValue, result);
299 }
300
301 bool QWebPagePrivate::shouldInterruptJavaScript()
302 {
303     return q->shouldInterruptJavaScript();
304 }
305
306 void QWebPagePrivate::printRequested(QWebFrameAdapter *frame)
307 {
308     emit q->printRequested(QWebFramePrivate::kit(frame));
309 }
310
311 void QWebPagePrivate::databaseQuotaExceeded(QWebFrameAdapter* frame, const QString& databaseName)
312 {
313     emit q->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
314 }
315
316 void QWebPagePrivate::applicationCacheQuotaExceeded(QWebSecurityOrigin *origin, quint64 defaultOriginQuota, quint64 c)
317 {
318     emit q->applicationCacheQuotaExceeded(origin, defaultOriginQuota, c);
319 }
320
321 void QWebPagePrivate::setToolTip(const QString &tip)
322 {
323 #ifndef QT_NO_TOOLTIP
324     if (!view)
325         return;
326
327     if (tip.isEmpty()) {
328         view->setToolTip(QString());
329         QToolTip::hideText();
330     } else {
331         QString dtip = QLatin1String("<p>") + QString(tip).toHtmlEscaped() + QLatin1String("</p>");
332         view->setToolTip(dtip);
333     }
334 #else
335     Q_UNUSED(tip);
336 #endif
337 }
338
339 #if USE(QT_MULTIMEDIA)
340 QWebFullScreenVideoHandler *QWebPagePrivate::createFullScreenVideoHandler()
341 {
342     return new WebKit::DefaultFullScreenVideoHandler;
343 }
344 #endif
345
346 QWebFrameAdapter *QWebPagePrivate::mainFrameAdapter()
347 {
348     return q->mainFrame()->d;
349 }
350
351 QStringList QWebPagePrivate::chooseFiles(QWebFrameAdapter *frame, bool allowMultiple, const QStringList &suggestedFileNames)
352 {
353     if (allowMultiple && q->supportsExtension(QWebPage::ChooseMultipleFilesExtension)) {
354         QWebPage::ChooseMultipleFilesExtensionOption option;
355         option.parentFrame = QWebFramePrivate::kit(frame);
356         option.suggestedFileNames = suggestedFileNames;
357
358         QWebPage::ChooseMultipleFilesExtensionReturn output;
359         q->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
360
361         return output.fileNames;
362     }
363     // Single file
364     QStringList result;
365     QString suggestedFile;
366     if (!suggestedFileNames.isEmpty())
367         suggestedFile = suggestedFileNames.first();
368     QString file = q->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
369     if (!file.isEmpty())
370         result << file;
371     return result;
372 }
373
374 bool QWebPagePrivate::acceptNavigationRequest(QWebFrameAdapter *frameAdapter, const QNetworkRequest &request, int type)
375 {
376     QWebFrame *frame = frameAdapter ? QWebFramePrivate::kit(frameAdapter): 0;
377     if (insideOpenCall
378         && frame == mainFrame.data())
379         return true;
380     return q->acceptNavigationRequest(frame, request, QWebPage::NavigationType(type));
381 }
382
383 void QWebPagePrivate::emitRestoreFrameStateRequested(QWebFrameAdapter *frame)
384 {
385     emit q->restoreFrameStateRequested(QWebFramePrivate::kit(frame));
386 }
387
388 void QWebPagePrivate::emitSaveFrameStateRequested(QWebFrameAdapter *frame, QWebHistoryItem *item)
389 {
390     emit q->saveFrameStateRequested(QWebFramePrivate::kit(frame), item);
391 }
392
393 void QWebPagePrivate::emitDownloadRequested(const QNetworkRequest &request)
394 {
395     emit q->downloadRequested(request);
396 }
397
398 void QWebPagePrivate::emitFrameCreated(QWebFrameAdapter *frame)
399 {
400     emit q->frameCreated(QWebFramePrivate::kit(frame));
401 }
402
403 bool QWebPagePrivate::errorPageExtension(QWebPageAdapter::ErrorPageOption *opt, QWebPageAdapter::ErrorPageReturn *out)
404 {
405     QWebPage::ErrorPageExtensionOption option;
406     if (opt->domain == QLatin1String("QtNetwork"))
407         option.domain = QWebPage::QtNetwork;
408     else if (opt->domain == QLatin1String("HTTP"))
409         option.domain = QWebPage::Http;
410     else if (opt->domain == QLatin1String("WebKit"))
411         option.domain = QWebPage::WebKit;
412     else
413         return false;
414     option.url = opt->url;
415     option.frame = QWebFramePrivate::kit(opt->frame);
416     option.error = opt->error;
417     option.errorString = opt->errorString;
418     QWebPage::ErrorPageExtensionReturn output;
419     if (!q->extension(QWebPage::ErrorPageExtension, &option, &output))
420         return false;
421     out->baseUrl = output.baseUrl;
422     out->content = output.content;
423     out->contentType = output.contentType;
424     out->encoding = output.encoding;
425     return true;
426 }
427
428 QtPluginWidgetAdapter *QWebPagePrivate::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
429 {
430     QObject *widget = q->createPlugin(classid, url, paramNames, paramValues);
431     return adapterForWidget(widget);
432 }
433
434 QtPluginWidgetAdapter *QWebPagePrivate::adapterForWidget(QObject *object) const
435 {
436     if (QWidget *widget = qobject_cast<QWidget*>(object))
437         return new QWidgetPluginImpl(widget);
438     if (QGraphicsWidget *widget = qobject_cast<QGraphicsWidget*>(object))
439         return new QGraphicsWidgetPluginImpl(widget);
440     return 0;
441 }
442
443 void QWebPagePrivate::createMainFrame()
444 {
445     if (!mainFrame) {
446         mainFrame = new QWebFrame(q);
447         emit q->frameCreated(mainFrame.data());
448     }
449 }
450
451 #define MAP_WEB_ACTION_FROM_ADAPTER_EQUIVALENT(Name, Value) \
452     case QWebPageAdapter::Name: return QWebPage::Name
453
454 static QWebPage::WebAction webActionForAdapterMenuAction(QWebPageAdapter::MenuAction action)
455 {
456     switch (action) {
457         FOR_EACH_MAPPED_MENU_ACTION(MAP_WEB_ACTION_FROM_ADAPTER_EQUIVALENT, SEMICOLON_SEPARATOR);
458 #if ENABLE(INSPECTOR)
459     case QWebPageAdapter::InspectElement: return QWebPage::InspectElement;
460 #endif
461     default:
462         ASSERT_NOT_REACHED();
463         break;
464     }
465     return QWebPage::NoWebAction;
466 }
467
468 #define MAP_ADAPTER_ACTION_FROM_WEBACTION_EQUIVALENT(Name, Value) \
469     case QWebPage::Name: return QWebPageAdapter::Name
470
471 static QWebPageAdapter::MenuAction adapterMenuActionForWebAction(QWebPage::WebAction action)
472 {
473     switch (action) {
474         FOR_EACH_MAPPED_MENU_ACTION(MAP_ADAPTER_ACTION_FROM_WEBACTION_EQUIVALENT, SEMICOLON_SEPARATOR);
475 #if ENABLE(INSPECTOR)
476     case QWebPage::InspectElement: return QWebPageAdapter::InspectElement;
477 #endif
478     default:
479         ASSERT_NOT_REACHED();
480         break;
481     }
482     return QWebPageAdapter::NoAction;
483 }
484
485 #ifndef QT_NO_CONTEXTMENU
486 typedef QWebPageAdapter::MenuItemDescription MenuItem;
487 QMenu *createContextMenu(QWebPage* page, const QList<MenuItem>& items, QBitArray *visitedWebActions)
488 {
489     if (items.isEmpty())
490         return 0;
491
492     QMenu* menu = new QMenu(page->view());
493     for (int i = 0; i < items.count(); ++i) {
494         const MenuItem &item = items.at(i);
495         switch (item.type) {
496         case MenuItem::Action: {
497             QWebPage::WebAction action = webActionForAdapterMenuAction(item.action);
498             QAction *a = page->action(action);
499             if (a) {
500                 a->setEnabled(item.traits & MenuItem::Enabled);
501                 a->setCheckable(item.traits & MenuItem::Checkable);
502                 a->setChecked(item.traits & MenuItem::Checked);
503
504                 menu->addAction(a);
505                 visitedWebActions->setBit(action);
506             }
507             break;
508         }
509         case MenuItem::Separator:
510             menu->addSeparator();
511             break;
512         case MenuItem::SubMenu: {
513             QMenu *subMenu = createContextMenu(page, item.subMenu, visitedWebActions);
514             Q_ASSERT(subMenu);
515
516             bool anyEnabledAction = false;
517
518             QList<QAction *> actions = subMenu->actions();
519             for (int i = 0; i < actions.count(); ++i) {
520                 if (actions.at(i)->isVisible())
521                     anyEnabledAction |= actions.at(i)->isEnabled();
522             }
523
524             // don't show sub-menus with just disabled actions
525             if (anyEnabledAction) {
526                 subMenu->setTitle(item.subMenuTitle);
527                 menu->addAction(subMenu->menuAction());
528             } else
529                 delete subMenu;
530             break;
531         }
532         }
533     }
534     return menu;
535 }
536 #endif // QT_NO_CONTEXTMENU
537
538 void QWebPagePrivate::createAndSetCurrentContextMenu(const QList<MenuItemDescription>& items, QBitArray* visitedWebActions)
539 {
540 #ifndef QT_NO_CONTEXTMENU
541     delete currentContextMenu.data();
542
543     currentContextMenu = createContextMenu(q, items, visitedWebActions);
544 #else
545     Q_UNUSED(menuDescription);
546     Q_UNUSED(visitedWebActions);
547 #endif // QT_NO_CONTEXTMENU
548 }
549
550 #ifndef QT_NO_ACTION
551 void QWebPagePrivate::_q_webActionTriggered(bool checked)
552 {
553     QAction *a = qobject_cast<QAction *>(q->sender());
554     if (!a)
555         return;
556     QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
557     q->triggerAction(action, checked);
558 }
559 #endif // QT_NO_ACTION
560
561 void QWebPagePrivate::updateAction(QWebPage::WebAction action)
562 {
563 #ifdef QT_NO_ACTION
564     Q_UNUSED(action)
565 #else
566     QAction *a = actions[action];
567     if (!a || !mainFrame)
568         return;
569
570     bool enabled = a->isEnabled();
571     bool checked = a->isChecked();
572
573     QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
574     const char* commandName = 0;
575
576     switch (action) {
577     case QWebPage::Back:
578     case QWebPage::Forward:
579     case QWebPage::Stop:
580     case QWebPage::Reload:
581     case QWebPage::SetTextDirectionDefault:
582     case QWebPage::SetTextDirectionLeftToRight:
583     case QWebPage::SetTextDirectionRightToLeft:
584         mappedAction = adapterMenuActionForWebAction(action);
585         break;
586     case QWebPage::ReloadAndBypassCache: // Manual mapping
587         mappedAction = QWebPageAdapter::Reload;
588         break;
589 #ifndef QT_NO_UNDOSTACK
590     case QWebPage::Undo:
591     case QWebPage::Redo:
592         // those two are handled by QUndoStack
593         break;
594 #endif // QT_NO_UNDOSTACK
595     case QWebPage::SelectAll: // editor command is always enabled
596         break;
597     default: {
598         // see if it's an editor command
599         commandName = editorCommandForWebActions(action);
600         break;
601     }
602     }
603     if (mappedAction != QWebPageAdapter::NoAction || commandName)
604         updateActionInternal(mappedAction, commandName, &enabled, &checked);
605
606     a->setEnabled(enabled);
607
608     if (a->isCheckable())
609         a->setChecked(checked);
610 #endif // QT_NO_ACTION
611 }
612
613 void QWebPagePrivate::updateNavigationActions()
614 {
615     updateAction(QWebPage::Back);
616     updateAction(QWebPage::Forward);
617     updateAction(QWebPage::Stop);
618     updateAction(QWebPage::Reload);
619     updateAction(QWebPage::ReloadAndBypassCache);
620 }
621
622 QObject *QWebPagePrivate::inspectorHandle()
623 {
624     return getOrCreateInspector();
625 }
626
627 void QWebPagePrivate::setInspectorFrontend(QObject* frontend)
628 {
629     inspectorFrontend = qobject_cast<QWidget*>(frontend);
630     if (inspector)
631         inspector->d->setFrontend(frontend);
632 }
633
634 void QWebPagePrivate::setInspectorWindowTitle(const QString& title)
635 {
636     if (inspector)
637         inspector->setWindowTitle(title);
638 }
639
640 void QWebPagePrivate::createWebInspector(QObject** inspectorView, QWebPageAdapter** inspectorPage)
641 {
642     QWebPage* page = new WebKit::InspectorClientWebPage;
643     *inspectorView = page->view();
644     *inspectorPage = page->d;
645 }
646
647 #ifndef QT_NO_MENU
648 static QStringList iterateContextMenu(QMenu* menu)
649 {
650     if (!menu)
651         return QStringList();
652
653     QStringList items;
654     QList<QAction *> actions = menu->actions();
655     for (int i = 0; i < actions.count(); ++i) {
656         if (actions.at(i)->isSeparator())
657             items << QLatin1String("<separator>");
658         else
659             items << actions.at(i)->text();
660         if (actions.at(i)->menu())
661             items << iterateContextMenu(actions.at(i)->menu());
662     }
663     return items;
664 }
665 #endif
666
667 QStringList QWebPagePrivate::menuActionsAsText()
668 {
669 #ifndef QT_NO_MENU
670     return iterateContextMenu(currentContextMenu.data());
671 #else
672     return QStringList();
673 #endif
674 }
675
676 void QWebPagePrivate::emitViewportChangeRequested()
677 {
678     emit q->viewportChangeRequested();
679 }
680
681 void QWebPagePrivate::updateEditorActions()
682 {
683     updateAction(QWebPage::Cut);
684     updateAction(QWebPage::Copy);
685     updateAction(QWebPage::Paste);
686     updateAction(QWebPage::MoveToNextChar);
687     updateAction(QWebPage::MoveToPreviousChar);
688     updateAction(QWebPage::MoveToNextWord);
689     updateAction(QWebPage::MoveToPreviousWord);
690     updateAction(QWebPage::MoveToNextLine);
691     updateAction(QWebPage::MoveToPreviousLine);
692     updateAction(QWebPage::MoveToStartOfLine);
693     updateAction(QWebPage::MoveToEndOfLine);
694     updateAction(QWebPage::MoveToStartOfBlock);
695     updateAction(QWebPage::MoveToEndOfBlock);
696     updateAction(QWebPage::MoveToStartOfDocument);
697     updateAction(QWebPage::MoveToEndOfDocument);
698     updateAction(QWebPage::SelectNextChar);
699     updateAction(QWebPage::SelectPreviousChar);
700     updateAction(QWebPage::SelectNextWord);
701     updateAction(QWebPage::SelectPreviousWord);
702     updateAction(QWebPage::SelectNextLine);
703     updateAction(QWebPage::SelectPreviousLine);
704     updateAction(QWebPage::SelectStartOfLine);
705     updateAction(QWebPage::SelectEndOfLine);
706     updateAction(QWebPage::SelectStartOfBlock);
707     updateAction(QWebPage::SelectEndOfBlock);
708     updateAction(QWebPage::SelectStartOfDocument);
709     updateAction(QWebPage::SelectEndOfDocument);
710     updateAction(QWebPage::DeleteStartOfWord);
711     updateAction(QWebPage::DeleteEndOfWord);
712     updateAction(QWebPage::SetTextDirectionDefault);
713     updateAction(QWebPage::SetTextDirectionLeftToRight);
714     updateAction(QWebPage::SetTextDirectionRightToLeft);
715     updateAction(QWebPage::ToggleBold);
716     updateAction(QWebPage::ToggleItalic);
717     updateAction(QWebPage::ToggleUnderline);
718     updateAction(QWebPage::InsertParagraphSeparator);
719     updateAction(QWebPage::InsertLineSeparator);
720     updateAction(QWebPage::PasteAndMatchStyle);
721     updateAction(QWebPage::RemoveFormat);
722     updateAction(QWebPage::ToggleStrikethrough);
723     updateAction(QWebPage::ToggleSubscript);
724     updateAction(QWebPage::ToggleSuperscript);
725     updateAction(QWebPage::InsertUnorderedList);
726     updateAction(QWebPage::InsertOrderedList);
727     updateAction(QWebPage::Indent);
728     updateAction(QWebPage::Outdent);
729     updateAction(QWebPage::AlignCenter);
730     updateAction(QWebPage::AlignJustified);
731     updateAction(QWebPage::AlignLeft);
732     updateAction(QWebPage::AlignRight);
733 }
734
735 void QWebPagePrivate::timerEvent(QTimerEvent *ev)
736 {
737     int timerId = ev->timerId();
738     if (timerId == tripleClickTimer.timerId())
739         tripleClickTimer.stop();
740     else
741         q->timerEvent(ev);
742 }
743
744 bool QWebPagePrivate::requestSoftwareInputPanel() const
745 {
746     return QStyle::RequestSoftwareInputPanel(client->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)) == QStyle::RSIP_OnMouseClick;
747 }
748
749 #ifndef QT_NO_CONTEXTMENU
750 void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos)
751 {
752     QMenu *menu = q->createStandardContextMenu();
753     if (menu) {
754         menu->exec(globalPos);
755         delete menu;
756     }
757 }
758 #endif // QT_NO_CONTEXTMENU
759
760 /*!
761     \since 4.5
762     This function creates the standard context menu which is shown when
763     the user clicks on the web page with the right mouse button. It is
764     called from the default contextMenuEvent() handler. The popup menu's
765     ownership is transferred to the caller.
766  */
767 QMenu *QWebPage::createStandardContextMenu()
768 {
769 #ifndef QT_NO_CONTEXTMENU
770     QMenu* menu = d->currentContextMenu.data();
771     d->currentContextMenu = 0;
772     return menu;
773 #else
774     return 0;
775 #endif
776 }
777
778 #ifndef QT_NO_SHORTCUT
779 QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event)
780 {
781     static struct {
782         QKeySequence::StandardKey standardKey;
783         QWebPage::WebAction action;
784     } editorActions[] = {
785         { QKeySequence::Cut, QWebPage::Cut },
786         { QKeySequence::Copy, QWebPage::Copy },
787         { QKeySequence::Paste, QWebPage::Paste },
788         { QKeySequence::Undo, QWebPage::Undo },
789         { QKeySequence::Redo, QWebPage::Redo },
790         { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar },
791         { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar },
792         { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord },
793         { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord },
794         { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine },
795         { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine },
796         { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine },
797         { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine },
798         { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock },
799         { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock },
800         { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument },
801         { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument },
802         { QKeySequence::SelectNextChar, QWebPage::SelectNextChar },
803         { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar },
804         { QKeySequence::SelectNextWord, QWebPage::SelectNextWord },
805         { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord },
806         { QKeySequence::SelectNextLine, QWebPage::SelectNextLine },
807         { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine },
808         { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine },
809         { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine },
810         { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock },
811         { QKeySequence::SelectEndOfBlock,  QWebPage::SelectEndOfBlock },
812         { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument },
813         { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument },
814         { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord },
815         { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord },
816         { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator },
817         { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator },
818         { QKeySequence::SelectAll, QWebPage::SelectAll },
819         { QKeySequence::UnknownKey, QWebPage::NoWebAction }
820     };
821
822     for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i)
823         if (event == editorActions[i].standardKey)
824             return editorActions[i].action;
825
826     return QWebPage::NoWebAction;
827 }
828 #endif // QT_NO_SHORTCUT
829
830 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
831 {
832     // we forward the key event to WebCore first to handle potential DOM
833     // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent
834     // to trigger editor commands via triggerAction().
835     bool handled = handleKeyEvent(ev);
836
837     if (!handled)
838         handled = handleScrolling(ev);
839
840     if (!handled) {
841         handled = true;
842         switch (ev->key()) {
843         case Qt::Key_Back:
844             q->triggerAction(QWebPage::Back);
845             break;
846         case Qt::Key_Forward:
847             q->triggerAction(QWebPage::Forward);
848             break;
849         case Qt::Key_Stop:
850             q->triggerAction(QWebPage::Stop);
851             break;
852         case Qt::Key_Refresh:
853             q->triggerAction(QWebPage::Reload);
854             break;
855         default:
856             handled = false;
857             break;
858         }
859     }
860
861     ev->setAccepted(handled);
862 }
863
864 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
865 {
866     if (ev->isAutoRepeat()) {
867         ev->setAccepted(true);
868         return;
869     }
870
871     bool handled = handleKeyEvent(ev);
872     ev->setAccepted(handled);
873 }
874
875 template<class T>
876 void QWebPagePrivate::dragEnterEvent(T* ev)
877 {
878 #ifndef QT_NO_DRAGANDDROP
879     Qt::DropAction action = dragEntered(ev->mimeData(), QPointF(ev->pos()).toPoint(), ev->possibleActions());
880     ev->setDropAction(action);
881     ev->acceptProposedAction();
882 #endif
883 }
884
885 template<class T>
886 void QWebPagePrivate::dragMoveEvent(T *ev)
887 {
888 #ifndef QT_NO_DRAGANDDROP
889     m_lastDropAction = dragUpdated(ev->mimeData(), QPointF(ev->pos()).toPoint(), ev->possibleActions());
890     ev->setDropAction(m_lastDropAction);
891     if (m_lastDropAction != Qt::IgnoreAction)
892         ev->accept();
893 #endif
894 }
895
896 template<class T>
897 void QWebPagePrivate::dropEvent(T *ev)
898 {
899 #ifndef QT_NO_DRAGANDDROP
900     if (performDrag(ev->mimeData(), QPointF(ev->pos()).toPoint(), ev->possibleActions())) {
901         ev->setDropAction(m_lastDropAction);
902         ev->accept();
903     }
904 #endif
905 }
906
907 void QWebPagePrivate::leaveEvent(QEvent*)
908 {
909     // Fake a mouse move event just outside of the widget, since all
910     // the interesting mouse-out behavior like invalidating scrollbars
911     // is handled by the WebKit event handler's mouseMoved function.
912     QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
913     mouseMoveEvent(&fakeEvent);
914 }
915
916 /*!
917     \property QWebPage::palette
918     \brief the page's palette
919
920     The base brush of the palette is used to draw the background of the main frame.
921
922     By default, this property contains the application's default palette.
923 */
924 void QWebPage::setPalette(const QPalette &pal)
925 {
926     d->palette = pal;
927     if (!d->mainFrame || !d->mainFrame.data()->d->hasView())
928         return;
929
930     QBrush brush = pal.brush(QPalette::Base);
931     QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
932     d->mainFrame.data()->d->updateBackgroundRecursively(backgroundColor);
933 }
934
935 QPalette QWebPage::palette() const
936 {
937     return d->palette;
938 }
939
940 void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event)
941 {
942     if (handleShortcutOverrideEvent(event))
943         return;
944 #ifndef QT_NO_SHORTCUT
945     if (editorActionForKeyEvent(event) != QWebPage::NoWebAction)
946         event->accept();
947 #endif
948
949 }
950
951 bool QWebPagePrivate::gestureEvent(QGestureEvent* event)
952 {
953     QWebFrameAdapter* frame = mainFrame.data()->d;
954     if (!frame->hasView())
955         return false;
956     // QGestureEvents can contain updates for multiple gestures.
957     bool handled = false;
958 #if ENABLE(GESTURE_EVENTS)
959     // QGestureEvent lives in Widgets, we'll need a dummy struct to mule the info it contains to the "other side"
960     QGestureEventFacade gestureFacade;
961
962     QGesture* gesture = event->gesture(Qt::TapGesture);
963     // Beware that gestures send by DumpRenderTree will have state Qt::NoGesture,
964     // due to not originating from a GestureRecognizer.
965     if (gesture && (gesture->state() == Qt::GestureStarted || gesture->state() == Qt::NoGesture)) {
966         gestureFacade.type = Qt::TapGesture;
967         QPointF globalPos = static_cast<const QTapGesture*>(gesture)->position();
968         gestureFacade.globalPos = globalPos.toPoint();
969         gestureFacade.pos = event->widget()->mapFromGlobal(globalPos.toPoint());
970         frame->handleGestureEvent(&gestureFacade);
971         handled = true;
972     }
973     gesture = event->gesture(Qt::TapAndHoldGesture);
974     if (gesture && (gesture->state() == Qt::GestureStarted || gesture->state() == Qt::NoGesture)) {
975         gestureFacade.type = Qt::TapAndHoldGesture;
976         QPointF globalPos = static_cast<const QTapAndHoldGesture*>(gesture)->position();
977         gestureFacade.globalPos = globalPos.toPoint();
978         gestureFacade.pos = event->widget()->mapFromGlobal(globalPos.toPoint());
979         frame->handleGestureEvent(&gestureFacade);
980         handled = true;
981     }
982 #endif // ENABLE(GESTURE_EVENTS)
983
984     event->setAccepted(handled);
985     return handled;
986 }
987
988 /*!
989   This method is used by the input method to query a set of properties of the page
990   to be able to support complex input method operations as support for surrounding
991   text and reconversions.
992
993   \a property specifies which property is queried.
994
995   \sa QWidget::inputMethodEvent(), QInputMethodEvent, QInputContext
996 */
997 QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const
998 {
999     return d->inputMethodQuery(property);
1000 }
1001
1002 /*!
1003     \internal
1004 */
1005 void QWebPagePrivate::setInspector(QWebInspector* insp)
1006 {
1007     if (inspector)
1008         inspector->d->setFrontend(0);
1009
1010     inspector = insp;
1011
1012     // Give inspector frontend web view if previously created
1013     if (inspector && inspectorFrontend)
1014         inspector->d->setFrontend(inspectorFrontend);
1015 }
1016
1017 /*!
1018     \internal
1019     Returns the inspector and creates it if it wasn't created yet.
1020     The instance created here will not be available through QWebPage's API.
1021 */
1022 QWebInspector* QWebPagePrivate::getOrCreateInspector()
1023 {
1024 #if ENABLE(INSPECTOR)
1025     if (!inspector) {
1026         QWebInspector* insp = new QWebInspector;
1027         insp->setPage(q);
1028         inspectorIsInternalOnly = true;
1029
1030         Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q)
1031     }
1032 #endif
1033     return inspector;
1034 }
1035
1036 /*!
1037    \enum QWebPage::FindFlag
1038
1039    This enum describes the options available to the findText() function. The options
1040    can be OR-ed together from the following list:
1041
1042    \value FindBackward Searches backwards instead of forwards.
1043    \value FindCaseSensitively By default findText() works case insensitive. Specifying this option
1044    changes the behaviour to a case sensitive find operation.
1045    \value FindWrapsAroundDocument Makes findText() restart from the beginning of the document if the end
1046    was reached and the text was not found.
1047    \value HighlightAllOccurrences Highlights all existing occurrences of a specific string.
1048        (This value was introduced in 4.6.)
1049    \value FindAtWordBeginningsOnly Searches for the sub-string only at the beginnings of words.
1050        (This value was introduced in 5.2.)
1051    \value TreatMedialCapitalAsWordBeginning Treats a capital letter occurring anywhere in the middle of a word
1052    as the beginning of a new word.
1053        (This value was introduced in 5.2.)
1054    \value FindBeginsInSelection Begin searching inside the text selection first.
1055        (This value was introduced in 5.2.)
1056 */
1057
1058 /*!
1059     \enum QWebPage::VisibilityState
1060
1061     This enum defines visibility states that a webpage can take.
1062
1063     \value VisibilityStateVisible The webpage is at least partially visible at on at least one screen.
1064     \value VisibilityStateHidden The webpage is not visible at all on any screen.
1065     \value VisibilityStatePrerender The webpage is loaded off-screen and is not visible.
1066     \value VisibilityStateUnloaded The webpage is unloading its content.
1067     More information about this values can be found at \l{ http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate}{W3C Recommendation: Page Visibility: visibilityState attribute}.
1068
1069     \sa QWebPage::visibilityState
1070 */
1071
1072 /*!
1073     \enum QWebPage::LinkDelegationPolicy
1074
1075     This enum defines the delegation policies a webpage can have when activating links and emitting
1076     the linkClicked() signal.
1077
1078     \value DontDelegateLinks No links are delegated. Instead, QWebPage tries to handle them all.
1079     \value DelegateExternalLinks When activating links that point to documents not stored on the
1080     local filesystem or an equivalent - such as the Qt resource system - then linkClicked() is emitted.
1081     \value DelegateAllLinks Whenever a link is activated the linkClicked() signal is emitted.
1082
1083     \sa QWebPage::linkDelegationPolicy
1084 */
1085
1086 /*!
1087     \enum QWebPage::NavigationType
1088
1089     This enum describes the types of navigation available when browsing through hyperlinked
1090     documents.
1091
1092     \value NavigationTypeLinkClicked The user clicked on a link or pressed return on a focused link.
1093     \value NavigationTypeFormSubmitted The user activated a submit button for an HTML form.
1094     \value NavigationTypeBackOrForward Navigation to a previously shown document in the back or forward history is requested.
1095     \value NavigationTypeReload The user activated the reload action.
1096     \value NavigationTypeFormResubmitted An HTML form was submitted a second time.
1097     \value NavigationTypeOther A navigation to another document using a method not listed above.
1098
1099     \sa acceptNavigationRequest()
1100 */
1101
1102 /*!
1103     \enum QWebPage::WebAction
1104
1105     This enum describes the types of action which can be performed on the web page.
1106
1107     Actions only have an effect when they are applicable. The availability of
1108     actions can be be determined by checking \l{QAction::}{isEnabled()} on the
1109     action returned by action().
1110
1111     One method of enabling the text editing, cursor movement, and text selection actions
1112     is by setting \l contentEditable to true.
1113
1114     \value NoWebAction No action is triggered.
1115     \value OpenLink Open the current link.
1116     \value OpenLinkInNewWindow Open the current link in a new window.
1117     \value OpenLinkInThisWindow Open the current link without opening a new window. Used on links that would default to opening in another frame or a new window. (Added in Qt 5.0)
1118     \value OpenFrameInNewWindow Replicate the current frame in a new window.
1119     \value DownloadLinkToDisk Download the current link to the disk.
1120     \value CopyLinkToClipboard Copy the current link to the clipboard.
1121     \value OpenImageInNewWindow Open the highlighted image in a new window.
1122     \value DownloadImageToDisk Download the highlighted image to the disk.
1123     \value CopyImageToClipboard Copy the highlighted image to the clipboard.  (Added in Qt 4.8)
1124     \value CopyImageUrlToClipboard Copy the highlighted image's URL to the clipboard.
1125     \value Back Navigate back in the history of navigated links.
1126     \value Forward Navigate forward in the history of navigated links.
1127     \value Stop Stop loading the current page.
1128     \value StopScheduledPageRefresh Stop all pending page refresh/redirect requests.  (Added in Qt 4.7)
1129     \value Reload Reload the current page.
1130     \value ReloadAndBypassCache Reload the current page, but do not use any local cache. (Added in Qt 4.6)
1131     \value Cut Cut the content currently selected into the clipboard.
1132     \value Copy Copy the content currently selected into the clipboard.
1133     \value Paste Paste content from the clipboard.
1134     \value Undo Undo the last editing action.
1135     \value Redo Redo the last editing action.
1136     \value MoveToNextChar Move the cursor to the next character.
1137     \value MoveToPreviousChar Move the cursor to the previous character.
1138     \value MoveToNextWord Move the cursor to the next word.
1139     \value MoveToPreviousWord Move the cursor to the previous word.
1140     \value MoveToNextLine Move the cursor to the next line.
1141     \value MoveToPreviousLine Move the cursor to the previous line.
1142     \value MoveToStartOfLine Move the cursor to the start of the line.
1143     \value MoveToEndOfLine Move the cursor to the end of the line.
1144     \value MoveToStartOfBlock Move the cursor to the start of the block.
1145     \value MoveToEndOfBlock Move the cursor to the end of the block.
1146     \value MoveToStartOfDocument Move the cursor to the start of the document.
1147     \value MoveToEndOfDocument Move the cursor to the end of the document.
1148     \value SelectNextChar Select to the next character.
1149     \value SelectPreviousChar Select to the previous character.
1150     \value SelectNextWord Select to the next word.
1151     \value SelectPreviousWord Select to the previous word.
1152     \value SelectNextLine Select to the next line.
1153     \value SelectPreviousLine Select to the previous line.
1154     \value SelectStartOfLine Select to the start of the line.
1155     \value SelectEndOfLine Select to the end of the line.
1156     \value SelectStartOfBlock Select to the start of the block.
1157     \value SelectEndOfBlock Select to the end of the block.
1158     \value SelectStartOfDocument Select to the start of the document.
1159     \value SelectEndOfDocument Select to the end of the document.
1160     \value DeleteStartOfWord Delete to the start of the word.
1161     \value DeleteEndOfWord Delete to the end of the word.
1162     \value SetTextDirectionDefault Set the text direction to the default direction.
1163     \value SetTextDirectionLeftToRight Set the text direction to left-to-right.
1164     \value SetTextDirectionRightToLeft Set the text direction to right-to-left.
1165     \value ToggleBold Toggle the formatting between bold and normal weight.
1166     \value ToggleItalic Toggle the formatting between italic and normal style.
1167     \value ToggleUnderline Toggle underlining.
1168     \value InspectElement Show the Web Inspector with the currently highlighted HTML element.
1169     \value InsertParagraphSeparator Insert a new paragraph.
1170     \value InsertLineSeparator Insert a new line.
1171     \value SelectAll Selects all content.
1172     \value PasteAndMatchStyle Paste content from the clipboard with current style. (Added in Qt 4.6)
1173     \value RemoveFormat Removes formatting and style. (Added in Qt 4.6)
1174     \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style. (Added in Qt 4.6)
1175     \value ToggleSubscript Toggle the formatting between subscript and baseline. (Added in Qt 4.6)
1176     \value ToggleSuperscript Toggle the formatting between supercript and baseline. (Added in Qt 4.6)
1177     \value InsertUnorderedList Toggles the selection between an ordered list and a normal block. (Added in Qt 4.6)
1178     \value InsertOrderedList Toggles the selection between an ordered list and a normal block. (Added in Qt 4.6)
1179     \value Indent Increases the indentation of the currently selected format block by one increment. (Added in Qt 4.6)
1180     \value Outdent Decreases the indentation of the currently selected format block by one increment. (Added in Qt 4.6)
1181     \value AlignCenter Applies center alignment to content. (Added in Qt 4.6)
1182     \value AlignJustified Applies full justification to content. (Added in Qt 4.6)
1183     \value AlignLeft Applies left justification to content. (Added in Qt 4.6)
1184     \value AlignRight Applies right justification to content. (Added in Qt 4.6)
1185
1186
1187     \omitvalue WebActionCount
1188
1189 */
1190
1191 /*!
1192     \enum QWebPage::WebWindowType
1193
1194     This enum describes the types of window that can be created by the createWindow() function.
1195
1196     \value WebBrowserWindow The window is a regular web browser window.
1197     \value WebModalDialog The window acts as modal dialog.
1198 */
1199
1200
1201 /*!
1202     \class QWebPage::ViewportAttributes
1203     \since 4.7
1204     \brief The QWebPage::ViewportAttributes class describes hints that can be applied to a viewport.
1205
1206     QWebPage::ViewportAttributes provides a description of a viewport, such as viewport geometry,
1207     initial scale factor with limits, plus information about whether a user should be able
1208     to scale the contents in the viewport or not, ie. by zooming.
1209
1210     ViewportAttributes can be set by a web author using the viewport meta tag extension, documented
1211     at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}.
1212
1213     All values might not be set, as such when dealing with the hints, the developer needs to
1214     check whether the values are valid. Negative values denote an invalid qreal value.
1215
1216     \inmodule QtWebKit
1217 */
1218
1219 /*!
1220     Constructs an empty QWebPage::ViewportAttributes.
1221 */
1222 QWebPage::ViewportAttributes::ViewportAttributes()
1223     : d(0)
1224     , m_initialScaleFactor(-1.0)
1225     , m_minimumScaleFactor(-1.0)
1226     , m_maximumScaleFactor(-1.0)
1227     , m_devicePixelRatio(-1.0)
1228     , m_isUserScalable(true)
1229     , m_isValid(false)
1230 {
1231
1232 }
1233
1234 /*!
1235     Constructs a QWebPage::ViewportAttributes which is a copy from \a other .
1236 */
1237 QWebPage::ViewportAttributes::ViewportAttributes(const QWebPage::ViewportAttributes& other)
1238     : d(other.d)
1239     , m_initialScaleFactor(other.m_initialScaleFactor)
1240     , m_minimumScaleFactor(other.m_minimumScaleFactor)
1241     , m_maximumScaleFactor(other.m_maximumScaleFactor)
1242     , m_devicePixelRatio(other.m_devicePixelRatio)
1243     , m_isUserScalable(other.m_isUserScalable)
1244     , m_isValid(other.m_isValid)
1245     , m_size(other.m_size)
1246 {
1247
1248 }
1249
1250 /*!
1251     Destroys the QWebPage::ViewportAttributes.
1252 */
1253 QWebPage::ViewportAttributes::~ViewportAttributes()
1254 {
1255
1256 }
1257
1258 /*!
1259     Assigns the given QWebPage::ViewportAttributes to this viewport hints and returns a
1260     reference to this.
1261 */
1262 QWebPage::ViewportAttributes& QWebPage::ViewportAttributes::operator=(const QWebPage::ViewportAttributes& other)
1263 {
1264     if (this != &other) {
1265         d = other.d;
1266         m_initialScaleFactor = other.m_initialScaleFactor;
1267         m_minimumScaleFactor = other.m_minimumScaleFactor;
1268         m_maximumScaleFactor = other.m_maximumScaleFactor;
1269         m_isUserScalable = other.m_isUserScalable;
1270         m_isValid = other.m_isValid;
1271         m_size = other.m_size;
1272     }
1273
1274     return *this;
1275 }
1276
1277 /*! \fn inline bool QWebPage::ViewportAttributes::isValid() const
1278     Returns whether this is a valid ViewportAttributes or not.
1279
1280     An invalid ViewportAttributes will have an empty QSize, negative values for scale factors and
1281     true for the boolean isUserScalable.
1282 */
1283
1284 /*! \fn inline QSize QWebPage::ViewportAttributes::size() const
1285     Returns the size of the viewport.
1286 */
1287
1288 /*! \fn inline qreal QWebPage::ViewportAttributes::initialScaleFactor() const
1289     Returns the initial scale of the viewport as a multiplier.
1290 */
1291
1292 /*! \fn inline qreal QWebPage::ViewportAttributes::minimumScaleFactor() const
1293     Returns the minimum scale value of the viewport as a multiplier.
1294 */
1295
1296 /*! \fn inline qreal QWebPage::ViewportAttributes::maximumScaleFactor() const
1297     Returns the maximum scale value of the viewport as a multiplier.
1298 */
1299
1300 /*! \fn inline bool QWebPage::ViewportAttributes::isUserScalable() const
1301     Determines whether or not the scale can be modified by the user.
1302 */
1303
1304
1305 /*!
1306     \class QWebPage
1307     \since 4.4
1308     \brief The QWebPage class provides an object to view and edit web documents.
1309
1310     \inmodule QtWebKit
1311
1312     QWebPage holds a main frame responsible for web content, settings, the history
1313     of navigated links and actions. This class can be used, together with QWebFrame,
1314     to provide functionality like QWebView in a widget-less environment.
1315
1316     QWebPage's API is very similar to QWebView, as you are still provided with
1317     common functions like action() (known as
1318     \l{QWebView::pageAction()}{pageAction}() in QWebView), triggerAction(),
1319     findText() and settings(). More QWebView-like functions can be found in the
1320     main frame of QWebPage, obtained via the mainFrame() function. For example,
1321     the \l{QWebFrame::load()}{load}(), \l{QWebFrame::setUrl()}{setUrl}() and
1322     \l{QWebFrame::setHtml()}{setHtml}() functions for QWebPage can be accessed
1323     using QWebFrame.
1324
1325     The loadStarted() signal is emitted when the page begins to load.The
1326     loadProgress() signal, on the other hand, is emitted whenever an element
1327     of the web page completes loading, such as an embedded image, a script,
1328     etc. Finally, the loadFinished() signal is emitted when the page contents
1329     are loaded completely, independent of script execution or page rendering.
1330     Its argument, either true or false, indicates whether or not the load
1331     operation succeeded.
1332
1333     \section1 Using QWebPage in a Widget-less Environment
1334
1335     Before you begin painting a QWebPage object, you need to set the size of
1336     the viewport by calling setViewportSize(). Then, you invoke the main
1337     frame's render function (QWebFrame::render()). An example of this
1338     is shown in the code snippet below.
1339
1340     Suppose we have a \c Thumbnail class as follows:
1341
1342     \snippet webkitsnippets/webpage/main.cpp 0
1343
1344     The \c Thumbnail's constructor takes in a \a url. We connect our QWebPage
1345     object's \l{QWebPage::}{loadFinished()} signal to our private slot,
1346     \c render().
1347
1348     \snippet webkitsnippets/webpage/main.cpp 1
1349
1350     The \c render() function shows how we can paint a thumbnail using a
1351     QWebPage object.
1352
1353     \snippet webkitsnippets/webpage/main.cpp 2
1354
1355     We begin by setting the \l{QWebPage::viewportSize()}{viewportSize} and
1356     then we instantiate a QImage object, \c image, with the same size as our
1357     \l{QWebPage::viewportSize()}{viewportSize}. This image is then sent
1358     as a parameter to \c painter. Next, we render the contents of the main
1359     frame and its subframes into \c painter. Finally, we save the scaled image.
1360
1361     \sa QWebFrame
1362 */
1363
1364 /*!
1365     Constructs an empty QWebPage with parent \a parent.
1366 */
1367 QWebPage::QWebPage(QObject *parent)
1368     : QObject(parent)
1369     , d(new QWebPagePrivate(this))
1370 {
1371     setView(qobject_cast<QWidget*>(parent));
1372
1373     connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int)));
1374 #ifndef NDEBUG
1375     connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages()));
1376 #endif
1377 }
1378
1379 /*!
1380     Destroys the web page.
1381 */
1382 QWebPage::~QWebPage()
1383 {
1384     delete d;
1385 }
1386
1387 /*!
1388     Returns the main frame of the page.
1389
1390     The main frame provides access to the hierarchy of sub-frames and is also needed if you
1391     want to explicitly render a web page into a given painter.
1392
1393     \sa currentFrame()
1394 */
1395 QWebFrame *QWebPage::mainFrame() const
1396 {
1397     d->createMainFrame();
1398     return d->mainFrame.data();
1399 }
1400
1401 /*!
1402     Returns the frame currently active.
1403
1404     \sa mainFrame(), frameCreated()
1405 */
1406 QWebFrame *QWebPage::currentFrame() const
1407 {
1408     d->createMainFrame();
1409     return qobject_cast<QWebFrame*>(d->currentFrame());
1410 }
1411
1412
1413 /*!
1414     \since 4.6
1415
1416     Returns the frame at the given point \a pos, or 0 if there is no frame at
1417     that position.
1418
1419     \sa mainFrame(), currentFrame()
1420 */
1421 QWebFrame* QWebPage::frameAt(const QPoint& pos) const
1422 {
1423     QWebFrame* webFrame = mainFrame();
1424     if (!webFrame->geometry().contains(pos))
1425         return 0;
1426     QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos);
1427     return hitTestResult.frame();
1428 }
1429
1430 /*!
1431     Returns a pointer to the view's history of navigated web pages.
1432 */
1433 QWebHistory *QWebPage::history() const
1434 {
1435     d->createMainFrame();
1436     return &d->history;
1437 }
1438
1439 /*!
1440     Sets the \a view that is associated with the web page.
1441
1442     \sa view()
1443 */
1444 void QWebPage::setView(QWidget* view)
1445 {
1446     if (this->view() == view)
1447         return;
1448
1449     d->view = view;
1450     setViewportSize(view ? view->size() : QSize(0, 0));
1451
1452     // If we have no client, we install a special client delegating
1453     // the responsibility to the QWidget. This is the code path
1454     // handling a.o. the "legacy" QWebView.
1455     //
1456     // If such a special delegate already exist, we substitute the view.
1457
1458     if (d->client) {
1459         if (d->client->isQWidgetClient())
1460             static_cast<PageClientQWidget*>(d->client.data())->view = view;
1461         return;
1462     }
1463
1464     if (view)
1465         d->client.reset(new PageClientQWidget(view, this));
1466 }
1467
1468 /*!
1469     Returns the view widget that is associated with the web page.
1470
1471     \sa setView()
1472 */
1473 QWidget *QWebPage::view() const
1474 {
1475     return d->view.data();
1476 }
1477
1478 /*!
1479     This function is called whenever a JavaScript program tries to print a \a message to the web browser's console.
1480
1481     For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber.
1482
1483     The default implementation prints nothing.
1484 */
1485 void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID)
1486 {
1487     Q_UNUSED(sourceID);
1488     Q_UNUSED(lineNumber);
1489     Q_UNUSED(sourceID);
1490 }
1491
1492 /*!
1493     This function is called whenever a JavaScript program running inside \a frame calls the alert() function with
1494     the message \a msg.
1495
1496     The default implementation shows the message, \a msg, with QMessageBox::information.
1497 */
1498 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
1499 {
1500     Q_UNUSED(frame);
1501 #ifndef QT_NO_MESSAGEBOX
1502     QMessageBox box(view());
1503     box.setWindowTitle(tr("JavaScript Alert - %1").arg(mainFrame()->url().host()));
1504     box.setTextFormat(Qt::PlainText);
1505     box.setText(msg);
1506     box.setStandardButtons(QMessageBox::Ok);
1507     box.exec();
1508 #endif
1509 }
1510
1511 /*!
1512     This function is called whenever a JavaScript program running inside \a frame calls the confirm() function
1513     with the message, \a msg. Returns true if the user confirms the message; otherwise returns false.
1514
1515     The default implementation executes the query using QMessageBox::information with QMessageBox::Ok and QMessageBox::Cancel buttons.
1516 */
1517 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
1518 {
1519     Q_UNUSED(frame);
1520 #ifdef QT_NO_MESSAGEBOX
1521     return true;
1522 #else
1523     QMessageBox box(view());
1524     box.setWindowTitle(tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()));
1525     box.setTextFormat(Qt::PlainText);
1526     box.setText(msg);
1527     box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1528     return QMessageBox::Ok == box.exec();
1529 #endif
1530 }
1531
1532 /*!
1533     This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input.
1534     The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue.
1535
1536     If the prompt was cancelled by the user the implementation should return false; otherwise the
1537     result should be written to \a result and true should be returned. If the prompt was not cancelled by the
1538     user, the implementation should return true and the result string must not be null.
1539
1540     The default implementation uses QInputDialog::getText().
1541 */
1542 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
1543 {
1544     Q_UNUSED(frame);
1545     bool ok = false;
1546 #ifndef QT_NO_INPUTDIALOG
1547
1548     QInputDialog dlg(view());
1549     dlg.setWindowTitle(tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()));
1550
1551     // Hack to force the dialog's QLabel into plain text mode
1552     // prevents https://bugs.webkit.org/show_bug.cgi?id=34429
1553     QLabel* label = dlg.findChild<QLabel*>();
1554     if (label)
1555         label->setTextFormat(Qt::PlainText);
1556
1557     // double the &'s because single & will underline the following character
1558     // (Accelerator mnemonics)
1559     QString escMsg(msg);
1560     escMsg.replace(QChar::fromLatin1('&'), QLatin1String("&&"));
1561     dlg.setLabelText(escMsg);
1562
1563     dlg.setTextEchoMode(QLineEdit::Normal);
1564     dlg.setTextValue(defaultValue);
1565
1566     ok = !!dlg.exec();
1567
1568     if (ok && result)
1569         *result = dlg.textValue();
1570 #endif
1571     return ok;
1572 }
1573
1574 /*!
1575     \fn bool QWebPage::shouldInterruptJavaScript()
1576     \since 4.6
1577     This function is called when a JavaScript program is running for a long period of time.
1578
1579     If the user wanted to stop the JavaScript the implementation should return true; otherwise false.
1580
1581     The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
1582 */
1583 bool QWebPage::shouldInterruptJavaScript()
1584 {
1585 #ifdef QT_NO_MESSAGEBOX
1586     return false;
1587 #else
1588     return QMessageBox::Yes == QMessageBox::information(view(), 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);
1589 #endif
1590 }
1591
1592 void QWebPage::setFeaturePermission(QWebFrame* frame, Feature feature, PermissionPolicy policy)
1593 {
1594 #if !ENABLE(NOTIFICATIONS) && !ENABLE(LEGACY_NOTIFICATIONS) && !ENABLE(GEOLOCATION)
1595     Q_UNUSED(frame);
1596     Q_UNUSED(policy);
1597 #endif
1598     switch (feature) {
1599     case Notifications:
1600 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
1601         if (policy != PermissionUnknown)
1602             d->setNotificationsAllowedForFrame(frame->d, (policy == PermissionGrantedByUser));
1603 #endif
1604         break;
1605     case Geolocation:
1606 #if ENABLE(GEOLOCATION) && HAVE(QTLOCATION)
1607         if (policy != PermissionUnknown)
1608             d->setGeolocationEnabledForFrame(frame->d, (policy == PermissionGrantedByUser));
1609 #endif
1610         break;
1611
1612     default:
1613         break;
1614     }
1615 }
1616
1617 /*!
1618     This function is called whenever WebKit wants to create a new window of the given \a type, for
1619     example when a JavaScript program requests to open a document in a new window.
1620
1621     If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned.
1622
1623     If the view associated with the web page is a QWebView object, then the default implementation forwards
1624     the request to QWebView's createWindow() function; otherwise it returns a null pointer.
1625
1626     If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window.
1627
1628     \note In the cases when the window creation is being triggered by JavaScript, apart from
1629     reimplementing this method application must also set the JavaScriptCanOpenWindows attribute
1630     of QWebSettings to true in order for it to get called.
1631
1632     \sa acceptNavigationRequest(), QWebView::createWindow()
1633 */
1634 QWebPage *QWebPage::createWindow(WebWindowType type)
1635 {
1636     QWebView *webView = qobject_cast<QWebView*>(view());
1637     if (webView) {
1638         QWebView *newView = webView->createWindow(type);
1639         if (newView)
1640             return newView->page();
1641     }
1642     return 0;
1643 }
1644
1645 /*!
1646     This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". It is
1647     called regardless of the value of QWebSettings::PluginsEnabled. The \a classid, \a url, \a paramNames and \a paramValues
1648     correspond to the HTML object element attributes and child elements to configure the embeddable object.
1649 */
1650 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
1651 {
1652     Q_UNUSED(classid);
1653     Q_UNUSED(url);
1654     Q_UNUSED(paramNames);
1655     Q_UNUSED(paramValues);
1656     return 0;
1657 }
1658
1659 /*!
1660  *  Returns the list of all content types supported by QWebPage.
1661  */
1662 QStringList QWebPage::supportedContentTypes() const
1663 {
1664     return d->supportedContentTypes();
1665 }
1666
1667 /*!
1668  *  Returns true if QWebPage can handle the given \a mimeType; otherwise, returns false.
1669  */
1670 bool QWebPage::supportsContentType(const QString& mimeType) const
1671 {
1672     return d->supportsContentType(mimeType);
1673 }
1674
1675 static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list)
1676 {
1677     list << frame->childFrames();
1678     QListIterator<QWebFrame*> it(frame->childFrames());
1679     while (it.hasNext())
1680         collectChildFrames(it.next(), list);
1681 }
1682
1683 /*!
1684     This function can be called to trigger the specified \a action.
1685     It is also called by Qt WebKit if the user triggers the action, for example
1686     through a context menu item.
1687
1688     If \a action is a checkable action then \a checked specified whether the action
1689     is toggled or not.
1690
1691     \sa action()
1692 */
1693 void QWebPage::triggerAction(WebAction action, bool)
1694 {
1695     const char *command = 0;
1696     QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
1697     QWebHitTestResultPrivate* hitTestResult = d->hitTestResult.d;
1698
1699     switch (action) {
1700     case OpenLink:
1701     case OpenLinkInNewWindow:
1702     case OpenLinkInThisWindow:
1703     case OpenFrameInNewWindow:
1704     case CopyLinkToClipboard:
1705     case OpenImageInNewWindow:
1706     case DownloadImageToDisk:
1707     case DownloadLinkToDisk:
1708     case Back:
1709     case Forward:
1710     case Stop:
1711     case Reload:
1712     case SetTextDirectionDefault:
1713     case SetTextDirectionLeftToRight:
1714     case SetTextDirectionRightToLeft:
1715         mappedAction = adapterMenuActionForWebAction(action);
1716         break;
1717     case ReloadAndBypassCache: // Manual mapping
1718         mappedAction = QWebPageAdapter::Reload;
1719         break;
1720 #ifndef QT_NO_CLIPBOARD
1721     case CopyImageToClipboard:
1722         QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap());
1723         break;
1724     case CopyImageUrlToClipboard:
1725         QApplication::clipboard()->setText(d->hitTestResult.imageUrl().toString());
1726         break;
1727 #endif
1728     case InspectElement: {
1729 #if ENABLE(INSPECTOR)
1730         if (!d->hitTestResult.isNull()) {
1731             d->getOrCreateInspector(); // Make sure the inspector is created
1732             d->inspector->show(); // The inspector is expected to be shown on inspection
1733             mappedAction = QWebPageAdapter::InspectElement;
1734         }
1735 #endif
1736         break;
1737     }
1738     case StopScheduledPageRefresh: {
1739         QWebFrame* topFrame = mainFrame();
1740         topFrame->d->cancelLoad();
1741         QList<QWebFrame*> childFrames;
1742         collectChildFrames(topFrame, childFrames);
1743         QListIterator<QWebFrame*> it(childFrames);
1744         while (it.hasNext())
1745             it.next()->d->cancelLoad();
1746         break;
1747     }
1748     default:
1749         command = QWebPagePrivate::editorCommandForWebActions(action);
1750         break;
1751     }
1752     if (command || mappedAction != QWebPageAdapter::NoAction)
1753         d->triggerAction(mappedAction, hitTestResult, command, /*endToEndReload*/ action == ReloadAndBypassCache);
1754 }
1755
1756
1757 QColor QWebPagePrivate::colorSelectionRequested(const QColor &selectedColor)
1758 {
1759     QColor ret = selectedColor;
1760 #ifndef QT_NO_COLORDIALOG
1761     ret = QColorDialog::getColor(selectedColor, q->view());
1762     if (!ret.isValid())
1763         ret = selectedColor;
1764 #endif
1765     return ret;
1766 }
1767
1768 QWebSelectMethod *QWebPagePrivate::createSelectPopup()
1769 {
1770     return new QtFallbackWebPopup(this);
1771 }
1772
1773 QRect QWebPagePrivate::viewRectRelativeToWindow()
1774 {
1775
1776     QWidget* ownerWidget= client.isNull() ? 0 : qobject_cast<QWidget*>(client->ownerWidget());
1777     if (!ownerWidget)
1778         return QRect();
1779     QWidget* topLevelWidget = ownerWidget->window();
1780
1781     QPoint topLeftCorner = ownerWidget->mapFrom(topLevelWidget, QPoint(0, 0));
1782     return QRect(topLeftCorner, ownerWidget->size());
1783 }
1784
1785 void QWebPagePrivate::geolocationPermissionRequested(QWebFrameAdapter* frame)
1786 {
1787     emit q->featurePermissionRequested(QWebFramePrivate::kit(frame), QWebPage::Geolocation);
1788 }
1789
1790 void QWebPagePrivate::geolocationPermissionRequestCancelled(QWebFrameAdapter* frame)
1791 {
1792     emit q->featurePermissionRequestCanceled(QWebFramePrivate::kit(frame), QWebPage::Geolocation);
1793 }
1794
1795 void QWebPagePrivate::notificationsPermissionRequested(QWebFrameAdapter* frame)
1796 {
1797     emit q->featurePermissionRequested(QWebFramePrivate::kit(frame), QWebPage::Notifications);
1798 }
1799
1800 void QWebPagePrivate::notificationsPermissionRequestCancelled(QWebFrameAdapter* frame)
1801 {
1802     emit q->featurePermissionRequestCanceled(QWebFramePrivate::kit(frame), QWebPage::Notifications);
1803 }
1804
1805 void QWebPagePrivate::respondToChangedContents()
1806 {
1807     updateEditorActions();
1808
1809     emit q->contentsChanged();
1810 }
1811
1812 void QWebPagePrivate::respondToChangedSelection()
1813 {
1814     updateEditorActions();
1815     emit q->selectionChanged();
1816 }
1817
1818 void QWebPagePrivate::microFocusChanged()
1819 {
1820     emit q->microFocusChanged();
1821 }
1822
1823 void QWebPagePrivate::triggerCopyAction()
1824 {
1825     q->triggerAction(QWebPage::Copy);
1826 }
1827
1828 void QWebPagePrivate::triggerActionForKeyEvent(QKeyEvent* event)
1829 {
1830     QWebPage::WebAction action = editorActionForKeyEvent(event);
1831     q->triggerAction(action);
1832 }
1833
1834 void QWebPagePrivate::clearUndoStack()
1835 {
1836 #ifndef QT_NO_UNDOSTACK
1837     if (undoStack)
1838         undoStack->clear();
1839 #endif
1840 }
1841
1842 bool QWebPagePrivate::canUndo() const
1843 {
1844 #ifndef QT_NO_UNDOSTACK
1845     if (!undoStack)
1846         return false;
1847     return undoStack->canUndo();
1848 #else
1849     return false;
1850 #endif
1851 }
1852
1853 bool QWebPagePrivate::canRedo() const
1854 {
1855 #ifndef QT_NO_UNDOSTACK
1856     if (!undoStack)
1857         return false;
1858     return undoStack->canRedo();
1859 #else
1860     return false;
1861 #endif
1862 }
1863
1864 void QWebPagePrivate::undo()
1865 {
1866 #ifndef QT_NO_UNDOSTACK
1867     if (undoStack)
1868         undoStack->undo();
1869 #endif
1870 }
1871
1872 void QWebPagePrivate::redo()
1873 {
1874 #ifndef QT_NO_UNDOSTACK
1875     if (undoStack)
1876         undoStack->redo();
1877 #endif
1878 }
1879
1880 void QWebPagePrivate::createUndoStep(QSharedPointer<UndoStepQt> step)
1881 {
1882 #ifndef QT_NO_UNDOSTACK
1883     // Call undoStack() getter first to ensure stack is created
1884     // if it doesn't exist yet.
1885     q->undoStack()->push(new QWebUndoCommand(step));
1886 #endif
1887 }
1888
1889 const char *QWebPagePrivate::editorCommandForKeyEvent(QKeyEvent* event)
1890 {
1891     QWebPage::WebAction action = editorActionForKeyEvent(event);
1892     return editorCommandForWebActions(action);
1893 }
1894
1895 QSize QWebPage::viewportSize() const
1896 {
1897     if (d->mainFrame && d->mainFrame.data()->d->hasView())
1898         return d->mainFrame.data()->d->frameRect().size();
1899
1900     return d->m_viewportSize;
1901 }
1902
1903 /*!
1904     \property QWebPage::viewportSize
1905     \brief the size of the viewport
1906
1907     The size affects for example the visibility of scrollbars
1908     if the document is larger than the viewport.
1909
1910     By default, for a newly-created Web page, this property contains a size with
1911     zero width and height.
1912
1913     \sa QWebFrame::render(), preferredContentsSize
1914 */
1915 void QWebPage::setViewportSize(const QSize &size) const
1916 {
1917     d->m_viewportSize = size;
1918
1919     QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
1920     if (!mainFrame->hasView())
1921         return;
1922
1923     mainFrame->setViewportSize(size);
1924 }
1925
1926 static int getintenv(const char* variable)
1927 {
1928     bool ok;
1929     int value = qgetenv(variable).toInt(&ok);
1930     return (ok) ? value : -1;
1931 }
1932
1933 static QSize queryDeviceSizeForScreenContainingWidget(const QWidget* widget)
1934 {
1935     QDesktopWidget* desktop = QApplication::desktop();
1936     if (!desktop)
1937         return QSize();
1938
1939     QSize size;
1940
1941     if (widget) {
1942         // Returns the available geometry of the screen which contains widget.
1943         // NOTE: this must be the the full screen size including any fixed status areas etc.
1944         size = desktop->availableGeometry(widget).size();
1945     } else
1946         size = desktop->availableGeometry().size();
1947
1948     // This must be in portrait mode, adjust if not.
1949     if (size.width() > size.height()) {
1950         int width = size.width();
1951         size.setWidth(size.height());
1952         size.setHeight(width);
1953     }
1954
1955     return size;
1956 }
1957
1958 /*!
1959     Computes the optimal viewport configuration given the \a availableSize, when
1960     user interface components are disregarded.
1961
1962     The configuration is also dependent on the device screen size which is obtained
1963     automatically. For testing purposes the size can be overridden by setting two
1964     environment variables QTWEBKIT_DEVICE_WIDTH and QTWEBKIT_DEVICE_HEIGHT, which
1965     both needs to be set.
1966
1967     The ViewportAttributes includes a pixel density ratio, which will also be exposed to
1968     the web author though the -webkit-pixel-ratio media feature. This is the ratio
1969     between 1 density-independent pixel (DPI) and physical pixels.
1970
1971     A density-independent pixel is equivalent to one physical pixel on a 160 DPI screen,
1972     so on our platform assumes that as the baseline density.
1973
1974     The conversion of DIP units to screen pixels is quite simple:
1975
1976     pixels = DIPs * (density / 160).
1977
1978     Thus, on a 240 DPI screen, 1 DIPs would equal 1.5 physical pixels.
1979
1980     An invalid instance will be returned in the case an empty size is passed to the
1981     method.
1982
1983     \note The density is automatically obtained from the DPI of the screen where the page
1984     is being shown, but as many X11 servers are reporting wrong DPI, it is possible to
1985     override it using QX11Info::setAppDpiY().
1986 */
1987
1988 QWebPage::ViewportAttributes QWebPage::viewportAttributesForSize(const QSize& availableSize) const
1989 {
1990     ViewportAttributes result;
1991
1992     if (availableSize.isEmpty())
1993         return result; // Returns an invalid instance.
1994
1995     QSize deviceSize(getintenv("QTWEBKIT_DEVICE_WIDTH"), getintenv("QTWEBKIT_DEVICE_HEIGHT"));
1996
1997     // Both environment variables need to be set - or they will be ignored.
1998     if (deviceSize.isNull())
1999         deviceSize = queryDeviceSizeForScreenContainingWidget(view());
2000     QWebPageAdapter::ViewportAttributes attr = d->viewportAttributesForSize(availableSize, deviceSize);
2001
2002     result.m_isValid = true;
2003     result.m_size = attr.size;
2004     result.m_initialScaleFactor = attr.initialScaleFactor;
2005     result.m_minimumScaleFactor = attr.minimumScaleFactor;
2006     result.m_maximumScaleFactor = attr.maximumScaleFactor;
2007     result.m_devicePixelRatio = attr.devicePixelRatio;
2008     result.m_isUserScalable = attr.isUserScalable;
2009
2010     return result;
2011 }
2012
2013 QSize QWebPage::preferredContentsSize() const
2014 {
2015     QWebFrameAdapter* mainFrame = d->mainFrame ? d->mainFrame->d : 0;
2016     QSize customSize;
2017     if (mainFrame && mainFrame->hasView())
2018         customSize = mainFrame->customLayoutSize();
2019
2020     return customSize.isNull() ? d->fixedLayoutSize : customSize;
2021 }
2022
2023 /*!
2024     \property QWebPage::preferredContentsSize
2025     \since 4.6
2026     \brief a custom size used for laying out the page contents.
2027
2028     By default all pages are laid out using the viewport of the page as the base.
2029
2030     As pages mostly are designed for desktop usage, they often do not layout properly
2031     on small devices as the contents require a certain view width. For this reason
2032     it is common to use a different layout size and then scale the contents to fit
2033     within the actual view.
2034
2035     If this property is set to a valid size, this size is used for all layout needs
2036     instead of the size of the viewport.
2037
2038     Setting an invalid size, makes the page fall back to using the viewport size for layout.
2039
2040     \sa viewportSize
2041 */
2042 void QWebPage::setPreferredContentsSize(const QSize& size) const
2043 {
2044     // FIXME: Rename this method to setCustomLayoutSize
2045
2046     d->fixedLayoutSize = size;
2047
2048     QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
2049     if (!mainFrame->hasView())
2050         return;
2051
2052     mainFrame->setCustomLayoutSize(size);
2053 }
2054
2055 /*
2056     This function is to be called after any (animated) scroll/pan has ended, in the case the application handles the
2057     scrolling/panning of the web contents. This is commonly used in combination with tiling where is it common for
2058     the application to pan the actual view, which then resizes itself to the size of the contents.
2059
2060     \note Calling this function makes WebKit stop trying to calculate the visibleContentRect. To turn that on
2061     again, call this method with an empty rect.
2062
2063     \sa QGraphicsWebView::resizesToContents, QWebSettings::TiledBackingStoreEnabled
2064 */
2065 void QWebPage::setActualVisibleContentRect(const QRect& rect) const
2066 {
2067     QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
2068     if (!mainFrame->hasView())
2069         return;
2070
2071     mainFrame->setFixedVisibleContentRect(rect);
2072 }
2073
2074 /*!
2075     \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
2076
2077     This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of
2078     the specified navigation type \a type.
2079
2080     If \a frame is a null pointer then navigation to a new window is requested. If the request is
2081     accepted createWindow() will be called.
2082
2083     The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true
2084     to let QWebPage handle the navigation itself.
2085
2086     \sa createWindow()
2087 */
2088 bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
2089 {
2090     Q_UNUSED(frame);
2091     if (type == NavigationTypeLinkClicked) {
2092         switch (d->linkPolicy) {
2093         case DontDelegateLinks:
2094             return true;
2095
2096         case DelegateExternalLinks:
2097             if (QWebPageAdapter::treatSchemeAsLocal(request.url().scheme()))
2098                 return true;
2099             emit linkClicked(request.url());
2100             return false;
2101
2102         case DelegateAllLinks:
2103             emit linkClicked(request.url());
2104             return false;
2105         }
2106     }
2107     return true;
2108 }
2109
2110 /*!
2111     \property QWebPage::hasSelection
2112     \brief whether this page contains selected content or not.
2113
2114     \sa selectionChanged()
2115 */
2116 bool QWebPage::hasSelection() const
2117 {
2118     d->createMainFrame();
2119     return d->hasSelection();
2120 }
2121
2122 /*!
2123     \property QWebPage::selectedText
2124     \brief the text currently selected
2125
2126     By default, this property contains an empty string.
2127
2128     \sa selectionChanged(), selectedHtml()
2129 */
2130 QString QWebPage::selectedText() const
2131 {
2132     d->createMainFrame();
2133     return d->selectedText();
2134 }
2135
2136 /*!
2137     \since 4.8
2138     \property QWebPage::selectedHtml
2139     \brief the HTML currently selected
2140
2141     By default, this property contains an empty string.
2142
2143     \sa selectionChanged(), selectedText()
2144 */
2145 QString QWebPage::selectedHtml() const
2146 {
2147     d->createMainFrame();
2148     return d->selectedHtml();
2149 }
2150
2151 #ifndef QT_NO_ACTION
2152 /*!
2153    Returns a QAction for the specified WebAction \a action.
2154
2155    The action is owned by the QWebPage but you can customize the look by
2156    changing its properties.
2157
2158    QWebPage also takes care of implementing the action, so that upon
2159    triggering the corresponding action is performed on the page.
2160
2161    \sa triggerAction()
2162 */
2163 QAction *QWebPage::action(WebAction action) const
2164 {
2165     if (action == QWebPage::NoWebAction)
2166         return 0;
2167     if (d->actions[action])
2168         return d->actions[action];
2169
2170     QString text;
2171     QIcon icon;
2172     QStyle *style = d->client ? d->client->style() : qApp->style();
2173     bool checkable = false;
2174     QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
2175
2176     switch (action) {
2177     // to be fetched from LocalizedStringsQt via the page adapter
2178     case OpenLink:
2179     case OpenLinkInNewWindow:
2180     case OpenFrameInNewWindow:
2181     case OpenLinkInThisWindow:
2182     case DownloadLinkToDisk:
2183     case CopyLinkToClipboard:
2184     case OpenImageInNewWindow:
2185     case DownloadImageToDisk:
2186     case CopyImageToClipboard:
2187     case CopyImageUrlToClipboard:
2188     case Cut:
2189     case Copy:
2190     case Paste:
2191     case SelectAll:
2192     case SetTextDirectionDefault:
2193     case SetTextDirectionLeftToRight:
2194     case SetTextDirectionRightToLeft:
2195     case ToggleBold:
2196     case ToggleItalic:
2197     case ToggleUnderline:
2198         mappedAction = adapterMenuActionForWebAction(action);
2199         break;
2200     case InspectElement:
2201 #if ENABLE(INSPECTOR)
2202         mappedAction = QWebPageAdapter::InspectElement;
2203 #endif
2204         break;
2205
2206         // icon needed as well, map by hand.
2207     case Back:
2208         mappedAction = QWebPageAdapter::Back;
2209         icon = style->standardIcon(QStyle::SP_ArrowBack);
2210         break;
2211     case Forward:
2212         mappedAction = QWebPageAdapter::Forward;
2213         icon = style->standardIcon(QStyle::SP_ArrowForward);
2214         break;
2215     case Stop:
2216         mappedAction = QWebPageAdapter::Stop;
2217         icon = style->standardIcon(QStyle::SP_BrowserStop);
2218         break;
2219     case Reload:
2220         mappedAction = QWebPageAdapter::Reload;
2221         icon = style->standardIcon(QStyle::SP_BrowserReload);
2222         break;
2223
2224 #ifndef QT_NO_UNDOSTACK
2225     case Undo: {
2226         QAction *a = undoStack()->createUndoAction(d->q);
2227         d->actions[action] = a;
2228         return a;
2229     }
2230     case Redo: {
2231         QAction *a = undoStack()->createRedoAction(d->q);
2232         d->actions[action] = a;
2233         return a;
2234     }
2235 #endif // QT_NO_UNDOSTACK
2236         // in place l10n
2237         case MoveToNextChar:
2238             text = tr("Move the cursor to the next character");
2239             break;
2240         case MoveToPreviousChar:
2241             text = tr("Move the cursor to the previous character");
2242             break;
2243         case MoveToNextWord:
2244             text = tr("Move the cursor to the next word");
2245             break;
2246         case MoveToPreviousWord:
2247             text = tr("Move the cursor to the previous word");
2248             break;
2249         case MoveToNextLine:
2250             text = tr("Move the cursor to the next line");
2251             break;
2252         case MoveToPreviousLine:
2253             text = tr("Move the cursor to the previous line");
2254             break;
2255         case MoveToStartOfLine:
2256             text = tr("Move the cursor to the start of the line");
2257             break;
2258         case MoveToEndOfLine:
2259             text = tr("Move the cursor to the end of the line");
2260             break;
2261         case MoveToStartOfBlock:
2262             text = tr("Move the cursor to the start of the block");
2263             break;
2264         case MoveToEndOfBlock:
2265             text = tr("Move the cursor to the end of the block");
2266             break;
2267         case MoveToStartOfDocument:
2268             text = tr("Move the cursor to the start of the document");
2269             break;
2270         case MoveToEndOfDocument:
2271             text = tr("Move the cursor to the end of the document");
2272             break;
2273         case SelectNextChar:
2274             text = tr("Select to the next character");
2275             break;
2276         case SelectPreviousChar:
2277             text = tr("Select to the previous character");
2278             break;
2279         case SelectNextWord:
2280             text = tr("Select to the next word");
2281             break;
2282         case SelectPreviousWord:
2283             text = tr("Select to the previous word");
2284             break;
2285         case SelectNextLine:
2286             text = tr("Select to the next line");
2287             break;
2288         case SelectPreviousLine:
2289             text = tr("Select to the previous line");
2290             break;
2291         case SelectStartOfLine:
2292             text = tr("Select to the start of the line");
2293             break;
2294         case SelectEndOfLine:
2295             text = tr("Select to the end of the line");
2296             break;
2297         case SelectStartOfBlock:
2298             text = tr("Select to the start of the block");
2299             break;
2300         case SelectEndOfBlock:
2301             text = tr("Select to the end of the block");
2302             break;
2303         case SelectStartOfDocument:
2304             text = tr("Select to the start of the document");
2305             break;
2306         case SelectEndOfDocument:
2307             text = tr("Select to the end of the document");
2308             break;
2309         case DeleteStartOfWord:
2310             text = tr("Delete to the start of the word");
2311             break;
2312         case DeleteEndOfWord:
2313             text = tr("Delete to the end of the word");
2314             break;
2315
2316         case InsertParagraphSeparator:
2317             text = tr("Insert a new paragraph");
2318             break;
2319         case InsertLineSeparator:
2320             text = tr("Insert a new line");
2321             break;
2322
2323         case PasteAndMatchStyle:
2324             text = tr("Paste and Match Style");
2325             break;
2326         case RemoveFormat:
2327             text = tr("Remove formatting");
2328             break;
2329
2330         case ToggleStrikethrough:
2331             text = tr("Strikethrough");
2332             checkable = true;
2333             break;
2334         case ToggleSubscript:
2335             text = tr("Subscript");
2336             checkable = true;
2337             break;
2338         case ToggleSuperscript:
2339             text = tr("Superscript");
2340             checkable = true;
2341             break;
2342         case InsertUnorderedList:
2343             text = tr("Insert Bulleted List");
2344             checkable = true;
2345             break;
2346         case InsertOrderedList:
2347             text = tr("Insert Numbered List");
2348             checkable = true;
2349             break;
2350         case Indent:
2351             text = tr("Indent");
2352             break;
2353         case Outdent:
2354             text = tr("Outdent");
2355             break;
2356         case AlignCenter:
2357             text = tr("Center");
2358             break;
2359         case AlignJustified:
2360             text = tr("Justify");
2361             break;
2362         case AlignLeft:
2363             text = tr("Align Left");
2364             break;
2365         case AlignRight:
2366             text = tr("Align Right");
2367             break;
2368         case NoWebAction:
2369             return 0;
2370         default:
2371             break;
2372     }
2373     if (mappedAction != QWebPageAdapter::NoAction)
2374         text = d->contextMenuItemTagForAction(mappedAction, &checkable);
2375
2376     if (text.isEmpty())
2377         return 0;
2378
2379     QAction *a = new QAction(d->q);
2380     a->setText(text);
2381     a->setData(action);
2382     a->setCheckable(checkable);
2383     a->setIcon(icon);
2384
2385     connect(a, SIGNAL(triggered(bool)),
2386         this, SLOT(_q_webActionTriggered(bool)));
2387
2388     d->actions[action] = a;
2389     d->updateAction(action);
2390     return a;
2391 }
2392 #endif // QT_NO_ACTION
2393
2394 /*!
2395     \property QWebPage::modified
2396     \brief whether the page contains unsubmitted form data, or the contents have been changed.
2397
2398     By default, this property is false.
2399
2400     \sa contentsChanged(), contentEditable, undoStack()
2401 */
2402 bool QWebPage::isModified() const
2403 {
2404 #ifdef QT_NO_UNDOSTACK
2405     return false;
2406 #else
2407     if (!d->undoStack)
2408         return false;
2409     return d->undoStack->canUndo();
2410 #endif // QT_NO_UNDOSTACK
2411 }
2412
2413 #ifndef QT_NO_UNDOSTACK
2414 /*!
2415     Returns a pointer to the undo stack used for editable content.
2416
2417     \sa modified
2418 */
2419 QUndoStack *QWebPage::undoStack() const
2420 {
2421     if (!d->undoStack)
2422         d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
2423
2424     return d->undoStack;
2425 }
2426 #endif // QT_NO_UNDOSTACK
2427
2428 /*! \reimp
2429 */
2430 bool QWebPage::event(QEvent *ev)
2431 {
2432     switch (ev->type()) {
2433     case QEvent::Timer:
2434         d->timerEvent(static_cast<QTimerEvent*>(ev));
2435         break;
2436     case QEvent::MouseMove:
2437         d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
2438         break;
2439     case QEvent::MouseButtonPress:
2440         d->mousePressEvent(static_cast<QMouseEvent*>(ev));
2441         break;
2442     case QEvent::MouseButtonDblClick:
2443         d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
2444         break;
2445     case QEvent::MouseButtonRelease:
2446         d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
2447         break;
2448 #if !defined(QT_NO_GRAPHICSVIEW)
2449     case QEvent::GraphicsSceneMouseMove: {
2450         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2451         QMouseEvent dummyEvent(QEvent::MouseMove, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2452         d->mouseMoveEvent(&dummyEvent);
2453         ev->setAccepted(dummyEvent.isAccepted());
2454         break;
2455     }
2456     case QEvent::GraphicsSceneMouseRelease: {
2457         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2458         QMouseEvent dummyEvent(QEvent::MouseButtonRelease, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2459         d->adjustPointForClicking(&dummyEvent);
2460         d->mouseReleaseEvent(&dummyEvent);
2461         ev->setAccepted(dummyEvent.isAccepted());
2462         break;
2463     }
2464     case QEvent::GraphicsSceneMousePress: {
2465         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2466         QMouseEvent dummyEvent(QEvent::MouseButtonPress, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2467         d->adjustPointForClicking(&dummyEvent);
2468         d->mousePressEvent(&dummyEvent);
2469         ev->setAccepted(dummyEvent.isAccepted());
2470         break;
2471     }
2472     case QEvent::GraphicsSceneMouseDoubleClick: {
2473         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2474         QMouseEvent dummyEvent(QEvent::MouseButtonDblClick, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2475         d->adjustPointForClicking(&dummyEvent);
2476         d->mouseDoubleClickEvent(&dummyEvent);
2477         ev->setAccepted(dummyEvent.isAccepted());
2478         break;
2479     }
2480 #endif
2481 #ifndef QT_NO_CONTEXTMENU
2482     case QEvent::ContextMenu:
2483         d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos());
2484         break;
2485 #if !defined(QT_NO_GRAPHICSVIEW)
2486     case QEvent::GraphicsSceneContextMenu:
2487         d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos());
2488         break;
2489 #endif
2490 #endif
2491 #ifndef QT_NO_WHEELEVENT
2492     case QEvent::Wheel:
2493         d->wheelEvent(static_cast<QWheelEvent*>(ev), QApplication::wheelScrollLines());
2494         break;
2495 #if !defined(QT_NO_GRAPHICSVIEW)
2496     case QEvent::GraphicsSceneWheel: {
2497         QGraphicsSceneWheelEvent *gsEv = static_cast<QGraphicsSceneWheelEvent*>(ev);
2498         QWheelEvent dummyEvent(gsEv->pos(), gsEv->screenPos(), gsEv->delta(), gsEv->buttons(), gsEv->modifiers(), gsEv->orientation());
2499         d->wheelEvent(&dummyEvent, QApplication::wheelScrollLines());
2500         ev->setAccepted(dummyEvent.isAccepted());
2501         break;
2502     }
2503 #endif
2504 #endif
2505     case QEvent::KeyPress:
2506         d->keyPressEvent(static_cast<QKeyEvent*>(ev));
2507         break;
2508     case QEvent::KeyRelease:
2509         d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
2510         break;
2511     case QEvent::FocusIn:
2512         d->focusInEvent(static_cast<QFocusEvent*>(ev));
2513         break;
2514     case QEvent::FocusOut:
2515         d->focusOutEvent(static_cast<QFocusEvent*>(ev));
2516         break;
2517 #ifndef QT_NO_DRAGANDDROP
2518     case QEvent::DragEnter:
2519         d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
2520         break;
2521     case QEvent::DragLeave:
2522         d->dragLeaveEvent();
2523         ev->accept();
2524         break;
2525     case QEvent::DragMove:
2526         d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
2527         break;
2528     case QEvent::Drop:
2529         d->dropEvent(static_cast<QDropEvent*>(ev));
2530         break;
2531 #if !defined(QT_NO_GRAPHICSVIEW)
2532     case QEvent::GraphicsSceneDragEnter:
2533         d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2534         break;
2535     case QEvent::GraphicsSceneDragMove:
2536         d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2537         break;
2538     case QEvent::GraphicsSceneDragLeave:
2539         d->dragLeaveEvent();
2540         ev->accept();
2541         break;
2542     case QEvent::GraphicsSceneDrop:
2543         d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2544         break;
2545 #endif
2546
2547 #endif
2548     case QEvent::InputMethod:
2549         d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev));
2550         break;
2551     case QEvent::ShortcutOverride:
2552         d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev));
2553         break;
2554     case QEvent::Leave:
2555         d->leaveEvent(ev);
2556         break;
2557     case QEvent::TouchBegin:
2558     case QEvent::TouchUpdate:
2559     case QEvent::TouchEnd:
2560     case QEvent::TouchCancel:
2561         // Return whether the default action was cancelled in the JS event handler
2562         return d->touchEvent(static_cast<QTouchEvent*>(ev));
2563 #ifndef QT_NO_GESTURES
2564     case QEvent::Gesture:
2565         d->gestureEvent(static_cast<QGestureEvent*>(ev));
2566         break;
2567 #endif
2568 #ifndef QT_NO_PROPERTIES
2569     case QEvent::DynamicPropertyChange:
2570         d->dynamicPropertyChangeEvent(this, static_cast<QDynamicPropertyChangeEvent*>(ev));
2571         break;
2572 #endif
2573     default:
2574         return QObject::event(ev);
2575     }
2576
2577     return true;
2578 }
2579
2580 /*!
2581     Similar to QWidget::focusNextPrevChild() it focuses the next focusable web element
2582     if \a next is true; otherwise the previous element is focused.
2583
2584     Returns true if it can find a new focusable element, or false if it can't.
2585 */
2586 bool QWebPage::focusNextPrevChild(bool next)
2587 {
2588     QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
2589     d->keyPressEvent(&ev);
2590     return d->hasFocusedNode();
2591 }
2592
2593 /*!
2594     \property QWebPage::contentEditable
2595     \brief whether the content in this QWebPage is editable or not
2596     \since 4.5
2597
2598     If this property is enabled the contents of the page can be edited by the user through a visible
2599     cursor. If disabled (the default) only HTML elements in the web page with their
2600     \c{contenteditable} attribute set are editable.
2601
2602     \sa modified, contentsChanged(), WebAction
2603 */
2604 void QWebPage::setContentEditable(bool editable)
2605 {
2606     if (isContentEditable() != editable) {
2607         d->setContentEditable(editable);
2608         d->updateEditorActions();
2609     }
2610 }
2611
2612 bool QWebPage::isContentEditable() const
2613 {
2614     return d->isContentEditable();
2615 }
2616
2617 /*!
2618     \property QWebPage::forwardUnsupportedContent
2619     \brief whether QWebPage should forward unsupported content
2620
2621     If enabled, the unsupportedContent() signal is emitted with a network reply that
2622     can be used to read the content.
2623
2624     If disabled, the download of such content is aborted immediately.
2625
2626     By default unsupported content is not forwarded.
2627 */
2628
2629 void QWebPage::setForwardUnsupportedContent(bool forward)
2630 {
2631     d->forwardUnsupportedContent = forward;
2632 }
2633
2634 bool QWebPage::forwardUnsupportedContent() const
2635 {
2636     return d->forwardUnsupportedContent;
2637 }
2638
2639 /*!
2640     \property QWebPage::linkDelegationPolicy
2641     \brief how QWebPage should delegate the handling of links through the
2642     linkClicked() signal
2643
2644     The default is to delegate no links.
2645 */
2646
2647 void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy)
2648 {
2649     d->linkPolicy = policy;
2650 }
2651
2652 QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const
2653 {
2654     return d->linkPolicy;
2655 }
2656
2657 #ifndef QT_NO_CONTEXTMENU
2658
2659 bool QWebPagePrivate::handleScrollbarContextMenuEvent(QContextMenuEvent* event, bool horizontal, QWebPageAdapter::ScrollDirection* direction, QWebPageAdapter::ScrollGranularity* granularity)
2660 {
2661     if (!QApplication::style()->styleHint(QStyle::SH_ScrollBar_ContextMenu))
2662         return false;
2663
2664     QMenu menu;
2665     QAction* actScrollHere = menu.addAction(QCoreApplication::translate("QWebPage", "Scroll here"));
2666     menu.addSeparator();
2667
2668     QAction* actScrollTop = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Left edge") : QCoreApplication::translate("QWebPage", "Top"));
2669     QAction* actScrollBottom = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Right edge") : QCoreApplication::translate("QWebPage", "Bottom"));
2670     menu.addSeparator();
2671
2672     QAction* actPageUp = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Page left") : QCoreApplication::translate("QWebPage", "Page up"));
2673     QAction* actPageDown = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Page right") : QCoreApplication::translate("QWebPage", "Page down"));
2674     menu.addSeparator();
2675
2676     QAction* actScrollUp = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Scroll left") : QCoreApplication::translate("QWebPage", "Scroll up"));
2677     QAction* actScrollDown = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Scroll right") : QCoreApplication::translate("QWebPage", "Scroll down"));
2678
2679     QAction* actionSelected = menu.exec(event->globalPos());
2680
2681     if (actionSelected == actScrollHere)
2682         return true;
2683     if (actionSelected == actScrollTop) {
2684         *direction = horizontal ? ScrollLeft : ScrollUp;
2685         *granularity = ScrollByDocument;
2686     } else if (actionSelected == actScrollBottom) {
2687         *direction =horizontal ? ScrollRight : ScrollDown;
2688         *granularity = ScrollByDocument;
2689     } else if (actionSelected == actPageUp) {
2690         *direction = horizontal ? ScrollLeft : ScrollUp;
2691         *granularity = ScrollByPage;
2692     } else if (actionSelected == actPageDown) {
2693         *direction =horizontal ? ScrollRight : ScrollDown;
2694         *granularity = ScrollByPage;
2695     } else if (actionSelected == actScrollUp) {
2696         *direction = horizontal ? ScrollLeft : ScrollUp;
2697         *granularity = ScrollByLine;
2698     } else if (actionSelected == actScrollDown) {
2699         *direction =horizontal ? ScrollRight : ScrollDown;
2700         *granularity = ScrollByLine;
2701     }
2702     return true;
2703 }
2704
2705 /*!
2706     Filters the context menu event, \a event, through handlers for scrollbars and
2707     custom event handlers in the web page. Returns true if the event was handled;
2708     otherwise false.
2709
2710     A web page may swallow a context menu event through a custom event handler, allowing for context
2711     menus to be implemented in HTML/JavaScript. This is used by \l{http://maps.google.com/}{Google
2712     Maps}, for example.
2713 */
2714 bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event)
2715 {
2716     QWebFrame* webFrame = frameAt(event->pos());
2717     return d->swallowContextMenuEvent(event, webFrame ? webFrame->d : 0);
2718 }
2719 #endif // QT_NO_CONTEXTMENU
2720
2721 /*!
2722     Updates the page's actions depending on the position \a pos. For example if \a pos is over an image
2723     element the CopyImageToClipboard action is enabled.
2724 */
2725 void QWebPage::updatePositionDependentActions(const QPoint &pos)
2726 {
2727 #ifndef QT_NO_ACTION
2728     // First we disable all actions, but keep track of which ones were originally enabled.
2729     QBitArray originallyEnabledWebActions(QWebPage::WebActionCount);
2730     for (int i = QWebPageAdapter::NoAction + 1; i < QWebPageAdapter::ActionCount; ++i) {
2731         QWebPage::WebAction action = webActionForAdapterMenuAction(QWebPageAdapter::MenuAction(i));
2732         if (QAction *a = this->action(action)) {
2733             originallyEnabledWebActions.setBit(action, a->isEnabled());
2734             a->setEnabled(false);
2735         }
2736     }
2737 #endif // QT_NO_ACTION
2738
2739     QBitArray visitedWebActions(QWebPage::WebActionCount);
2740     d->createMainFrame();
2741     // Then we let updatePositionDependantMenuActions() enable the actions that are put into the menu
2742     QWebHitTestResultPrivate* result = d->updatePositionDependentMenuActions(pos, &visitedWebActions);
2743     if (!result)
2744         d->hitTestResult = QWebHitTestResult();
2745     else
2746         d->hitTestResult = QWebHitTestResult(result);
2747
2748 #ifndef QT_NO_ACTION
2749     // Finally, we restore the original enablement for the actions that were not put into the menu.
2750     originallyEnabledWebActions &= ~visitedWebActions; // Mask out visited actions (they're part of the menu)
2751     for (int i = 0; i < QWebPage::WebActionCount; ++i) {
2752         if (originallyEnabledWebActions.at(i)) {
2753             if (QAction *a = this->action(QWebPage::WebAction(i)))
2754                 a->setEnabled(true);
2755         }
2756     }
2757 #endif // QT_NO_ACTION
2758
2759     // This whole process ensures that any actions put into to the context menu has the right
2760     // enablement, while also keeping the correct enablement for actions that were left out of
2761     // the menu.
2762
2763 }
2764
2765
2766
2767 /*!
2768     \enum QWebPage::Extension
2769
2770     This enum describes the types of extensions that the page can support. Before using these extensions, you
2771     should verify that the extension is supported by calling supportsExtension().
2772
2773     \value ChooseMultipleFilesExtension Whether the web page supports multiple file selection.
2774     This extension is invoked when the web content requests one or more file names, for example
2775     as a result of the user clicking on a "file upload" button in a HTML form where multiple
2776     file selection is allowed.
2777
2778     \value ErrorPageExtension Whether the web page can provide an error page when loading fails.
2779     (introduced in Qt 4.6)
2780
2781     \sa ChooseMultipleFilesExtensionOption, ChooseMultipleFilesExtensionReturn, ErrorPageExtensionOption, ErrorPageExtensionReturn
2782 */
2783
2784 /*!
2785     \enum QWebPage::ErrorDomain
2786     \since 4.6
2787
2788     This enum describes the domain of an ErrorPageExtensionOption object (i.e. the layer in which the error occurred).
2789
2790     \value QtNetwork The error occurred in the QtNetwork layer; the error code is of type QNetworkReply::NetworkError.
2791     \value Http The error occurred in the HTTP layer; the error code is a HTTP status code (see QNetworkRequest::HttpStatusCodeAttribute).
2792     \value WebKit The error is an internal WebKit error.
2793 */
2794
2795 /*!
2796     \class QWebPage::ExtensionOption
2797     \since 4.4
2798     \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support.
2799
2800     \inmodule QtWebKit
2801
2802     \sa QWebPage::extension(), QWebPage::ExtensionReturn
2803 */
2804
2805
2806 /*!
2807     \class QWebPage::ExtensionReturn
2808     \since 4.4
2809     \brief The ExtensionReturn class provides an output result from a QWebPage's extension.
2810
2811     \inmodule QtWebKit
2812
2813     \sa QWebPage::extension(), QWebPage::ExtensionOption
2814 */
2815
2816 /*!
2817     \class QWebPage::ErrorPageExtensionOption
2818     \since 4.6
2819     \brief The ErrorPageExtensionOption class describes the option
2820     for the error page extension.
2821
2822     \inmodule QtWebKit
2823
2824     The ErrorPageExtensionOption class holds the \a url for which an error occurred as well as
2825     the associated \a frame.
2826
2827     The error itself is reported by an error \a domain, the \a error code as well as \a errorString.
2828
2829     \sa QWebPage::extension(), QWebPage::ErrorPageExtensionReturn
2830 */
2831
2832 /*!
2833     \variable QWebPage::ErrorPageExtensionOption::url
2834     \brief the url for which an error occurred
2835 */
2836
2837 /*!
2838     \variable QWebPage::ErrorPageExtensionOption::frame
2839     \brief the frame associated with the error
2840 */
2841
2842 /*!
2843     \variable QWebPage::ErrorPageExtensionOption::domain
2844     \brief the domain that reported the error
2845 */
2846
2847 /*!
2848     \variable QWebPage::ErrorPageExtensionOption::error
2849     \brief the error code. Interpretation of the value depends on the \a domain
2850     \sa QWebPage::ErrorDomain
2851 */
2852
2853 /*!
2854     \variable QWebPage::ErrorPageExtensionOption::errorString
2855     \brief a string that describes the error
2856 */
2857
2858 /*!
2859     \class QWebPage::ErrorPageExtensionReturn
2860     \since 4.6
2861     \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the
2862     frame for which the error occured.
2863
2864     \inmodule QtWebKit
2865
2866     The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are
2867     optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which
2868     is assumed to be UTF-8 if not indicated otherwise.
2869
2870     The error page is stored in the \a content byte array, as HTML content. In order to convert a
2871     QString to a byte array, the QString::toUtf8() method can be used.
2872
2873     External objects such as stylesheets or images referenced in the HTML are located relative to
2874     \a baseUrl.
2875
2876     \sa QWebPage::extension(), QWebPage::ErrorPageExtensionOption, QString::toUtf8()
2877 */
2878
2879 /*!
2880     \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn()
2881
2882     Constructs a new error page object.
2883 */
2884
2885
2886 /*!
2887     \variable QWebPage::ErrorPageExtensionReturn::contentType
2888     \brief the error page's content type
2889 */
2890
2891 /*!
2892     \variable QWebPage::ErrorPageExtensionReturn::encoding
2893     \brief the error page encoding
2894 */
2895
2896 /*!
2897     \variable QWebPage::ErrorPageExtensionReturn::baseUrl
2898     \brief the base url
2899
2900     External objects such as stylesheets or images referenced in the HTML are located relative to this url.
2901 */
2902
2903 /*!
2904     \variable QWebPage::ErrorPageExtensionReturn::content
2905     \brief the HTML content of the error page
2906 */
2907
2908 /*!
2909     \class QWebPage::ChooseMultipleFilesExtensionOption
2910     \since 4.5
2911     \brief The ChooseMultipleFilesExtensionOption class describes the option
2912     for the multiple files selection extension.
2913
2914     \inmodule QtWebKit
2915
2916     The ChooseMultipleFilesExtensionOption class holds the frame originating the request
2917     and the suggested filenames which might be provided.
2918
2919     \sa QWebPage::extension(), QWebPage::chooseFile(), QWebPage::ChooseMultipleFilesExtensionReturn
2920 */
2921
2922 /*!
2923     \variable QWebPage::ChooseMultipleFilesExtensionOption::parentFrame
2924     \brief The frame in which the request originated
2925 */
2926
2927 /*!
2928     \variable QWebPage::ChooseMultipleFilesExtensionOption::suggestedFileNames
2929     \brief The suggested filenames
2930 */
2931
2932 /*!
2933     \variable QWebPage::ChooseMultipleFilesExtensionReturn::fileNames
2934     \brief The selected filenames
2935 */
2936
2937 /*!
2938     \class QWebPage::ChooseMultipleFilesExtensionReturn
2939     \since 4.5
2940     \brief The ChooseMultipleFilesExtensionReturn describes the return value
2941     for the multiple files selection extension.
2942
2943     \inmodule QtWebKit
2944
2945     The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user
2946     when the extension is invoked.
2947
2948     \sa QWebPage::extension(), QWebPage::ChooseMultipleFilesExtensionOption
2949 */
2950
2951 /*!
2952     This virtual function can be reimplemented in a QWebPage subclass to provide support for extensions. The \a option
2953     argument is provided as input to the extension; the output results can be stored in \a output.
2954
2955     The behavior of this function is determined by \a extension. The \a option
2956     and \a output values are typically casted to the corresponding types (for
2957     example, ChooseMultipleFilesExtensionOption and
2958     ChooseMultipleFilesExtensionReturn for ChooseMultipleFilesExtension).
2959
2960     You can call supportsExtension() to check if an extension is supported by the page.
2961
2962     Returns true if the extension was called successfully; otherwise returns false.
2963
2964     \sa supportsExtension(), Extension
2965 */
2966 bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
2967 {
2968 #ifndef QT_NO_FILEDIALOG
2969     if (extension == ChooseMultipleFilesExtension) {
2970         // FIXME: do not ignore suggestedFiles
2971         QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames;
2972         QStringList names = QFileDialog::getOpenFileNames(view(), QString::null);
2973         static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
2974         return true;
2975     }
2976 #endif
2977
2978     return false;
2979 }
2980
2981 /*!
2982     This virtual function returns true if the web page supports \a extension; otherwise false is returned.
2983
2984     \sa extension()
2985 */
2986 bool QWebPage::supportsExtension(Extension extension) const
2987 {
2988 #ifndef QT_NO_FILEDIALOG
2989     return extension == ChooseMultipleFilesExtension;
2990 #else
2991     Q_UNUSED(extension);
2992     return false;
2993 #endif
2994 }
2995
2996 /*!
2997  * \internal
2998  */
2999 QWebPageAdapter *QWebPage::handle() const
3000 {
3001     return d;
3002 }
3003
3004 /*!
3005     Finds the specified string, \a subString, in the page, using the given \a options.
3006
3007     If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences
3008     that exist in the page. All subsequent calls will extend the highlight, rather than
3009     replace it, with occurrences of the new string.
3010
3011     If the HighlightAllOccurrences flag is not passed, the function will select an occurrence
3012     and all subsequent calls will replace the current occurrence with the next one.
3013
3014     To clear the selection, just pass an empty string.
3015
3016     Returns true if \a subString was found; otherwise returns false.
3017 */
3018 bool QWebPage::findText(const QString &subString, FindFlags options)
3019 {
3020     return d->findText(subString, static_cast<QWebPageAdapter::FindFlag>(options.operator int()));
3021 }
3022
3023 /*!
3024     Returns a pointer to the page's settings object.
3025
3026     \sa QWebSettings::globalSettings()
3027 */
3028 QWebSettings *QWebPage::settings() const
3029 {
3030     return d->settings;
3031 }
3032
3033 /*!
3034     This function is called when the web content requests a file name, for example
3035     as a result of the user clicking on a "file upload" button in a HTML form.
3036
3037     A suggested filename may be provided in \a suggestedFile. The frame originating the
3038     request is provided as \a parentFrame.
3039
3040     \sa ChooseMultipleFilesExtension
3041 */
3042 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile)
3043 {
3044     Q_UNUSED(parentFrame);
3045 #ifndef QT_NO_FILEDIALOG
3046     return QFileDialog::getOpenFileName(view(), QString::null, suggestedFile);
3047 #else
3048     return QString::null;
3049 #endif
3050 }
3051
3052 /*!
3053     Sets the QNetworkAccessManager \a manager responsible for serving network requests for this
3054     QWebPage.
3055
3056     \note It is currently not supported to change the network access manager after the
3057     QWebPage has used it. The results of doing this are undefined.
3058
3059     \sa networkAccessManager()
3060 */
3061 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
3062 {
3063     d->setNetworkAccessManager(manager);
3064 }
3065
3066 /*!
3067     Returns the QNetworkAccessManager that is responsible for serving network
3068     requests for this QWebPage.
3069
3070     \sa setNetworkAccessManager()
3071 */
3072 QNetworkAccessManager *QWebPage::networkAccessManager() const
3073 {
3074     return d->networkAccessManager();
3075 }
3076
3077 /*!
3078     Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this
3079     QWebPage.
3080
3081     Note: The plugin factory is only used if the QWebSettings::PluginsEnabled attribute is enabled.
3082
3083     \sa pluginFactory()
3084 */
3085 void QWebPage::setPluginFactory(QWebPluginFactory *factory)
3086 {
3087     d->pluginFactory = factory;
3088 }
3089
3090 /*!
3091     Returns the QWebPluginFactory that is responsible for creating plugins embedded into
3092     this QWebPage. If no plugin factory is installed a null pointer is returned.
3093
3094     \sa setPluginFactory()
3095 */
3096 QWebPluginFactory *QWebPage::pluginFactory() const
3097 {
3098     return d->pluginFactory;
3099 }
3100
3101 /*!
3102     This function is called when a user agent for HTTP requests is needed. You can reimplement this
3103     function to dynamically return different user agents for different URLs, based on the \a url parameter.
3104
3105     The default implementation returns the following value:
3106
3107     "Mozilla/5.0 (%Platform%%Security%%Subplatform%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%"
3108
3109     In this string the following values are replaced at run-time:
3110     \list
3111     \li %Platform% expands to the windowing system followed by "; " if it is not Windows (e.g. "X11; ").
3112     \li %Security% expands to "N; " if SSL is disabled.
3113     \li %Subplatform% expands to the operating system version (e.g. "Windows NT 6.1" or "Intel Mac OS X 10.5").
3114     \li %WebKitVersion% is the version of WebKit the application was compiled against.
3115     \li %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version.
3116     \endlist
3117 */
3118 QString QWebPage::userAgentForUrl(const QUrl&) const
3119 {
3120     return QWebPageAdapter::defaultUserAgentString();
3121 }
3122
3123
3124 /*!
3125     Returns the total number of bytes that were received from the network to render the current page,
3126     including extra content such as embedded images.
3127
3128     \sa bytesReceived()
3129 */
3130 quint64 QWebPage::totalBytes() const
3131 {
3132     return d->m_totalBytes;
3133 }
3134
3135
3136 /*!
3137     Returns the number of bytes that were received from the network to render the current page.
3138
3139     \sa totalBytes(), loadProgress()
3140 */
3141 quint64 QWebPage::bytesReceived() const
3142 {
3143     return d->m_bytesReceived;
3144 }
3145
3146
3147 /*!
3148     \property QWebPage::visibilityState
3149     \brief the page's visibility state
3150
3151     This property should be changed by Qt applications who want to notify the JavaScript application
3152     that the visibility state has changed (e.g. by reimplementing QWidget::setVisible).
3153     The visibility state will be updated with the \a state parameter value only if it's different from the previous set.
3154     Then, HTML DOM Document Object attributes 'hidden' and 'visibilityState'
3155     will be updated to the correct value and a 'visiblitychange' event will be fired.
3156     More information about this HTML5 API can be found at \l{http://www.w3.org/TR/page-visibility/}{W3C Recommendation: Page Visibility}.
3157
3158     By default, this property is set to VisibilityStateVisible.
3159 */
3160 void QWebPage::setVisibilityState(VisibilityState state)
3161 {
3162     d->setVisibilityState(static_cast<QWebPageAdapter::VisibilityState>(state));
3163 }
3164
3165 QWebPage::VisibilityState QWebPage::visibilityState() const
3166 {
3167     return static_cast<VisibilityState>(d->visibilityState());
3168 }
3169
3170
3171 /*!
3172     \since 4.8
3173     \fn void QWebPage::viewportChangeRequested()
3174
3175     Page authors can provide the supplied values by using the viewport meta tag. More information
3176     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}.
3177
3178     \sa QWebPage::ViewportAttributes, setPreferredContentsSize(), QGraphicsWebView::setScale()
3179 */
3180
3181 /*!
3182     \fn void QWebPage::loadStarted()
3183
3184     This signal is emitted when a page starts loading content.
3185
3186     \sa loadFinished()
3187 */
3188
3189 /*!
3190     \fn void QWebPage::loadProgress(int progress)
3191
3192     This signal is emitted when the global progress status changes.
3193     The current value is provided by \a progress and scales from 0 to 100,
3194     which is the default range of QProgressBar.
3195     It accumulates changes from all the child frames.
3196
3197     \sa bytesReceived()
3198 */
3199
3200 /*!
3201     \fn void QWebPage::loadFinished(bool ok)
3202
3203     This signal is emitted when the page finishes loading content. This signal
3204     is independant of script execution or page rendering.
3205     \a ok will indicate whether the load was successful or any error occurred.
3206
3207     \sa loadStarted(), ErrorPageExtension
3208 */
3209
3210 /*!
3211     \fn void QWebPage::linkHovered(const QString &link, const QString &title, const QString &textContent)
3212
3213     This signal is emitted when the mouse hovers over a link.
3214
3215     \a link contains the link url.
3216     \a title is the link element's title, if it is specified in the markup.
3217     \a textContent provides text within the link element, e.g., text inside an HTML anchor tag.
3218
3219     When the mouse leaves the link element the signal is emitted with empty parameters.
3220
3221     \sa linkClicked()
3222 */
3223
3224 /*!
3225     \fn void QWebPage::statusBarMessage(const QString& text)
3226
3227     This signal is emitted when the statusbar \a text is changed by the page.
3228 */
3229
3230 /*!
3231     \fn void QWebPage::frameCreated(QWebFrame *frame)
3232
3233     This signal is emitted whenever the page creates a new \a frame.
3234
3235     \sa currentFrame()
3236 */
3237
3238 /*!
3239     \fn void QWebPage::selectionChanged()
3240
3241     This signal is emitted whenever the selection changes, either interactively
3242     or programmatically (e.g. by calling triggerAction() with a selection action).
3243
3244     \sa selectedText()
3245 */
3246
3247 /*!
3248     \fn void QWebPage::contentsChanged()
3249     \since 4.5
3250
3251     This signal is emitted whenever the text in form elements changes
3252     as well as other editable content.
3253
3254     \sa contentEditable, modified, QWebFrame::toHtml(), QWebFrame::toPlainText()
3255 */
3256
3257 /*!
3258     \fn void QWebPage::geometryChangeRequested(const QRect& geom)
3259
3260     This signal is emitted whenever the document wants to change the position and size of the
3261     page to \a geom. This can happen for example through JavaScript.
3262 */
3263
3264 /*!
3265     \fn void QWebPage::repaintRequested(const QRect& dirtyRect)
3266
3267     This signal is emitted whenever this QWebPage should be updated. It's useful
3268     when rendering a QWebPage without a QWebView or QGraphicsWebView.
3269     \a dirtyRect contains the area that needs to be updated. To paint the QWebPage get
3270     the mainFrame() and call the render(QPainter*, const QRegion&) method with the
3271     \a dirtyRect as the second parameter.
3272
3273     \sa mainFrame()
3274     \sa view()
3275 */
3276
3277 /*!
3278     \fn void QWebPage::scrollRequested(int dx, int dy, const QRect& rectToScroll)
3279
3280     This signal is emitted whenever the content given by \a rectToScroll needs
3281     to be scrolled \a dx and \a dy downwards and no view was set.
3282
3283     \sa view()
3284 */
3285
3286 /*!
3287     \fn void QWebPage::windowCloseRequested()
3288
3289     This signal is emitted whenever the page requests the web browser window to be closed,
3290     for example through the JavaScript \c{window.close()} call.
3291 */
3292
3293 /*!
3294     \fn void QWebPage::printRequested(QWebFrame *frame)
3295
3296     This signal is emitted whenever the page requests the web browser to print \a frame,
3297     for example through the JavaScript \c{window.print()} call.
3298
3299     \sa QWebFrame::print(), QPrintPreviewDialog
3300 */
3301
3302 /*!
3303     \fn void QWebPage::unsupportedContent(QNetworkReply *reply)
3304
3305     This signal is emitted when WebKit cannot handle a link the user navigated to or a
3306     web server's response includes a "Content-Disposition" header with the 'attachment' 
3307     directive. If "Content-Disposition" is present in \a reply, the web server is indicating
3308     that the client should prompt the user to save the content regardless of content-type. 
3309     See RFC 2616 sections 19.5.1 for details about Content-Disposition.
3310
3311     At signal emission time the meta-data of the QNetworkReply \a reply is available.
3312
3313     \note The receiving slot is responsible for deleting the QNetworkReply \a reply.
3314
3315     \note This signal is only emitted if the forwardUnsupportedContent property is set to true.
3316
3317     \sa downloadRequested()
3318 */
3319
3320 /*!
3321     \fn void QWebPage::downloadRequested(const QNetworkRequest &request)
3322
3323     This signal is emitted when the user decides to download a link. The url of
3324     the link as well as additional meta-information is contained in \a request.
3325
3326     \sa unsupportedContent()
3327 */
3328
3329 /*!
3330     \fn void QWebPage::microFocusChanged()
3331
3332     This signal is emitted when for example the position of the cursor in an editable form
3333     element changes. It is used to inform input methods about the new on-screen position where
3334     the user is able to enter text. This signal is usually connected to the
3335     QWidget::updateMicroFocus() slot.
3336 */
3337
3338 /*!
3339     \fn void QWebPage::linkClicked(const QUrl &url)
3340
3341     This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy
3342     property is set to delegate the link handling for the specified \a url.
3343
3344     By default no links are delegated and are handled by QWebPage instead.
3345
3346     \note This signal possibly won't be emitted for clicked links which use
3347     JavaScript to trigger navigation.
3348
3349     \sa linkHovered()
3350 */
3351
3352 /*!
3353     \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible)
3354
3355     This signal is emitted whenever the visibility of the toolbar in a web browser
3356     window that hosts QWebPage should be changed to \a visible.
3357 */
3358
3359 /*!
3360     \fn void QWebPage::statusBarVisibilityChangeRequested(bool visible)
3361
3362     This signal is emitted whenever the visibility of the statusbar in a web browser
3363     window that hosts QWebPage should be changed to \a visible.
3364 */
3365
3366 /*!
3367     \fn void QWebPage::menuBarVisibilityChangeRequested(bool visible)
3368
3369     This signal is emitted whenever the visibility of the menubar in a web browser
3370     window that hosts QWebPage should be changed to \a visible.
3371 */
3372
3373 /*!
3374     \fn void QWebPage::databaseQuotaExceeded(QWebFrame* frame, QString databaseName);
3375     \since 4.5
3376
3377     This signal is emitted whenever the web site shown in \a frame is asking to store data
3378     to the database \a databaseName and the quota allocated to that web site is exceeded.
3379
3380     \sa QWebDatabase
3381 */
3382 /*!
3383     \fn void QWebPage::applicationCacheQuotaExceeded(QWebSecurityOrigin* origin, quint64 defaultOriginQuota, quint64 totalSpaceNeeded);
3384
3385     This signal is emitted whenever the web site is asking to store data to the application cache
3386     database databaseName and the quota allocated to that web site is exceeded.
3387
3388 */
3389
3390 /*!
3391   \since 4.5
3392   \fn void QWebPage::saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item);
3393
3394   This signal is emitted shortly before the history of navigated pages
3395   in \a frame is changed, for example when navigating back in the history.
3396
3397   The provided QWebHistoryItem, \a item, holds the history entry of the frame before
3398   the change.
3399
3400   A potential use-case for this signal is to store custom data in
3401   the QWebHistoryItem associated to the frame, using QWebHistoryItem::setUserData().
3402 */
3403
3404 /*!
3405   \since 4.5
3406   \fn void QWebPage::restoreFrameStateRequested(QWebFrame* frame);
3407
3408   This signal is emitted when the load of \a frame is finished and the application may now update its state accordingly.
3409 */
3410
3411 /*!
3412   \fn QWebPagePrivate* QWebPage::handle() const
3413   \internal
3414 */
3415
3416 #include "moc_qwebpage.cpp"