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