0f3f14d39e255f1052b58993211e827bd1e1a80c
[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
1489     // Catch plugin logDestroy message for LayoutTests/plugins/open-and-close-window-with-plugin.html
1490     // At this point DRT's WebPage has already been destroyed
1491     if (QWebPageAdapter::drtRun) {
1492         if (message == QLatin1String("PLUGIN: NPP_Destroy")) {
1493             fprintf(stdout, "CONSOLE MESSAGE: ");
1494             if (lineNumber)
1495                 fprintf(stdout, "line %d: ", lineNumber);
1496             fprintf(stdout, "%s\n", message.toUtf8().constData());
1497         }
1498     }
1499 }
1500
1501 /*!
1502     This function is called whenever a JavaScript program running inside \a frame calls the alert() function with
1503     the message \a msg.
1504
1505     The default implementation shows the message, \a msg, with QMessageBox::information.
1506 */
1507 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
1508 {
1509     Q_UNUSED(frame);
1510 #ifndef QT_NO_MESSAGEBOX
1511     QMessageBox box(view());
1512     box.setWindowTitle(tr("JavaScript Alert - %1").arg(mainFrame()->url().host()));
1513     box.setTextFormat(Qt::PlainText);
1514     box.setText(msg);
1515     box.setStandardButtons(QMessageBox::Ok);
1516     box.exec();
1517 #endif
1518 }
1519
1520 /*!
1521     This function is called whenever a JavaScript program running inside \a frame calls the confirm() function
1522     with the message, \a msg. Returns true if the user confirms the message; otherwise returns false.
1523
1524     The default implementation executes the query using QMessageBox::information with QMessageBox::Ok and QMessageBox::Cancel buttons.
1525 */
1526 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
1527 {
1528     Q_UNUSED(frame);
1529 #ifdef QT_NO_MESSAGEBOX
1530     return true;
1531 #else
1532     QMessageBox box(view());
1533     box.setWindowTitle(tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()));
1534     box.setTextFormat(Qt::PlainText);
1535     box.setText(msg);
1536     box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1537     return QMessageBox::Ok == box.exec();
1538 #endif
1539 }
1540
1541 /*!
1542     This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input.
1543     The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue.
1544
1545     If the prompt was cancelled by the user the implementation should return false; otherwise the
1546     result should be written to \a result and true should be returned. If the prompt was not cancelled by the
1547     user, the implementation should return true and the result string must not be null.
1548
1549     The default implementation uses QInputDialog::getText().
1550 */
1551 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
1552 {
1553     Q_UNUSED(frame);
1554     bool ok = false;
1555 #ifndef QT_NO_INPUTDIALOG
1556
1557     QInputDialog dlg(view());
1558     dlg.setWindowTitle(tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()));
1559
1560     // Hack to force the dialog's QLabel into plain text mode
1561     // prevents https://bugs.webkit.org/show_bug.cgi?id=34429
1562     QLabel* label = dlg.findChild<QLabel*>();
1563     if (label)
1564         label->setTextFormat(Qt::PlainText);
1565
1566     // double the &'s because single & will underline the following character
1567     // (Accelerator mnemonics)
1568     QString escMsg(msg);
1569     escMsg.replace(QChar::fromLatin1('&'), QLatin1String("&&"));
1570     dlg.setLabelText(escMsg);
1571
1572     dlg.setTextEchoMode(QLineEdit::Normal);
1573     dlg.setTextValue(defaultValue);
1574
1575     ok = !!dlg.exec();
1576
1577     if (ok && result)
1578         *result = dlg.textValue();
1579 #endif
1580     return ok;
1581 }
1582
1583 /*!
1584     \fn bool QWebPage::shouldInterruptJavaScript()
1585     \since 4.6
1586     This function is called when a JavaScript program is running for a long period of time.
1587
1588     If the user wanted to stop the JavaScript the implementation should return true; otherwise false.
1589
1590     The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
1591 */
1592 bool QWebPage::shouldInterruptJavaScript()
1593 {
1594 #ifdef QT_NO_MESSAGEBOX
1595     return false;
1596 #else
1597     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);
1598 #endif
1599 }
1600
1601 void QWebPage::setFeaturePermission(QWebFrame* frame, Feature feature, PermissionPolicy policy)
1602 {
1603 #if !ENABLE(NOTIFICATIONS) && !ENABLE(LEGACY_NOTIFICATIONS) && !ENABLE(GEOLOCATION)
1604     Q_UNUSED(frame);
1605     Q_UNUSED(policy);
1606 #endif
1607     switch (feature) {
1608     case Notifications:
1609 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
1610         if (policy != PermissionUnknown)
1611             d->setNotificationsAllowedForFrame(frame->d, (policy == PermissionGrantedByUser));
1612 #endif
1613         break;
1614     case Geolocation:
1615 #if ENABLE(GEOLOCATION) && HAVE(QTLOCATION)
1616         if (policy != PermissionUnknown)
1617             d->setGeolocationEnabledForFrame(frame->d, (policy == PermissionGrantedByUser));
1618 #endif
1619         break;
1620
1621     default:
1622         break;
1623     }
1624 }
1625
1626 /*!
1627     This function is called whenever WebKit wants to create a new window of the given \a type, for
1628     example when a JavaScript program requests to open a document in a new window.
1629
1630     If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned.
1631
1632     If the view associated with the web page is a QWebView object, then the default implementation forwards
1633     the request to QWebView's createWindow() function; otherwise it returns a null pointer.
1634
1635     If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window.
1636
1637     \note In the cases when the window creation is being triggered by JavaScript, apart from
1638     reimplementing this method application must also set the JavaScriptCanOpenWindows attribute
1639     of QWebSettings to true in order for it to get called.
1640
1641     \sa acceptNavigationRequest(), QWebView::createWindow()
1642 */
1643 QWebPage *QWebPage::createWindow(WebWindowType type)
1644 {
1645     QWebView *webView = qobject_cast<QWebView*>(view());
1646     if (webView) {
1647         QWebView *newView = webView->createWindow(type);
1648         if (newView)
1649             return newView->page();
1650     }
1651     return 0;
1652 }
1653
1654 /*!
1655     This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". It is
1656     called regardless of the value of QWebSettings::PluginsEnabled. The \a classid, \a url, \a paramNames and \a paramValues
1657     correspond to the HTML object element attributes and child elements to configure the embeddable object.
1658 */
1659 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
1660 {
1661     Q_UNUSED(classid);
1662     Q_UNUSED(url);
1663     Q_UNUSED(paramNames);
1664     Q_UNUSED(paramValues);
1665     return 0;
1666 }
1667
1668 /*!
1669  *  Returns the list of all content types supported by QWebPage.
1670  */
1671 QStringList QWebPage::supportedContentTypes() const
1672 {
1673     return d->supportedContentTypes();
1674 }
1675
1676 /*!
1677  *  Returns true if QWebPage can handle the given \a mimeType; otherwise, returns false.
1678  */
1679 bool QWebPage::supportsContentType(const QString& mimeType) const
1680 {
1681     return d->supportsContentType(mimeType);
1682 }
1683
1684 static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list)
1685 {
1686     list << frame->childFrames();
1687     QListIterator<QWebFrame*> it(frame->childFrames());
1688     while (it.hasNext())
1689         collectChildFrames(it.next(), list);
1690 }
1691
1692 /*!
1693     This function can be called to trigger the specified \a action.
1694     It is also called by Qt WebKit if the user triggers the action, for example
1695     through a context menu item.
1696
1697     If \a action is a checkable action then \a checked specified whether the action
1698     is toggled or not.
1699
1700     \sa action()
1701 */
1702 void QWebPage::triggerAction(WebAction action, bool)
1703 {
1704     const char *command = 0;
1705     QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
1706     QWebHitTestResultPrivate* hitTestResult = d->hitTestResult.d;
1707
1708     switch (action) {
1709     case OpenLink:
1710     case OpenLinkInNewWindow:
1711     case OpenLinkInThisWindow:
1712     case OpenFrameInNewWindow:
1713     case CopyLinkToClipboard:
1714     case OpenImageInNewWindow:
1715     case DownloadImageToDisk:
1716     case DownloadLinkToDisk:
1717     case Back:
1718     case Forward:
1719     case Stop:
1720     case Reload:
1721     case SetTextDirectionDefault:
1722     case SetTextDirectionLeftToRight:
1723     case SetTextDirectionRightToLeft:
1724         mappedAction = adapterMenuActionForWebAction(action);
1725         break;
1726     case ReloadAndBypassCache: // Manual mapping
1727         mappedAction = QWebPageAdapter::Reload;
1728         break;
1729 #ifndef QT_NO_CLIPBOARD
1730     case CopyImageToClipboard:
1731         QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap());
1732         break;
1733     case CopyImageUrlToClipboard:
1734         QApplication::clipboard()->setText(d->hitTestResult.imageUrl().toString());
1735         break;
1736 #endif
1737     case InspectElement: {
1738 #if ENABLE(INSPECTOR)
1739         if (!d->hitTestResult.isNull()) {
1740             d->getOrCreateInspector(); // Make sure the inspector is created
1741             d->inspector->show(); // The inspector is expected to be shown on inspection
1742             mappedAction = QWebPageAdapter::InspectElement;
1743         }
1744 #endif
1745         break;
1746     }
1747     case StopScheduledPageRefresh: {
1748         QWebFrame* topFrame = mainFrame();
1749         topFrame->d->cancelLoad();
1750         QList<QWebFrame*> childFrames;
1751         collectChildFrames(topFrame, childFrames);
1752         QListIterator<QWebFrame*> it(childFrames);
1753         while (it.hasNext())
1754             it.next()->d->cancelLoad();
1755         break;
1756     }
1757     default:
1758         command = QWebPagePrivate::editorCommandForWebActions(action);
1759         break;
1760     }
1761     if (command || mappedAction != QWebPageAdapter::NoAction)
1762         d->triggerAction(mappedAction, hitTestResult, command, /*endToEndReload*/ action == ReloadAndBypassCache);
1763 }
1764
1765
1766 QColor QWebPagePrivate::colorSelectionRequested(const QColor &selectedColor)
1767 {
1768     QColor ret = selectedColor;
1769 #ifndef QT_NO_COLORDIALOG
1770     ret = QColorDialog::getColor(selectedColor, q->view());
1771     if (!ret.isValid())
1772         ret = selectedColor;
1773 #endif
1774     return ret;
1775 }
1776
1777 QWebSelectMethod *QWebPagePrivate::createSelectPopup()
1778 {
1779     return new QtFallbackWebPopup(this);
1780 }
1781
1782 QRect QWebPagePrivate::viewRectRelativeToWindow()
1783 {
1784
1785     QWidget* ownerWidget= client.isNull() ? 0 : qobject_cast<QWidget*>(client->ownerWidget());
1786     if (!ownerWidget)
1787         return QRect();
1788     QWidget* topLevelWidget = ownerWidget->window();
1789
1790     QPoint topLeftCorner = ownerWidget->mapFrom(topLevelWidget, QPoint(0, 0));
1791     return QRect(topLeftCorner, ownerWidget->size());
1792 }
1793
1794 void QWebPagePrivate::geolocationPermissionRequested(QWebFrameAdapter* frame)
1795 {
1796     emit q->featurePermissionRequested(QWebFramePrivate::kit(frame), QWebPage::Geolocation);
1797 }
1798
1799 void QWebPagePrivate::geolocationPermissionRequestCancelled(QWebFrameAdapter* frame)
1800 {
1801     emit q->featurePermissionRequestCanceled(QWebFramePrivate::kit(frame), QWebPage::Geolocation);
1802 }
1803
1804 void QWebPagePrivate::notificationsPermissionRequested(QWebFrameAdapter* frame)
1805 {
1806     emit q->featurePermissionRequested(QWebFramePrivate::kit(frame), QWebPage::Notifications);
1807 }
1808
1809 void QWebPagePrivate::notificationsPermissionRequestCancelled(QWebFrameAdapter* frame)
1810 {
1811     emit q->featurePermissionRequestCanceled(QWebFramePrivate::kit(frame), QWebPage::Notifications);
1812 }
1813
1814 void QWebPagePrivate::respondToChangedContents()
1815 {
1816     updateEditorActions();
1817
1818     emit q->contentsChanged();
1819 }
1820
1821 void QWebPagePrivate::respondToChangedSelection()
1822 {
1823     updateEditorActions();
1824     emit q->selectionChanged();
1825 }
1826
1827 void QWebPagePrivate::microFocusChanged()
1828 {
1829     emit q->microFocusChanged();
1830 }
1831
1832 void QWebPagePrivate::triggerCopyAction()
1833 {
1834     q->triggerAction(QWebPage::Copy);
1835 }
1836
1837 void QWebPagePrivate::triggerActionForKeyEvent(QKeyEvent* event)
1838 {
1839     QWebPage::WebAction action = editorActionForKeyEvent(event);
1840     q->triggerAction(action);
1841 }
1842
1843 void QWebPagePrivate::clearUndoStack()
1844 {
1845 #ifndef QT_NO_UNDOSTACK
1846     if (undoStack)
1847         undoStack->clear();
1848 #endif
1849 }
1850
1851 bool QWebPagePrivate::canUndo() const
1852 {
1853 #ifndef QT_NO_UNDOSTACK
1854     if (!undoStack)
1855         return false;
1856     return undoStack->canUndo();
1857 #else
1858     return false;
1859 #endif
1860 }
1861
1862 bool QWebPagePrivate::canRedo() const
1863 {
1864 #ifndef QT_NO_UNDOSTACK
1865     if (!undoStack)
1866         return false;
1867     return undoStack->canRedo();
1868 #else
1869     return false;
1870 #endif
1871 }
1872
1873 void QWebPagePrivate::undo()
1874 {
1875 #ifndef QT_NO_UNDOSTACK
1876     if (undoStack)
1877         undoStack->undo();
1878 #endif
1879 }
1880
1881 void QWebPagePrivate::redo()
1882 {
1883 #ifndef QT_NO_UNDOSTACK
1884     if (undoStack)
1885         undoStack->redo();
1886 #endif
1887 }
1888
1889 void QWebPagePrivate::createUndoStep(QSharedPointer<UndoStepQt> step)
1890 {
1891 #ifndef QT_NO_UNDOSTACK
1892     // Call undoStack() getter first to ensure stack is created
1893     // if it doesn't exist yet.
1894     q->undoStack()->push(new QWebUndoCommand(step));
1895 #endif
1896 }
1897
1898 const char *QWebPagePrivate::editorCommandForKeyEvent(QKeyEvent* event)
1899 {
1900     QWebPage::WebAction action = editorActionForKeyEvent(event);
1901     return editorCommandForWebActions(action);
1902 }
1903
1904 QSize QWebPage::viewportSize() const
1905 {
1906     if (d->mainFrame && d->mainFrame.data()->d->hasView())
1907         return d->mainFrame.data()->d->frameRect().size();
1908
1909     return d->m_viewportSize;
1910 }
1911
1912 /*!
1913     \property QWebPage::viewportSize
1914     \brief the size of the viewport
1915
1916     The size affects for example the visibility of scrollbars
1917     if the document is larger than the viewport.
1918
1919     By default, for a newly-created Web page, this property contains a size with
1920     zero width and height.
1921
1922     \sa QWebFrame::render(), preferredContentsSize
1923 */
1924 void QWebPage::setViewportSize(const QSize &size) const
1925 {
1926     d->m_viewportSize = size;
1927
1928     QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
1929     if (!mainFrame->hasView())
1930         return;
1931
1932     mainFrame->setViewportSize(size);
1933 }
1934
1935 static int getintenv(const char* variable)
1936 {
1937     bool ok;
1938     int value = qgetenv(variable).toInt(&ok);
1939     return (ok) ? value : -1;
1940 }
1941
1942 static QSize queryDeviceSizeForScreenContainingWidget(const QWidget* widget)
1943 {
1944     QDesktopWidget* desktop = QApplication::desktop();
1945     if (!desktop)
1946         return QSize();
1947
1948     QSize size;
1949
1950     if (widget) {
1951         // Returns the available geometry of the screen which contains widget.
1952         // NOTE: this must be the the full screen size including any fixed status areas etc.
1953         size = desktop->availableGeometry(widget).size();
1954     } else
1955         size = desktop->availableGeometry().size();
1956
1957     // This must be in portrait mode, adjust if not.
1958     if (size.width() > size.height()) {
1959         int width = size.width();
1960         size.setWidth(size.height());
1961         size.setHeight(width);
1962     }
1963
1964     return size;
1965 }
1966
1967 /*!
1968     Computes the optimal viewport configuration given the \a availableSize, when
1969     user interface components are disregarded.
1970
1971     The configuration is also dependent on the device screen size which is obtained
1972     automatically. For testing purposes the size can be overridden by setting two
1973     environment variables QTWEBKIT_DEVICE_WIDTH and QTWEBKIT_DEVICE_HEIGHT, which
1974     both needs to be set.
1975
1976     The ViewportAttributes includes a pixel density ratio, which will also be exposed to
1977     the web author though the -webkit-pixel-ratio media feature. This is the ratio
1978     between 1 density-independent pixel (DPI) and physical pixels.
1979
1980     A density-independent pixel is equivalent to one physical pixel on a 160 DPI screen,
1981     so on our platform assumes that as the baseline density.
1982
1983     The conversion of DIP units to screen pixels is quite simple:
1984
1985     pixels = DIPs * (density / 160).
1986
1987     Thus, on a 240 DPI screen, 1 DIPs would equal 1.5 physical pixels.
1988
1989     An invalid instance will be returned in the case an empty size is passed to the
1990     method.
1991
1992     \note The density is automatically obtained from the DPI of the screen where the page
1993     is being shown, but as many X11 servers are reporting wrong DPI, it is possible to
1994     override it using QX11Info::setAppDpiY().
1995 */
1996
1997 QWebPage::ViewportAttributes QWebPage::viewportAttributesForSize(const QSize& availableSize) const
1998 {
1999     ViewportAttributes result;
2000
2001     if (availableSize.isEmpty())
2002         return result; // Returns an invalid instance.
2003
2004     QSize deviceSize(getintenv("QTWEBKIT_DEVICE_WIDTH"), getintenv("QTWEBKIT_DEVICE_HEIGHT"));
2005
2006     // Both environment variables need to be set - or they will be ignored.
2007     if (deviceSize.isNull())
2008         deviceSize = queryDeviceSizeForScreenContainingWidget(view());
2009     QWebPageAdapter::ViewportAttributes attr = d->viewportAttributesForSize(availableSize, deviceSize);
2010
2011     result.m_isValid = true;
2012     result.m_size = attr.size;
2013     result.m_initialScaleFactor = attr.initialScaleFactor;
2014     result.m_minimumScaleFactor = attr.minimumScaleFactor;
2015     result.m_maximumScaleFactor = attr.maximumScaleFactor;
2016     result.m_devicePixelRatio = attr.devicePixelRatio;
2017     result.m_isUserScalable = attr.isUserScalable;
2018
2019     return result;
2020 }
2021
2022 QSize QWebPage::preferredContentsSize() const
2023 {
2024     QWebFrameAdapter* mainFrame = d->mainFrame ? d->mainFrame->d : 0;
2025     QSize customSize;
2026     if (mainFrame && mainFrame->hasView())
2027         customSize = mainFrame->customLayoutSize();
2028
2029     return customSize.isNull() ? d->fixedLayoutSize : customSize;
2030 }
2031
2032 /*!
2033     \property QWebPage::preferredContentsSize
2034     \since 4.6
2035     \brief a custom size used for laying out the page contents.
2036
2037     By default all pages are laid out using the viewport of the page as the base.
2038
2039     As pages mostly are designed for desktop usage, they often do not layout properly
2040     on small devices as the contents require a certain view width. For this reason
2041     it is common to use a different layout size and then scale the contents to fit
2042     within the actual view.
2043
2044     If this property is set to a valid size, this size is used for all layout needs
2045     instead of the size of the viewport.
2046
2047     Setting an invalid size, makes the page fall back to using the viewport size for layout.
2048
2049     \sa viewportSize
2050 */
2051 void QWebPage::setPreferredContentsSize(const QSize& size) const
2052 {
2053     // FIXME: Rename this method to setCustomLayoutSize
2054
2055     d->fixedLayoutSize = size;
2056
2057     QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
2058     if (!mainFrame->hasView())
2059         return;
2060
2061     mainFrame->setCustomLayoutSize(size);
2062 }
2063
2064 /*
2065     This function is to be called after any (animated) scroll/pan has ended, in the case the application handles the
2066     scrolling/panning of the web contents. This is commonly used in combination with tiling where is it common for
2067     the application to pan the actual view, which then resizes itself to the size of the contents.
2068
2069     \note Calling this function makes WebKit stop trying to calculate the visibleContentRect. To turn that on
2070     again, call this method with an empty rect.
2071
2072     \sa QGraphicsWebView::resizesToContents, QWebSettings::TiledBackingStoreEnabled
2073 */
2074 void QWebPage::setActualVisibleContentRect(const QRect& rect) const
2075 {
2076     QWebFrameAdapter* mainFrame = d->mainFrameAdapter();
2077     if (!mainFrame->hasView())
2078         return;
2079
2080     mainFrame->setFixedVisibleContentRect(rect);
2081 }
2082
2083 /*!
2084     \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
2085
2086     This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of
2087     the specified navigation type \a type.
2088
2089     If \a frame is a null pointer then navigation to a new window is requested. If the request is
2090     accepted createWindow() will be called.
2091
2092     The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true
2093     to let QWebPage handle the navigation itself.
2094
2095     \sa createWindow()
2096 */
2097 bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
2098 {
2099     Q_UNUSED(frame);
2100     if (type == NavigationTypeLinkClicked) {
2101         switch (d->linkPolicy) {
2102         case DontDelegateLinks:
2103             return true;
2104
2105         case DelegateExternalLinks:
2106             if (QWebPageAdapter::treatSchemeAsLocal(request.url().scheme()))
2107                 return true;
2108             emit linkClicked(request.url());
2109             return false;
2110
2111         case DelegateAllLinks:
2112             emit linkClicked(request.url());
2113             return false;
2114         }
2115     }
2116     return true;
2117 }
2118
2119 /*!
2120     \property QWebPage::hasSelection
2121     \brief whether this page contains selected content or not.
2122
2123     \sa selectionChanged()
2124 */
2125 bool QWebPage::hasSelection() const
2126 {
2127     d->createMainFrame();
2128     return d->hasSelection();
2129 }
2130
2131 /*!
2132     \property QWebPage::selectedText
2133     \brief the text currently selected
2134
2135     By default, this property contains an empty string.
2136
2137     \sa selectionChanged(), selectedHtml()
2138 */
2139 QString QWebPage::selectedText() const
2140 {
2141     d->createMainFrame();
2142     return d->selectedText();
2143 }
2144
2145 /*!
2146     \since 4.8
2147     \property QWebPage::selectedHtml
2148     \brief the HTML currently selected
2149
2150     By default, this property contains an empty string.
2151
2152     \sa selectionChanged(), selectedText()
2153 */
2154 QString QWebPage::selectedHtml() const
2155 {
2156     d->createMainFrame();
2157     return d->selectedHtml();
2158 }
2159
2160 #ifndef QT_NO_ACTION
2161 /*!
2162    Returns a QAction for the specified WebAction \a action.
2163
2164    The action is owned by the QWebPage but you can customize the look by
2165    changing its properties.
2166
2167    QWebPage also takes care of implementing the action, so that upon
2168    triggering the corresponding action is performed on the page.
2169
2170    \sa triggerAction()
2171 */
2172 QAction *QWebPage::action(WebAction action) const
2173 {
2174     if (action == QWebPage::NoWebAction)
2175         return 0;
2176     if (d->actions[action])
2177         return d->actions[action];
2178
2179     QString text;
2180     QIcon icon;
2181     QStyle *style = d->client ? d->client->style() : qApp->style();
2182     bool checkable = false;
2183     QWebPageAdapter::MenuAction mappedAction = QWebPageAdapter::NoAction;
2184
2185     switch (action) {
2186     // to be fetched from LocalizedStringsQt via the page adapter
2187     case OpenLink:
2188     case OpenLinkInNewWindow:
2189     case OpenFrameInNewWindow:
2190     case OpenLinkInThisWindow:
2191     case DownloadLinkToDisk:
2192     case CopyLinkToClipboard:
2193     case OpenImageInNewWindow:
2194     case DownloadImageToDisk:
2195     case CopyImageToClipboard:
2196     case CopyImageUrlToClipboard:
2197     case Cut:
2198     case Copy:
2199     case Paste:
2200     case SelectAll:
2201     case SetTextDirectionDefault:
2202     case SetTextDirectionLeftToRight:
2203     case SetTextDirectionRightToLeft:
2204     case ToggleBold:
2205     case ToggleItalic:
2206     case ToggleUnderline:
2207         mappedAction = adapterMenuActionForWebAction(action);
2208         break;
2209     case InspectElement:
2210 #if ENABLE(INSPECTOR)
2211         mappedAction = QWebPageAdapter::InspectElement;
2212 #endif
2213         break;
2214
2215         // icon needed as well, map by hand.
2216     case Back:
2217         mappedAction = QWebPageAdapter::Back;
2218         icon = style->standardIcon(QStyle::SP_ArrowBack);
2219         break;
2220     case Forward:
2221         mappedAction = QWebPageAdapter::Forward;
2222         icon = style->standardIcon(QStyle::SP_ArrowForward);
2223         break;
2224     case Stop:
2225         mappedAction = QWebPageAdapter::Stop;
2226         icon = style->standardIcon(QStyle::SP_BrowserStop);
2227         break;
2228     case Reload:
2229         mappedAction = QWebPageAdapter::Reload;
2230         icon = style->standardIcon(QStyle::SP_BrowserReload);
2231         break;
2232
2233 #ifndef QT_NO_UNDOSTACK
2234     case Undo: {
2235         QAction *a = undoStack()->createUndoAction(d->q);
2236         d->actions[action] = a;
2237         return a;
2238     }
2239     case Redo: {
2240         QAction *a = undoStack()->createRedoAction(d->q);
2241         d->actions[action] = a;
2242         return a;
2243     }
2244 #endif // QT_NO_UNDOSTACK
2245         // in place l10n
2246         case MoveToNextChar:
2247             text = tr("Move the cursor to the next character");
2248             break;
2249         case MoveToPreviousChar:
2250             text = tr("Move the cursor to the previous character");
2251             break;
2252         case MoveToNextWord:
2253             text = tr("Move the cursor to the next word");
2254             break;
2255         case MoveToPreviousWord:
2256             text = tr("Move the cursor to the previous word");
2257             break;
2258         case MoveToNextLine:
2259             text = tr("Move the cursor to the next line");
2260             break;
2261         case MoveToPreviousLine:
2262             text = tr("Move the cursor to the previous line");
2263             break;
2264         case MoveToStartOfLine:
2265             text = tr("Move the cursor to the start of the line");
2266             break;
2267         case MoveToEndOfLine:
2268             text = tr("Move the cursor to the end of the line");
2269             break;
2270         case MoveToStartOfBlock:
2271             text = tr("Move the cursor to the start of the block");
2272             break;
2273         case MoveToEndOfBlock:
2274             text = tr("Move the cursor to the end of the block");
2275             break;
2276         case MoveToStartOfDocument:
2277             text = tr("Move the cursor to the start of the document");
2278             break;
2279         case MoveToEndOfDocument:
2280             text = tr("Move the cursor to the end of the document");
2281             break;
2282         case SelectNextChar:
2283             text = tr("Select to the next character");
2284             break;
2285         case SelectPreviousChar:
2286             text = tr("Select to the previous character");
2287             break;
2288         case SelectNextWord:
2289             text = tr("Select to the next word");
2290             break;
2291         case SelectPreviousWord:
2292             text = tr("Select to the previous word");
2293             break;
2294         case SelectNextLine:
2295             text = tr("Select to the next line");
2296             break;
2297         case SelectPreviousLine:
2298             text = tr("Select to the previous line");
2299             break;
2300         case SelectStartOfLine:
2301             text = tr("Select to the start of the line");
2302             break;
2303         case SelectEndOfLine:
2304             text = tr("Select to the end of the line");
2305             break;
2306         case SelectStartOfBlock:
2307             text = tr("Select to the start of the block");
2308             break;
2309         case SelectEndOfBlock:
2310             text = tr("Select to the end of the block");
2311             break;
2312         case SelectStartOfDocument:
2313             text = tr("Select to the start of the document");
2314             break;
2315         case SelectEndOfDocument:
2316             text = tr("Select to the end of the document");
2317             break;
2318         case DeleteStartOfWord:
2319             text = tr("Delete to the start of the word");
2320             break;
2321         case DeleteEndOfWord:
2322             text = tr("Delete to the end of the word");
2323             break;
2324
2325         case InsertParagraphSeparator:
2326             text = tr("Insert a new paragraph");
2327             break;
2328         case InsertLineSeparator:
2329             text = tr("Insert a new line");
2330             break;
2331
2332         case PasteAndMatchStyle:
2333             text = tr("Paste and Match Style");
2334             break;
2335         case RemoveFormat:
2336             text = tr("Remove formatting");
2337             break;
2338
2339         case ToggleStrikethrough:
2340             text = tr("Strikethrough");
2341             checkable = true;
2342             break;
2343         case ToggleSubscript:
2344             text = tr("Subscript");
2345             checkable = true;
2346             break;
2347         case ToggleSuperscript:
2348             text = tr("Superscript");
2349             checkable = true;
2350             break;
2351         case InsertUnorderedList:
2352             text = tr("Insert Bulleted List");
2353             checkable = true;
2354             break;
2355         case InsertOrderedList:
2356             text = tr("Insert Numbered List");
2357             checkable = true;
2358             break;
2359         case Indent:
2360             text = tr("Indent");
2361             break;
2362         case Outdent:
2363             text = tr("Outdent");
2364             break;
2365         case AlignCenter:
2366             text = tr("Center");
2367             break;
2368         case AlignJustified:
2369             text = tr("Justify");
2370             break;
2371         case AlignLeft:
2372             text = tr("Align Left");
2373             break;
2374         case AlignRight:
2375             text = tr("Align Right");
2376             break;
2377         case NoWebAction:
2378             return 0;
2379         default:
2380             break;
2381     }
2382     if (mappedAction != QWebPageAdapter::NoAction)
2383         text = d->contextMenuItemTagForAction(mappedAction, &checkable);
2384
2385     if (text.isEmpty())
2386         return 0;
2387
2388     QAction *a = new QAction(d->q);
2389     a->setText(text);
2390     a->setData(action);
2391     a->setCheckable(checkable);
2392     a->setIcon(icon);
2393
2394     connect(a, SIGNAL(triggered(bool)),
2395         this, SLOT(_q_webActionTriggered(bool)));
2396
2397     d->actions[action] = a;
2398     d->updateAction(action);
2399     return a;
2400 }
2401 #endif // QT_NO_ACTION
2402
2403 /*!
2404     \property QWebPage::modified
2405     \brief whether the page contains unsubmitted form data, or the contents have been changed.
2406
2407     By default, this property is false.
2408
2409     \sa contentsChanged(), contentEditable, undoStack()
2410 */
2411 bool QWebPage::isModified() const
2412 {
2413 #ifdef QT_NO_UNDOSTACK
2414     return false;
2415 #else
2416     if (!d->undoStack)
2417         return false;
2418     return d->undoStack->canUndo();
2419 #endif // QT_NO_UNDOSTACK
2420 }
2421
2422 #ifndef QT_NO_UNDOSTACK
2423 /*!
2424     Returns a pointer to the undo stack used for editable content.
2425
2426     \sa modified
2427 */
2428 QUndoStack *QWebPage::undoStack() const
2429 {
2430     if (!d->undoStack)
2431         d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
2432
2433     return d->undoStack;
2434 }
2435 #endif // QT_NO_UNDOSTACK
2436
2437 /*! \reimp
2438 */
2439 bool QWebPage::event(QEvent *ev)
2440 {
2441     switch (ev->type()) {
2442     case QEvent::Timer:
2443         d->timerEvent(static_cast<QTimerEvent*>(ev));
2444         break;
2445     case QEvent::MouseMove:
2446         d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
2447         break;
2448     case QEvent::MouseButtonPress:
2449         d->mousePressEvent(static_cast<QMouseEvent*>(ev));
2450         break;
2451     case QEvent::MouseButtonDblClick:
2452         d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
2453         break;
2454     case QEvent::MouseButtonRelease:
2455         d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
2456         break;
2457 #if !defined(QT_NO_GRAPHICSVIEW)
2458     case QEvent::GraphicsSceneMouseMove: {
2459         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2460         QMouseEvent dummyEvent(QEvent::MouseMove, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2461         d->mouseMoveEvent(&dummyEvent);
2462         ev->setAccepted(dummyEvent.isAccepted());
2463         break;
2464     }
2465     case QEvent::GraphicsSceneMouseRelease: {
2466         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2467         QMouseEvent dummyEvent(QEvent::MouseButtonRelease, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2468         d->adjustPointForClicking(&dummyEvent);
2469         d->mouseReleaseEvent(&dummyEvent);
2470         ev->setAccepted(dummyEvent.isAccepted());
2471         break;
2472     }
2473     case QEvent::GraphicsSceneMousePress: {
2474         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2475         QMouseEvent dummyEvent(QEvent::MouseButtonPress, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2476         d->adjustPointForClicking(&dummyEvent);
2477         d->mousePressEvent(&dummyEvent);
2478         ev->setAccepted(dummyEvent.isAccepted());
2479         break;
2480     }
2481     case QEvent::GraphicsSceneMouseDoubleClick: {
2482         QGraphicsSceneMouseEvent *gsEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
2483         QMouseEvent dummyEvent(QEvent::MouseButtonDblClick, gsEv->pos(), gsEv->screenPos(), gsEv->button(), gsEv->buttons(), gsEv->modifiers());
2484         d->adjustPointForClicking(&dummyEvent);
2485         d->mouseDoubleClickEvent(&dummyEvent);
2486         ev->setAccepted(dummyEvent.isAccepted());
2487         break;
2488     }
2489 #endif
2490 #ifndef QT_NO_CONTEXTMENU
2491     case QEvent::ContextMenu:
2492         d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos());
2493         break;
2494 #if !defined(QT_NO_GRAPHICSVIEW)
2495     case QEvent::GraphicsSceneContextMenu:
2496         d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos());
2497         break;
2498 #endif
2499 #endif
2500 #ifndef QT_NO_WHEELEVENT
2501     case QEvent::Wheel:
2502         d->wheelEvent(static_cast<QWheelEvent*>(ev), QApplication::wheelScrollLines());
2503         break;
2504 #if !defined(QT_NO_GRAPHICSVIEW)
2505     case QEvent::GraphicsSceneWheel: {
2506         QGraphicsSceneWheelEvent *gsEv = static_cast<QGraphicsSceneWheelEvent*>(ev);
2507         QWheelEvent dummyEvent(gsEv->pos(), gsEv->screenPos(), gsEv->delta(), gsEv->buttons(), gsEv->modifiers(), gsEv->orientation());
2508         d->wheelEvent(&dummyEvent, QApplication::wheelScrollLines());
2509         ev->setAccepted(dummyEvent.isAccepted());
2510         break;
2511     }
2512 #endif
2513 #endif
2514     case QEvent::KeyPress:
2515         d->keyPressEvent(static_cast<QKeyEvent*>(ev));
2516         break;
2517     case QEvent::KeyRelease:
2518         d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
2519         break;
2520     case QEvent::FocusIn:
2521         d->focusInEvent(static_cast<QFocusEvent*>(ev));
2522         break;
2523     case QEvent::FocusOut:
2524         d->focusOutEvent(static_cast<QFocusEvent*>(ev));
2525         break;
2526 #ifndef QT_NO_DRAGANDDROP
2527     case QEvent::DragEnter:
2528         d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
2529         break;
2530     case QEvent::DragLeave:
2531         d->dragLeaveEvent();
2532         ev->accept();
2533         break;
2534     case QEvent::DragMove:
2535         d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
2536         break;
2537     case QEvent::Drop:
2538         d->dropEvent(static_cast<QDropEvent*>(ev));
2539         break;
2540 #if !defined(QT_NO_GRAPHICSVIEW)
2541     case QEvent::GraphicsSceneDragEnter:
2542         d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2543         break;
2544     case QEvent::GraphicsSceneDragMove:
2545         d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2546         break;
2547     case QEvent::GraphicsSceneDragLeave:
2548         d->dragLeaveEvent();
2549         ev->accept();
2550         break;
2551     case QEvent::GraphicsSceneDrop:
2552         d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2553         break;
2554 #endif
2555
2556 #endif
2557     case QEvent::InputMethod:
2558         d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev));
2559         break;
2560     case QEvent::ShortcutOverride:
2561         d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev));
2562         break;
2563     case QEvent::Leave:
2564         d->leaveEvent(ev);
2565         break;
2566     case QEvent::TouchBegin:
2567     case QEvent::TouchUpdate:
2568     case QEvent::TouchEnd:
2569     case QEvent::TouchCancel:
2570         // Return whether the default action was cancelled in the JS event handler
2571         return d->touchEvent(static_cast<QTouchEvent*>(ev));
2572 #ifndef QT_NO_GESTURES
2573     case QEvent::Gesture:
2574         d->gestureEvent(static_cast<QGestureEvent*>(ev));
2575         break;
2576 #endif
2577 #ifndef QT_NO_PROPERTIES
2578     case QEvent::DynamicPropertyChange:
2579         d->dynamicPropertyChangeEvent(this, static_cast<QDynamicPropertyChangeEvent*>(ev));
2580         break;
2581 #endif
2582     default:
2583         return QObject::event(ev);
2584     }
2585
2586     return true;
2587 }
2588
2589 /*!
2590     Similar to QWidget::focusNextPrevChild() it focuses the next focusable web element
2591     if \a next is true; otherwise the previous element is focused.
2592
2593     Returns true if it can find a new focusable element, or false if it can't.
2594 */
2595 bool QWebPage::focusNextPrevChild(bool next)
2596 {
2597     QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
2598     d->keyPressEvent(&ev);
2599     return d->hasFocusedNode();
2600 }
2601
2602 /*!
2603     \property QWebPage::contentEditable
2604     \brief whether the content in this QWebPage is editable or not
2605     \since 4.5
2606
2607     If this property is enabled the contents of the page can be edited by the user through a visible
2608     cursor. If disabled (the default) only HTML elements in the web page with their
2609     \c{contenteditable} attribute set are editable.
2610
2611     \sa modified, contentsChanged(), WebAction
2612 */
2613 void QWebPage::setContentEditable(bool editable)
2614 {
2615     if (isContentEditable() != editable) {
2616         d->setContentEditable(editable);
2617         d->updateEditorActions();
2618     }
2619 }
2620
2621 bool QWebPage::isContentEditable() const
2622 {
2623     return d->isContentEditable();
2624 }
2625
2626 /*!
2627     \property QWebPage::forwardUnsupportedContent
2628     \brief whether QWebPage should forward unsupported content
2629
2630     If enabled, the unsupportedContent() signal is emitted with a network reply that
2631     can be used to read the content.
2632
2633     If disabled, the download of such content is aborted immediately.
2634
2635     By default unsupported content is not forwarded.
2636 */
2637
2638 void QWebPage::setForwardUnsupportedContent(bool forward)
2639 {
2640     d->forwardUnsupportedContent = forward;
2641 }
2642
2643 bool QWebPage::forwardUnsupportedContent() const
2644 {
2645     return d->forwardUnsupportedContent;
2646 }
2647
2648 /*!
2649     \property QWebPage::linkDelegationPolicy
2650     \brief how QWebPage should delegate the handling of links through the
2651     linkClicked() signal
2652
2653     The default is to delegate no links.
2654 */
2655
2656 void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy)
2657 {
2658     d->linkPolicy = policy;
2659 }
2660
2661 QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const
2662 {
2663     return d->linkPolicy;
2664 }
2665
2666 #ifndef QT_NO_CONTEXTMENU
2667
2668 bool QWebPagePrivate::handleScrollbarContextMenuEvent(QContextMenuEvent* event, bool horizontal, QWebPageAdapter::ScrollDirection* direction, QWebPageAdapter::ScrollGranularity* granularity)
2669 {
2670     if (!QApplication::style()->styleHint(QStyle::SH_ScrollBar_ContextMenu))
2671         return false;
2672
2673     QMenu menu;
2674     QAction* actScrollHere = menu.addAction(QCoreApplication::translate("QWebPage", "Scroll here"));
2675     menu.addSeparator();
2676
2677     QAction* actScrollTop = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Left edge") : QCoreApplication::translate("QWebPage", "Top"));
2678     QAction* actScrollBottom = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Right edge") : QCoreApplication::translate("QWebPage", "Bottom"));
2679     menu.addSeparator();
2680
2681     QAction* actPageUp = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Page left") : QCoreApplication::translate("QWebPage", "Page up"));
2682     QAction* actPageDown = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Page right") : QCoreApplication::translate("QWebPage", "Page down"));
2683     menu.addSeparator();
2684
2685     QAction* actScrollUp = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Scroll left") : QCoreApplication::translate("QWebPage", "Scroll up"));
2686     QAction* actScrollDown = menu.addAction(horizontal ? QCoreApplication::translate("QWebPage", "Scroll right") : QCoreApplication::translate("QWebPage", "Scroll down"));
2687
2688     QAction* actionSelected = menu.exec(event->globalPos());
2689
2690     if (actionSelected == actScrollHere)
2691         return true;
2692     if (actionSelected == actScrollTop) {
2693         *direction = horizontal ? ScrollLeft : ScrollUp;
2694         *granularity = ScrollByDocument;
2695     } else if (actionSelected == actScrollBottom) {
2696         *direction =horizontal ? ScrollRight : ScrollDown;
2697         *granularity = ScrollByDocument;
2698     } else if (actionSelected == actPageUp) {
2699         *direction = horizontal ? ScrollLeft : ScrollUp;
2700         *granularity = ScrollByPage;
2701     } else if (actionSelected == actPageDown) {
2702         *direction =horizontal ? ScrollRight : ScrollDown;
2703         *granularity = ScrollByPage;
2704     } else if (actionSelected == actScrollUp) {
2705         *direction = horizontal ? ScrollLeft : ScrollUp;
2706         *granularity = ScrollByLine;
2707     } else if (actionSelected == actScrollDown) {
2708         *direction =horizontal ? ScrollRight : ScrollDown;
2709         *granularity = ScrollByLine;
2710     }
2711     return true;
2712 }
2713
2714 /*!
2715     Filters the context menu event, \a event, through handlers for scrollbars and
2716     custom event handlers in the web page. Returns true if the event was handled;
2717     otherwise false.
2718
2719     A web page may swallow a context menu event through a custom event handler, allowing for context
2720     menus to be implemented in HTML/JavaScript. This is used by \l{http://maps.google.com/}{Google
2721     Maps}, for example.
2722 */
2723 bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event)
2724 {
2725     QWebFrame* webFrame = frameAt(event->pos());
2726     return d->swallowContextMenuEvent(event, webFrame ? webFrame->d : 0);
2727 }
2728 #endif // QT_NO_CONTEXTMENU
2729
2730 /*!
2731     Updates the page's actions depending on the position \a pos. For example if \a pos is over an image
2732     element the CopyImageToClipboard action is enabled.
2733 */
2734 void QWebPage::updatePositionDependentActions(const QPoint &pos)
2735 {
2736 #ifndef QT_NO_ACTION
2737     // First we disable all actions, but keep track of which ones were originally enabled.
2738     QBitArray originallyEnabledWebActions(QWebPage::WebActionCount);
2739     for (int i = QWebPageAdapter::NoAction + 1; i < QWebPageAdapter::ActionCount; ++i) {
2740         QWebPage::WebAction action = webActionForAdapterMenuAction(QWebPageAdapter::MenuAction(i));
2741         if (QAction *a = this->action(action)) {
2742             originallyEnabledWebActions.setBit(action, a->isEnabled());
2743             a->setEnabled(false);
2744         }
2745     }
2746 #endif // QT_NO_ACTION
2747
2748     QBitArray visitedWebActions(QWebPage::WebActionCount);
2749     d->createMainFrame();
2750     // Then we let updatePositionDependantMenuActions() enable the actions that are put into the menu
2751     QWebHitTestResultPrivate* result = d->updatePositionDependentMenuActions(pos, &visitedWebActions);
2752     if (!result)
2753         d->hitTestResult = QWebHitTestResult();
2754     else
2755         d->hitTestResult = QWebHitTestResult(result);
2756
2757 #ifndef QT_NO_ACTION
2758     // Finally, we restore the original enablement for the actions that were not put into the menu.
2759     originallyEnabledWebActions &= ~visitedWebActions; // Mask out visited actions (they're part of the menu)
2760     for (int i = 0; i < QWebPage::WebActionCount; ++i) {
2761         if (originallyEnabledWebActions.at(i)) {
2762             if (QAction *a = this->action(QWebPage::WebAction(i)))
2763                 a->setEnabled(true);
2764         }
2765     }
2766 #endif // QT_NO_ACTION
2767
2768     // This whole process ensures that any actions put into to the context menu has the right
2769     // enablement, while also keeping the correct enablement for actions that were left out of
2770     // the menu.
2771
2772 }
2773
2774
2775
2776 /*!
2777     \enum QWebPage::Extension
2778
2779     This enum describes the types of extensions that the page can support. Before using these extensions, you
2780     should verify that the extension is supported by calling supportsExtension().
2781
2782     \value ChooseMultipleFilesExtension Whether the web page supports multiple file selection.
2783     This extension is invoked when the web content requests one or more file names, for example
2784     as a result of the user clicking on a "file upload" button in a HTML form where multiple
2785     file selection is allowed.
2786
2787     \value ErrorPageExtension Whether the web page can provide an error page when loading fails.
2788     (introduced in Qt 4.6)
2789
2790     \sa ChooseMultipleFilesExtensionOption, ChooseMultipleFilesExtensionReturn, ErrorPageExtensionOption, ErrorPageExtensionReturn
2791 */
2792
2793 /*!
2794     \enum QWebPage::ErrorDomain
2795     \since 4.6
2796
2797     This enum describes the domain of an ErrorPageExtensionOption object (i.e. the layer in which the error occurred).
2798
2799     \value QtNetwork The error occurred in the QtNetwork layer; the error code is of type QNetworkReply::NetworkError.
2800     \value Http The error occurred in the HTTP layer; the error code is a HTTP status code (see QNetworkRequest::HttpStatusCodeAttribute).
2801     \value WebKit The error is an internal WebKit error.
2802 */
2803
2804 /*!
2805     \class QWebPage::ExtensionOption
2806     \since 4.4
2807     \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support.
2808
2809     \inmodule QtWebKit
2810
2811     \sa QWebPage::extension(), QWebPage::ExtensionReturn
2812 */
2813
2814
2815 /*!
2816     \class QWebPage::ExtensionReturn
2817     \since 4.4
2818     \brief The ExtensionReturn class provides an output result from a QWebPage's extension.
2819
2820     \inmodule QtWebKit
2821
2822     \sa QWebPage::extension(), QWebPage::ExtensionOption
2823 */
2824
2825 /*!
2826     \class QWebPage::ErrorPageExtensionOption
2827     \since 4.6
2828     \brief The ErrorPageExtensionOption class describes the option
2829     for the error page extension.
2830
2831     \inmodule QtWebKit
2832
2833     The ErrorPageExtensionOption class holds the \a url for which an error occurred as well as
2834     the associated \a frame.
2835
2836     The error itself is reported by an error \a domain, the \a error code as well as \a errorString.
2837
2838     \sa QWebPage::extension(), QWebPage::ErrorPageExtensionReturn
2839 */
2840
2841 /*!
2842     \variable QWebPage::ErrorPageExtensionOption::url
2843     \brief the url for which an error occurred
2844 */
2845
2846 /*!
2847     \variable QWebPage::ErrorPageExtensionOption::frame
2848     \brief the frame associated with the error
2849 */
2850
2851 /*!
2852     \variable QWebPage::ErrorPageExtensionOption::domain
2853     \brief the domain that reported the error
2854 */
2855
2856 /*!
2857     \variable QWebPage::ErrorPageExtensionOption::error
2858     \brief the error code. Interpretation of the value depends on the \a domain
2859     \sa QWebPage::ErrorDomain
2860 */
2861
2862 /*!
2863     \variable QWebPage::ErrorPageExtensionOption::errorString
2864     \brief a string that describes the error
2865 */
2866
2867 /*!
2868     \class QWebPage::ErrorPageExtensionReturn
2869     \since 4.6
2870     \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the
2871     frame for which the error occured.
2872
2873     \inmodule QtWebKit
2874
2875     The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are
2876     optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which
2877     is assumed to be UTF-8 if not indicated otherwise.
2878
2879     The error page is stored in the \a content byte array, as HTML content. In order to convert a
2880     QString to a byte array, the QString::toUtf8() method can be used.
2881
2882     External objects such as stylesheets or images referenced in the HTML are located relative to
2883     \a baseUrl.
2884
2885     \sa QWebPage::extension(), QWebPage::ErrorPageExtensionOption, QString::toUtf8()
2886 */
2887
2888 /*!
2889     \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn()
2890
2891     Constructs a new error page object.
2892 */
2893
2894
2895 /*!
2896     \variable QWebPage::ErrorPageExtensionReturn::contentType
2897     \brief the error page's content type
2898 */
2899
2900 /*!
2901     \variable QWebPage::ErrorPageExtensionReturn::encoding
2902     \brief the error page encoding
2903 */
2904
2905 /*!
2906     \variable QWebPage::ErrorPageExtensionReturn::baseUrl
2907     \brief the base url
2908
2909     External objects such as stylesheets or images referenced in the HTML are located relative to this url.
2910 */
2911
2912 /*!
2913     \variable QWebPage::ErrorPageExtensionReturn::content
2914     \brief the HTML content of the error page
2915 */
2916
2917 /*!
2918     \class QWebPage::ChooseMultipleFilesExtensionOption
2919     \since 4.5
2920     \brief The ChooseMultipleFilesExtensionOption class describes the option
2921     for the multiple files selection extension.
2922
2923     \inmodule QtWebKit
2924
2925     The ChooseMultipleFilesExtensionOption class holds the frame originating the request
2926     and the suggested filenames which might be provided.
2927
2928     \sa QWebPage::extension(), QWebPage::chooseFile(), QWebPage::ChooseMultipleFilesExtensionReturn
2929 */
2930
2931 /*!
2932     \variable QWebPage::ChooseMultipleFilesExtensionOption::parentFrame
2933     \brief The frame in which the request originated
2934 */
2935
2936 /*!
2937     \variable QWebPage::ChooseMultipleFilesExtensionOption::suggestedFileNames
2938     \brief The suggested filenames
2939 */
2940
2941 /*!
2942     \variable QWebPage::ChooseMultipleFilesExtensionReturn::fileNames
2943     \brief The selected filenames
2944 */
2945
2946 /*!
2947     \class QWebPage::ChooseMultipleFilesExtensionReturn
2948     \since 4.5
2949     \brief The ChooseMultipleFilesExtensionReturn describes the return value
2950     for the multiple files selection extension.
2951
2952     \inmodule QtWebKit
2953
2954     The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user
2955     when the extension is invoked.
2956
2957     \sa QWebPage::extension(), QWebPage::ChooseMultipleFilesExtensionOption
2958 */
2959
2960 /*!
2961     This virtual function can be reimplemented in a QWebPage subclass to provide support for extensions. The \a option
2962     argument is provided as input to the extension; the output results can be stored in \a output.
2963
2964     The behavior of this function is determined by \a extension. The \a option
2965     and \a output values are typically casted to the corresponding types (for
2966     example, ChooseMultipleFilesExtensionOption and
2967     ChooseMultipleFilesExtensionReturn for ChooseMultipleFilesExtension).
2968
2969     You can call supportsExtension() to check if an extension is supported by the page.
2970
2971     Returns true if the extension was called successfully; otherwise returns false.
2972
2973     \sa supportsExtension(), Extension
2974 */
2975 bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
2976 {
2977 #ifndef QT_NO_FILEDIALOG
2978     if (extension == ChooseMultipleFilesExtension) {
2979         // FIXME: do not ignore suggestedFiles
2980         QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames;
2981         QStringList names = QFileDialog::getOpenFileNames(view(), QString::null);
2982         static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
2983         return true;
2984     }
2985 #endif
2986
2987     return false;
2988 }
2989
2990 /*!
2991     This virtual function returns true if the web page supports \a extension; otherwise false is returned.
2992
2993     \sa extension()
2994 */
2995 bool QWebPage::supportsExtension(Extension extension) const
2996 {
2997 #ifndef QT_NO_FILEDIALOG
2998     return extension == ChooseMultipleFilesExtension;
2999 #else
3000     Q_UNUSED(extension);
3001     return false;
3002 #endif
3003 }
3004
3005 /*!
3006  * \internal
3007  */
3008 QWebPageAdapter *QWebPage::handle() const
3009 {
3010     return d;
3011 }
3012
3013 /*!
3014     Finds the specified string, \a subString, in the page, using the given \a options.
3015
3016     If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences
3017     that exist in the page. All subsequent calls will extend the highlight, rather than
3018     replace it, with occurrences of the new string.
3019
3020     If the HighlightAllOccurrences flag is not passed, the function will select an occurrence
3021     and all subsequent calls will replace the current occurrence with the next one.
3022
3023     To clear the selection, just pass an empty string.
3024
3025     Returns true if \a subString was found; otherwise returns false.
3026 */
3027 bool QWebPage::findText(const QString &subString, FindFlags options)
3028 {
3029     return d->findText(subString, static_cast<QWebPageAdapter::FindFlag>(options.operator int()));
3030 }
3031
3032 /*!
3033     Returns a pointer to the page's settings object.
3034
3035     \sa QWebSettings::globalSettings()
3036 */
3037 QWebSettings *QWebPage::settings() const
3038 {
3039     return d->settings;
3040 }
3041
3042 /*!
3043     This function is called when the web content requests a file name, for example
3044     as a result of the user clicking on a "file upload" button in a HTML form.
3045
3046     A suggested filename may be provided in \a suggestedFile. The frame originating the
3047     request is provided as \a parentFrame.
3048
3049     \sa ChooseMultipleFilesExtension
3050 */
3051 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile)
3052 {
3053     Q_UNUSED(parentFrame);
3054 #ifndef QT_NO_FILEDIALOG
3055     return QFileDialog::getOpenFileName(view(), QString::null, suggestedFile);
3056 #else
3057     return QString::null;
3058 #endif
3059 }
3060
3061 /*!
3062     Sets the QNetworkAccessManager \a manager responsible for serving network requests for this
3063     QWebPage.
3064
3065     \note It is currently not supported to change the network access manager after the
3066     QWebPage has used it. The results of doing this are undefined.
3067
3068     \sa networkAccessManager()
3069 */
3070 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
3071 {
3072     d->setNetworkAccessManager(manager);
3073 }
3074
3075 /*!
3076     Returns the QNetworkAccessManager that is responsible for serving network
3077     requests for this QWebPage.
3078
3079     \sa setNetworkAccessManager()
3080 */
3081 QNetworkAccessManager *QWebPage::networkAccessManager() const
3082 {
3083     return d->networkAccessManager();
3084 }
3085
3086 /*!
3087     Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this
3088     QWebPage.
3089
3090     Note: The plugin factory is only used if the QWebSettings::PluginsEnabled attribute is enabled.
3091
3092     \sa pluginFactory()
3093 */
3094 void QWebPage::setPluginFactory(QWebPluginFactory *factory)
3095 {
3096     d->pluginFactory = factory;
3097 }
3098
3099 /*!
3100     Returns the QWebPluginFactory that is responsible for creating plugins embedded into
3101     this QWebPage. If no plugin factory is installed a null pointer is returned.
3102
3103     \sa setPluginFactory()
3104 */
3105 QWebPluginFactory *QWebPage::pluginFactory() const
3106 {
3107     return d->pluginFactory;
3108 }
3109
3110 /*!
3111     This function is called when a user agent for HTTP requests is needed. You can reimplement this
3112     function to dynamically return different user agents for different URLs, based on the \a url parameter.
3113
3114     The default implementation returns the following value:
3115
3116     "Mozilla/5.0 (%Platform%%Security%%Subplatform%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%"
3117
3118     In this string the following values are replaced at run-time:
3119     \list
3120     \li %Platform% expands to the windowing system followed by "; " if it is not Windows (e.g. "X11; ").
3121     \li %Security% expands to "N; " if SSL is disabled.
3122     \li %Subplatform% expands to the operating system version (e.g. "Windows NT 6.1" or "Intel Mac OS X 10.5").
3123     \li %WebKitVersion% is the version of WebKit the application was compiled against.
3124     \li %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version.
3125     \endlist
3126 */
3127 QString QWebPage::userAgentForUrl(const QUrl&) const
3128 {
3129     return QWebPageAdapter::defaultUserAgentString();
3130 }
3131
3132
3133 /*!
3134     Returns the total number of bytes that were received from the network to render the current page,
3135     including extra content such as embedded images.
3136
3137     \sa bytesReceived()
3138 */
3139 quint64 QWebPage::totalBytes() const
3140 {
3141     return d->m_totalBytes;
3142 }
3143
3144
3145 /*!
3146     Returns the number of bytes that were received from the network to render the current page.
3147
3148     \sa totalBytes(), loadProgress()
3149 */
3150 quint64 QWebPage::bytesReceived() const
3151 {
3152     return d->m_bytesReceived;
3153 }
3154
3155
3156 /*!
3157     \property QWebPage::visibilityState
3158     \brief the page's visibility state
3159
3160     This property should be changed by Qt applications who want to notify the JavaScript application
3161     that the visibility state has changed (e.g. by reimplementing QWidget::setVisible).
3162     The visibility state will be updated with the \a state parameter value only if it's different from the previous set.
3163     Then, HTML DOM Document Object attributes 'hidden' and 'visibilityState'
3164     will be updated to the correct value and a 'visiblitychange' event will be fired.
3165     More information about this HTML5 API can be found at \l{http://www.w3.org/TR/page-visibility/}{W3C Recommendation: Page Visibility}.
3166
3167     By default, this property is set to VisibilityStateVisible.
3168 */
3169 void QWebPage::setVisibilityState(VisibilityState state)
3170 {
3171     d->setVisibilityState(static_cast<QWebPageAdapter::VisibilityState>(state));
3172 }
3173
3174 QWebPage::VisibilityState QWebPage::visibilityState() const
3175 {
3176     return static_cast<VisibilityState>(d->visibilityState());
3177 }
3178
3179
3180 /*!
3181     \since 4.8
3182     \fn void QWebPage::viewportChangeRequested()
3183
3184     Page authors can provide the supplied values by using the viewport meta tag. More information
3185     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}.
3186
3187     \sa QWebPage::ViewportAttributes, setPreferredContentsSize(), QGraphicsWebView::setScale()
3188 */
3189
3190 /*!
3191     \fn void QWebPage::loadStarted()
3192
3193     This signal is emitted when a page starts loading content.
3194
3195     \sa loadFinished()
3196 */
3197
3198 /*!
3199     \fn void QWebPage::loadProgress(int progress)
3200
3201     This signal is emitted when the global progress status changes.
3202     The current value is provided by \a progress and scales from 0 to 100,
3203     which is the default range of QProgressBar.
3204     It accumulates changes from all the child frames.
3205
3206     \sa bytesReceived()
3207 */
3208
3209 /*!
3210     \fn void QWebPage::loadFinished(bool ok)
3211
3212     This signal is emitted when the page finishes loading content. This signal
3213     is independant of script execution or page rendering.
3214     \a ok will indicate whether the load was successful or any error occurred.
3215
3216     \sa loadStarted(), ErrorPageExtension
3217 */
3218
3219 /*!
3220     \fn void QWebPage::linkHovered(const QString &link, const QString &title, const QString &textContent)
3221
3222     This signal is emitted when the mouse hovers over a link.
3223
3224     \a link contains the link url.
3225     \a title is the link element's title, if it is specified in the markup.
3226     \a textContent provides text within the link element, e.g., text inside an HTML anchor tag.
3227
3228     When the mouse leaves the link element the signal is emitted with empty parameters.
3229
3230     \sa linkClicked()
3231 */
3232
3233 /*!
3234     \fn void QWebPage::statusBarMessage(const QString& text)
3235
3236     This signal is emitted when the statusbar \a text is changed by the page.
3237 */
3238
3239 /*!
3240     \fn void QWebPage::frameCreated(QWebFrame *frame)
3241
3242     This signal is emitted whenever the page creates a new \a frame.
3243
3244     \sa currentFrame()
3245 */
3246
3247 /*!
3248     \fn void QWebPage::selectionChanged()
3249
3250     This signal is emitted whenever the selection changes, either interactively
3251     or programmatically (e.g. by calling triggerAction() with a selection action).
3252
3253     \sa selectedText()
3254 */
3255
3256 /*!
3257     \fn void QWebPage::contentsChanged()
3258     \since 4.5
3259
3260     This signal is emitted whenever the text in form elements changes
3261     as well as other editable content.
3262
3263     \sa contentEditable, modified, QWebFrame::toHtml(), QWebFrame::toPlainText()
3264 */
3265
3266 /*!
3267     \fn void QWebPage::geometryChangeRequested(const QRect& geom)
3268
3269     This signal is emitted whenever the document wants to change the position and size of the
3270     page to \a geom. This can happen for example through JavaScript.
3271 */
3272
3273 /*!
3274     \fn void QWebPage::repaintRequested(const QRect& dirtyRect)
3275
3276     This signal is emitted whenever this QWebPage should be updated. It's useful
3277     when rendering a QWebPage without a QWebView or QGraphicsWebView.
3278     \a dirtyRect contains the area that needs to be updated. To paint the QWebPage get
3279     the mainFrame() and call the render(QPainter*, const QRegion&) method with the
3280     \a dirtyRect as the second parameter.
3281
3282     \sa mainFrame()
3283     \sa view()
3284 */
3285
3286 /*!
3287     \fn void QWebPage::scrollRequested(int dx, int dy, const QRect& rectToScroll)
3288
3289     This signal is emitted whenever the content given by \a rectToScroll needs
3290     to be scrolled \a dx and \a dy downwards and no view was set.
3291
3292     \sa view()
3293 */
3294
3295 /*!
3296     \fn void QWebPage::windowCloseRequested()
3297
3298     This signal is emitted whenever the page requests the web browser window to be closed,
3299     for example through the JavaScript \c{window.close()} call.
3300 */
3301
3302 /*!
3303     \fn void QWebPage::printRequested(QWebFrame *frame)
3304
3305     This signal is emitted whenever the page requests the web browser to print \a frame,
3306     for example through the JavaScript \c{window.print()} call.
3307
3308     \sa QWebFrame::print(), QPrintPreviewDialog
3309 */
3310
3311 /*!
3312     \fn void QWebPage::unsupportedContent(QNetworkReply *reply)
3313
3314     This signal is emitted when WebKit cannot handle a link the user navigated to or a
3315     web server's response includes a "Content-Disposition" header with the 'attachment' 
3316     directive. If "Content-Disposition" is present in \a reply, the web server is indicating
3317     that the client should prompt the user to save the content regardless of content-type. 
3318     See RFC 2616 sections 19.5.1 for details about Content-Disposition.
3319
3320     At signal emission time the meta-data of the QNetworkReply \a reply is available.
3321
3322     \note The receiving slot is responsible for deleting the QNetworkReply \a reply.
3323
3324     \note This signal is only emitted if the forwardUnsupportedContent property is set to true.
3325
3326     \sa downloadRequested()
3327 */
3328
3329 /*!
3330     \fn void QWebPage::downloadRequested(const QNetworkRequest &request)
3331
3332     This signal is emitted when the user decides to download a link. The url of
3333     the link as well as additional meta-information is contained in \a request.
3334
3335     \sa unsupportedContent()
3336 */
3337
3338 /*!
3339     \fn void QWebPage::microFocusChanged()
3340
3341     This signal is emitted when for example the position of the cursor in an editable form
3342     element changes. It is used to inform input methods about the new on-screen position where
3343     the user is able to enter text. This signal is usually connected to the
3344     QWidget::updateMicroFocus() slot.
3345 */
3346
3347 /*!
3348     \fn void QWebPage::linkClicked(const QUrl &url)
3349
3350     This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy
3351     property is set to delegate the link handling for the specified \a url.
3352
3353     By default no links are delegated and are handled by QWebPage instead.
3354
3355     \note This signal possibly won't be emitted for clicked links which use
3356     JavaScript to trigger navigation.
3357
3358     \sa linkHovered()
3359 */
3360
3361 /*!
3362     \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible)
3363
3364     This signal is emitted whenever the visibility of the toolbar in a web browser
3365     window that hosts QWebPage should be changed to \a visible.
3366 */
3367
3368 /*!
3369     \fn void QWebPage::statusBarVisibilityChangeRequested(bool visible)
3370
3371     This signal is emitted whenever the visibility of the statusbar in a web browser
3372     window that hosts QWebPage should be changed to \a visible.
3373 */
3374
3375 /*!
3376     \fn void QWebPage::menuBarVisibilityChangeRequested(bool visible)
3377
3378     This signal is emitted whenever the visibility of the menubar in a web browser
3379     window that hosts QWebPage should be changed to \a visible.
3380 */
3381
3382 /*!
3383     \fn void QWebPage::databaseQuotaExceeded(QWebFrame* frame, QString databaseName);
3384     \since 4.5
3385
3386     This signal is emitted whenever the web site shown in \a frame is asking to store data
3387     to the database \a databaseName and the quota allocated to that web site is exceeded.
3388
3389     \sa QWebDatabase
3390 */
3391 /*!
3392     \fn void QWebPage::applicationCacheQuotaExceeded(QWebSecurityOrigin* origin, quint64 defaultOriginQuota, quint64 totalSpaceNeeded);
3393
3394     This signal is emitted whenever the web site is asking to store data to the application cache
3395     database databaseName and the quota allocated to that web site is exceeded.
3396
3397 */
3398
3399 /*!
3400   \since 4.5
3401   \fn void QWebPage::saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item);
3402
3403   This signal is emitted shortly before the history of navigated pages
3404   in \a frame is changed, for example when navigating back in the history.
3405
3406   The provided QWebHistoryItem, \a item, holds the history entry of the frame before
3407   the change.
3408
3409   A potential use-case for this signal is to store custom data in
3410   the QWebHistoryItem associated to the frame, using QWebHistoryItem::setUserData().
3411 */
3412
3413 /*!
3414   \since 4.5
3415   \fn void QWebPage::restoreFrameStateRequested(QWebFrame* frame);
3416
3417   This signal is emitted when the load of \a frame is finished and the application may now update its state accordingly.
3418 */
3419
3420 /*!
3421   \fn QWebPagePrivate* QWebPage::handle() const
3422   \internal
3423 */
3424
3425 #include "moc_qwebpage.cpp"