* Move the QWebPagePrivate methods up to the other private ones
[WebKit-https.git] / WebKit / qt / Api / qwebpage.cpp
index f3954967ff8023af54aeb5ab8f8123e70765c218..a523044754754b482a4bcaa3980d165392c3eb44 100644 (file)
 
 using namespace WebCore;
 
+static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
+{
+    unsigned result = 0;
+    if (actions & Qt::CopyAction)
+        result |= DragOperationCopy;
+    if (actions & Qt::MoveAction)
+        result |= DragOperationMove;
+    if (actions & Qt::LinkAction)
+        result |= DragOperationLink;
+    return (DragOperation)result;    
+}
+
+static inline Qt::DropAction dragOpToDropAction(unsigned actions)
+{
+    Qt::DropAction result = Qt::IgnoreAction;
+    if (actions & DragOperationCopy)
+        result = Qt::CopyAction;
+    else if (actions & DragOperationMove)
+        result = Qt::MoveAction;
+    else if (actions & DragOperationLink)
+        result = Qt::LinkAction;
+    return result;    
+}
+
 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
     : q(qq)
     , view(0)
@@ -283,890 +307,866 @@ void QWebPagePrivate::updateEditorActions()
     updateAction(QWebPage::Paste);
 }
 
-QWebPage::QWebPage(QObject *parent)
-    : QObject(parent)
-    , d(new QWebPagePrivate(this))
+void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev)
 {
-    setView(qobject_cast<QWidget *>(parent));
+    QWebFrame *f = currentFrame(ev->pos());
+    if (!f)
+        return;
 
-    connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
-}
+    QWebFramePrivate *frame = f->d;
+    if (!frame->frameView)
+        return;
 
-QWebPage::~QWebPage()
-{
-    FrameLoader *loader = d->mainFrame->d->frame->loader();
-    if (loader)
-        loader->detachFromParent();
-    delete d;
+    frame->eventHandler->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
+    const int xOffset =
+        frame->horizontalScrollBar() ? frame->horizontalScrollBar()->value() : 0;
+    const int yOffset =
+        frame->verticalScrollBar() ? frame->verticalScrollBar()->value() : 0;
+    IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
+    WebCore::HitTestResult result = frame->eventHandler->hitTestResultAtPoint(pt, false);
+    WebCore::Element *link = result.URLElement();
+    if (link != frame->lastHoverElement) {
+        frame->lastHoverElement = link;
+        emit q->hoveringOverLink(result.absoluteLinkURL().prettyURL(), result.title(), result.textContent());
+    }
 }
 
-QWebFrame *QWebPage::mainFrame() const
+void QWebPagePrivate::mousePressEvent(QMouseEvent *ev)
 {
-    d->createMainFrame();
-    return d->mainFrame;
-}
+    frameUnderMouse = frameAt(ev->pos());
+    if (!frameUnderMouse)
+        return;
 
-QWebFrame *QWebPage::currentFrame() const
-{
-    return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame();
-}
+    QWebFramePrivate *frame = frameUnderMouse->d;
+    if (!frame->eventHandler)
+        return;
 
-QWebPageHistory *QWebPage::history() const
-{
-    return &d->history;
+    frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
 }
 
-void QWebPage::setView(QWidget *view)
+void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev)
 {
-    d->view = view;
-    setViewportSize(view ? view->size() : QSize(0, 0));
+    QWebFrame *f = currentFrame(ev->pos());
+    if (!f)
+        return;
+
+    QWebFramePrivate *frame = f->d;
+    if (!frame->eventHandler)
+        return;
+
+    frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 2));
 }
 
-QWidget *QWebPage::view() const
+void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev)
 {
-    return d->view;
-}
+    QWebFrame *f = currentFrame(ev->pos());
+    if (!f)
+        return;
 
+    QWebFramePrivate *frame = f->d;
+    if (!frame->frameView)
+        return;
 
-void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
-{
-}
+    frame->eventHandler->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
 
-void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
-{
-    //FIXME frame pos...
-    QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Ok);
+    frameUnderMouse = 0;
 }
 
-bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
+void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev)
 {
-    //FIXME frame pos...
-    return 0 == QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Yes, QMessageBox::No);
-}
+    QWebFrame *f = currentFrame(ev->pos());
+    if (!f)
+        return;
 
-bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
-{
-    //FIXME frame pos...
-    bool ok = false;
-#ifndef QT_NO_INPUTDIALOG
-    QString x = QInputDialog::getText(d->view, mainFrame()->title(), msg, QLineEdit::Normal, defaultValue, &ok);
-    if (ok && result) {
-        *result = x;
-    }
-#endif
-    return ok;
-}
+    QWebFramePrivate *frame = f->d;
+    if (!frame->eventHandler)
+        return;
 
-QWebPage *QWebPage::createWindow()
-{
-    return 0;
-}
+    page->contextMenuController()->clearContextMenu();
+    frame->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
+    ContextMenu *menu = page->contextMenuController()->contextMenu();
 
-QWebPage *QWebPage::createModalDialog()
-{
-    return 0;
-}
+    QWebPageContext oldContext = currentContext;
+    currentContext = QWebPageContext(menu->hitTestResult());
 
-QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
-{
-    Q_UNUSED(classid)
-    Q_UNUSED(url)
-    Q_UNUSED(paramNames)
-    Q_UNUSED(paramValues)
-    return 0;
+    const QList<ContextMenuItem> *items = menu->platformDescription();
+    QMenu *qmenu = createContextMenu(menu, items);
+    if (qmenu) {
+        qmenu->exec(ev->globalPos());
+        delete qmenu;
+    }
+    currentContext = oldContext;
 }
 
-static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
+void QWebPagePrivate::wheelEvent(QWheelEvent *ev)
 {
-    WebCore::ResourceRequest rr(WebCore::KURL(url.toString()),
-                                frame->loader()->outgoingReferrer());
-    return WebCore::FrameLoadRequest(rr);
-}
+    QWebFramePrivate *frame = currentFrame(ev->pos())->d;
 
-static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
-{
-    if (Page* oldPage = frame->page()) {
-        WindowFeatures features;
-        if (Page* newPage = oldPage->chrome()->createWindow(frame,
-                frameLoadRequest(url, frame), features))
-            newPage->chrome()->show();
+    bool accepted = false;
+    if (frame->eventHandler) {
+        WebCore::PlatformWheelEvent pev(ev);
+        accepted = frame->eventHandler->handleWheelEvent(pev);
     }
+
+    ev->setAccepted(accepted);
 }
 
-void QWebPage::triggerAction(WebAction action, bool checked)
+void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
 {
-    WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
-    WebCore::Editor *editor = frame->editor();
-    const char *command = 0;
-
-    switch (action) {
-        case OpenLink:
-            if (QWebFrame *targetFrame = d->currentContext.targetFrame()) {
-                WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
-                targetFrame->d->frame->loader()->load(frameLoadRequest(d->currentContext.linkUrl(), wcFrame.get()),
-                                                      /*lockHistory*/ false,
-                                                      /*userGesture*/ true,
-                                                      /*event*/ 0,
-                                                      /*HTMLFormElement*/ 0,
-                                                      /*formValues*/
-                                                      WTF::HashMap<String, String>());
-                break;
-            } else {
-            }
-            // fall through
-        case OpenLinkInNewWindow:
-            openNewWindow(d->currentContext.linkUrl(), frame);
-            break;
-        case OpenFrameInNewWindow:
-            break;
-        case DownloadLinkToDisk:
-        case CopyLinkToClipboard:
-            editor->copyURL(WebCore::KURL(d->currentContext.linkUrl().toString()), d->currentContext.text());
-            break;
-        case OpenImageInNewWindow:
-            openNewWindow(d->currentContext.imageUrl(), frame);
-            break;
-        case DownloadImageToDisk:
-        case CopyImageToClipboard:
-            break;
-        case GoBack:
-            d->page->goBack();
-            break;
-        case GoForward:
-            d->page->goForward();
-            break;
-        case Stop:
-            mainFrame()->d->frame->loader()->stopForUserCancel();
-            break;
-        case Reload:
-            mainFrame()->d->frame->loader()->reload();
-            break;
-        case Cut:
-            command = "Cut";
-            break;
-        case Copy:
-            command = "Copy";
-            break;
-        case Paste:
-            command = "Paste";
-            break;
-
-        case Undo:
-            command = "Undo";
-            break;
-        case Redo:
-            command = "Redo";
-            break;
+    if (!mainFrame->d->eventHandler)
+        return;
 
-        case MoveToNextChar:
-            command = "MoveForward";
-            break;
-        case MoveToPreviousChar:
-            command = "MoveBackward";
-            break;
-        case MoveToNextWord:
-            command = "MoveWordForward";
-            break;
-        case MoveToPreviousWord:
-            command = "MoveWordBackward";
-            break;
-        case MoveToNextLine:
-            command = "MoveDown";
-            break;
-        case MoveToPreviousLine:
-            command = "MoveUp";
-            break;
-        case MoveToStartOfLine:
-            command = "MoveToBeginningOfLine";
-            break;
-        case MoveToEndOfLine:
-            command = "MoveToEndOfLine";
-            break;
-        case MoveToStartOfBlock:
-            command = "MoveToBeginningOfParagraph";
-            break;
-        case MoveToEndOfBlock:
-            command = "MoveToEndOfParagraph";
-            break;
-        case MoveToStartOfDocument:
-            command = "MoveToBeginningOfDocument";
-            break;
-        case MoveToEndOfDocument:
-            command = "MoveToEndOfDocument";
-            break;
-        case SelectNextChar:
-            command = "MoveForwardAndModifySelection";
-            break;
-        case SelectPreviousChar:
-            command = "MoveBackwardAndModifySelection";
-            break;
-        case SelectNextWord:
-            command = "MoveWordForwardAndModifySelection";
-            break;
-        case SelectPreviousWord:
-            command = "MoveWordBackwardAndModifySelection";
-            break;
-        case SelectNextLine:
-            command = "MoveDownAndModifySelection";
-            break;
-        case SelectPreviousLine:
-            command = "MoveUpAndModifySelection";
-            break;
-        case SelectStartOfLine:
-            command = "MoveToBeginningOfLineAndModifySelection";
-            break;
-        case SelectEndOfLine:
-            command = "MoveToEndOfLineAndModifySelection";
-            break;
-        case SelectStartOfBlock:
-            command = "MoveToBeginningOfParagraphAndModifySelection";
-            break;
-        case SelectEndOfBlock:
-            command = "MoveToEndOfParagraphAndModifySelection";
-            break;
-        case SelectStartOfDocument:
-            command = "MoveToBeginningOfDocumentAndModifySelection";
-            break;
-        case SelectEndOfDocument:
-            command = "MoveToEndOfDocumentAndModifySelection";
-            break;
-        case DeleteStartOfWord:
-            command = "DeleteWordBackward";
-            break;
-        case DeleteEndOfWord:
-            command = "DeleteWordForward";
-            break;
+    bool handled = false;
+    QWebFrame *frame = mainFrame;
+    WebCore::Editor *editor = frame->d->frame->editor();
+    if (editor->canEdit()) {
+        if (ev == QKeySequence::Cut) {
+            q->triggerAction(QWebPage::Cut);
+            handled = true;
+        } else if (ev == QKeySequence::Copy) {
+            q->triggerAction(QWebPage::Copy);
+            handled = true;
+        } else if (ev == QKeySequence::Paste) {
+            q->triggerAction(QWebPage::Paste);
+            handled = true;
+        } else if (ev == QKeySequence::Undo) {
+            q->triggerAction(QWebPage::Undo);
+            handled = true;
+        } else if (ev == QKeySequence::Redo) {
+            q->triggerAction(QWebPage::Redo);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToNextChar) {
+            q->triggerAction(QWebPage::MoveToNextChar);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToPreviousChar) {
+            q->triggerAction(QWebPage::MoveToPreviousChar);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToNextWord) {
+            q->triggerAction(QWebPage::MoveToNextWord);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToPreviousWord) {
+            q->triggerAction(QWebPage::MoveToPreviousWord);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToNextLine) {
+            q->triggerAction(QWebPage::MoveToNextLine);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToPreviousLine) {
+            q->triggerAction(QWebPage::MoveToPreviousLine);
+            handled = true;
+//             } else if(ev == QKeySequence::MoveToNextPage) {
+//             } else if(ev == QKeySequence::MoveToPreviousPage) {
+        } else if(ev == QKeySequence::MoveToStartOfLine) {
+            q->triggerAction(QWebPage::MoveToStartOfLine);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToEndOfLine) {
+            q->triggerAction(QWebPage::MoveToEndOfLine);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToStartOfBlock) {
+            q->triggerAction(QWebPage::MoveToStartOfBlock);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToEndOfBlock) {
+            q->triggerAction(QWebPage::MoveToEndOfBlock);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToStartOfDocument) {
+            q->triggerAction(QWebPage::MoveToStartOfDocument);
+            handled = true;
+        } else if(ev == QKeySequence::MoveToEndOfDocument) {
+            q->triggerAction(QWebPage::MoveToEndOfDocument);
+            handled = true;
+        } else if(ev == QKeySequence::SelectNextChar) {
+            q->triggerAction(QWebPage::SelectNextChar);
+            handled = true;
+        } else if(ev == QKeySequence::SelectPreviousChar) {
+            q->triggerAction(QWebPage::SelectPreviousChar);
+            handled = true;
+        } else if(ev == QKeySequence::SelectNextWord) {
+            q->triggerAction(QWebPage::SelectNextWord);
+            handled = true;
+        } else if(ev == QKeySequence::SelectPreviousWord) {
+            q->triggerAction(QWebPage::SelectPreviousWord);
+            handled = true;
+        } else if(ev == QKeySequence::SelectNextLine) {
+            q->triggerAction(QWebPage::SelectNextLine);
+            handled = true;
+        } else if(ev == QKeySequence::SelectPreviousLine) {
+            q->triggerAction(QWebPage::SelectPreviousLine);
+            handled = true;
+//             } else if(ev == QKeySequence::SelectNextPage) {
+//             } else if(ev == QKeySequence::SelectPreviousPage) {
+        } else if(ev == QKeySequence::SelectStartOfLine) {
+            q->triggerAction(QWebPage::SelectStartOfLine);
+            handled = true;
+        } else if(ev == QKeySequence::SelectEndOfLine) {
+            q->triggerAction(QWebPage::SelectEndOfLine);
+            handled = true;
+        } else if(ev == QKeySequence::SelectStartOfBlock) {
+            q->triggerAction(QWebPage::SelectStartOfBlock);
+            handled = true;
+        } else if(ev == QKeySequence::SelectEndOfBlock) {
+            q->triggerAction(QWebPage::SelectEndOfBlock);
+            handled = true;
+        } else if(ev == QKeySequence::SelectStartOfDocument) {
+            q->triggerAction(QWebPage::SelectStartOfDocument);
+            handled = true;
+        } else if(ev == QKeySequence::SelectEndOfDocument) {
+            q->triggerAction(QWebPage::SelectEndOfDocument);
+            handled = true;
+        } else if(ev == QKeySequence::DeleteStartOfWord) {
+            q->triggerAction(QWebPage::DeleteStartOfWord);
+            handled = true;
+        } else if(ev == QKeySequence::DeleteEndOfWord) {
+            q->triggerAction(QWebPage::DeleteEndOfWord);
+            handled = true;
+//             } else if(ev == QKeySequence::DeleteEndOfLine) {
+        }
+    }
+    if (!handled) 
+        handled = frame->d->eventHandler->keyEvent(ev);
+    if (!handled) {
+        handled = true;
+        PlatformScrollbar *h, *v;
+        h = mainFrame->d->horizontalScrollBar();
+        v = mainFrame->d->verticalScrollBar();
 
-        case SetTextDirectionDefault:
-            editor->setBaseWritingDirection("inherit");
-            break;
-        case SetTextDirectionLeftToRight:
-            editor->setBaseWritingDirection("ltr");
-            break;
-        case SetTextDirectionRightToLeft:
-            editor->setBaseWritingDirection("rtl");
-            break;
+        if (ev == QKeySequence::MoveToNextPage) {
+            if (v)
+                v->setValue(v->value() + q->viewportSize().height());
+        } else if (ev == QKeySequence::MoveToPreviousPage) {
+            if (v)
+                v->setValue(v->value() - q->viewportSize().height());
+        } else {
+            switch (ev->key()) {
+            case Qt::Key_Up:
+                if (v)
+                    v->setValue(v->value() - 10);
+                break;
+            case Qt::Key_Down:
+                if (v)
+                    v->setValue(v->value() + 10);
+                break;
+            case Qt::Key_Left:
+                if (h)
+                    h->setValue(h->value() - 10);
+                break;
+            case Qt::Key_Right:
+                if (h)
+                    h->setValue(h->value() + 10);
+                break;
+            default:
+                handled = false;
+                break;
+            }
+        }
+    }
 
-        case ToggleBold:
-            command = "ToggleBold";
-            break;
-        case ToggleItalic:
-            command = "ToggleItalic";
-            break;
-        case ToggleUnderline:
-            editor->toggleUnderline();
+    ev->setAccepted(handled);
+}
 
-        case InspectElement:
-            d->page->inspectorController()->inspect(d->currentContext.d->innerNonSharedNode.get());
-            break;
+void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
+{
+    if (ev->isAutoRepeat()) {
+        ev->setAccepted(true);
+        return;
+    }
 
-        default: break;
+    if (!mainFrame->d->eventHandler)
+        return;
+
+    bool handled = mainFrame->d->eventHandler->keyEvent(ev);
+    ev->setAccepted(handled);
+}
+
+void QWebPagePrivate::focusInEvent(QFocusEvent *ev)
+{
+    if (ev->reason() != Qt::PopupFocusReason) 
+        mainFrame->d->frame->page()->focusController()->setFocusedFrame(mainFrame->d->frame);
+}
+
+void QWebPagePrivate::focusOutEvent(QFocusEvent *ev)
+{
+    if (ev->reason() != Qt::PopupFocusReason) {
+        mainFrame->d->frame->selectionController()->clear();
+        mainFrame->d->frame->setIsActive(false);
     }
+}
 
-    if (command)
-        editor->command(command).execute();
+void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
+                      dropActionToDragOp(ev->possibleActions()));
+    Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
+    ev->setDropAction(action);
+    ev->accept();
+#endif
 }
 
-QSize QWebPage::viewportSize() const
+void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev)
 {
-    QWebFrame *frame = mainFrame();
-    if (frame->d->frame && frame->d->frameView)
-        return frame->d->frameView->frameGeometry().size();
-    return QSize(0, 0);
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
+    page->dragController()->dragExited(&dragData);
+    ev->accept();
+#endif
 }
 
-void QWebPage::setViewportSize(const QSize &size) const
+void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev)
 {
-    QWebFrame *frame = mainFrame();
-    if (frame->d->frame && frame->d->frameView) {
-        frame->d->frameView->setFrameGeometry(QRect(QPoint(0, 0), size));
-        frame->d->frame->forceLayout();
-        frame->d->frame->view()->adjustViewSize();
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
+                      dropActionToDragOp(ev->possibleActions()));
+    Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
+    ev->setDropAction(action);
+    ev->accept();
+#endif
+}
+
+void QWebPagePrivate::dropEvent(QDropEvent *ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
+                      dropActionToDragOp(ev->possibleActions()));
+    Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData));
+    ev->accept();
+#endif
+}
+
+QWebPage::QWebPage(QObject *parent)
+    : QObject(parent)
+    , d(new QWebPagePrivate(this))
+{
+    setView(qobject_cast<QWidget *>(parent));
+
+    connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
+}
+
+QWebPage::~QWebPage()
+{
+    FrameLoader *loader = d->mainFrame->d->frame->loader();
+    if (loader)
+        loader->detachFromParent();
+    delete d;
+}
+
+QWebFrame *QWebPage::mainFrame() const
+{
+    d->createMainFrame();
+    return d->mainFrame;
+}
+
+QWebFrame *QWebPage::currentFrame() const
+{
+    return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame();
+}
+
+QWebPageHistory *QWebPage::history() const
+{
+    return &d->history;
+}
+
+void QWebPage::setView(QWidget *view)
+{
+    d->view = view;
+    setViewportSize(view ? view->size() : QSize(0, 0));
+}
+
+QWidget *QWebPage::view() const
+{
+    return d->view;
+}
+
+
+void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
+{
+}
+
+void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
+{
+    //FIXME frame pos...
+    QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Ok);
+}
+
+bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
+{
+    //FIXME frame pos...
+    return 0 == QMessageBox::information(d->view, mainFrame()->title(), msg, QMessageBox::Yes, QMessageBox::No);
+}
+
+bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
+{
+    //FIXME frame pos...
+    bool ok = false;
+#ifndef QT_NO_INPUTDIALOG
+    QString x = QInputDialog::getText(d->view, mainFrame()->title(), msg, QLineEdit::Normal, defaultValue, &ok);
+    if (ok && result) {
+        *result = x;
     }
+#endif
+    return ok;
 }
 
+QWebPage *QWebPage::createWindow()
+{
+    return 0;
+}
 
-QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
+QWebPage *QWebPage::createModalDialog()
 {
-    Q_UNUSED(request)
-    return AcceptNavigationRequest;
+    return 0;
 }
 
-QString QWebPage::selectedText() const
+QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
 {
-    return d->page->focusController()->focusedOrMainFrame()->selectedText();
+    Q_UNUSED(classid)
+    Q_UNUSED(url)
+    Q_UNUSED(paramNames)
+    Q_UNUSED(paramValues)
+    return 0;
 }
 
-QAction *QWebPage::action(WebAction action) const
+static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
 {
-    if (action == QWebPage::NoWebAction) return 0;
-    if (d->actions[action])
-        return d->actions[action];
+    WebCore::ResourceRequest rr(WebCore::KURL(url.toString()),
+                                frame->loader()->outgoingReferrer());
+    return WebCore::FrameLoadRequest(rr);
+}
 
-    QString text;
-    bool checkable = false;
+static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
+{
+    if (Page* oldPage = frame->page()) {
+        WindowFeatures features;
+        if (Page* newPage = oldPage->chrome()->createWindow(frame,
+                frameLoadRequest(url, frame), features))
+            newPage->chrome()->show();
+    }
+}
+
+void QWebPage::triggerAction(WebAction action, bool checked)
+{
+    WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
+    WebCore::Editor *editor = frame->editor();
+    const char *command = 0;
 
     switch (action) {
         case OpenLink:
-            text = contextMenuItemTagOpenLink();
-            break;
+            if (QWebFrame *targetFrame = d->currentContext.targetFrame()) {
+                WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
+                targetFrame->d->frame->loader()->load(frameLoadRequest(d->currentContext.linkUrl(), wcFrame.get()),
+                                                      /*lockHistory*/ false,
+                                                      /*userGesture*/ true,
+                                                      /*event*/ 0,
+                                                      /*HTMLFormElement*/ 0,
+                                                      /*formValues*/
+                                                      WTF::HashMap<String, String>());
+                break;
+            } else {
+            }
+            // fall through
         case OpenLinkInNewWindow:
-            text = contextMenuItemTagOpenLinkInNewWindow();
+            openNewWindow(d->currentContext.linkUrl(), frame);
             break;
         case OpenFrameInNewWindow:
-            text = contextMenuItemTagOpenFrameInNewWindow();
             break;
-
         case DownloadLinkToDisk:
-            text = contextMenuItemTagDownloadLinkToDisk();
-            break;
         case CopyLinkToClipboard:
-            text = contextMenuItemTagCopyLinkToClipboard();
+            editor->copyURL(WebCore::KURL(d->currentContext.linkUrl().toString()), d->currentContext.text());
             break;
-
         case OpenImageInNewWindow:
-            text = contextMenuItemTagOpenImageInNewWindow();
+            openNewWindow(d->currentContext.imageUrl(), frame);
             break;
         case DownloadImageToDisk:
-            text = contextMenuItemTagDownloadImageToDisk();
-            break;
         case CopyImageToClipboard:
-            text = contextMenuItemTagCopyImageToClipboard();
             break;
-
         case GoBack:
-            text = contextMenuItemTagGoBack();
+            d->page->goBack();
             break;
         case GoForward:
-            text = contextMenuItemTagGoForward();
+            d->page->goForward();
             break;
         case Stop:
-            text = contextMenuItemTagStop();
+            mainFrame()->d->frame->loader()->stopForUserCancel();
             break;
         case Reload:
-            text = contextMenuItemTagReload();
+            mainFrame()->d->frame->loader()->reload();
             break;
-
         case Cut:
-            text = contextMenuItemTagCut();
+            command = "Cut";
             break;
         case Copy:
-            text = contextMenuItemTagCopy();
+            command = "Copy";
             break;
         case Paste:
-            text = contextMenuItemTagPaste();
+            command = "Paste";
+            break;
+
+        case Undo:
+            command = "Undo";
+            break;
+        case Redo:
+            command = "Redo";
             break;
 
-        case Undo: {
-            QAction *a = undoStack()->createUndoAction(d->q);
-            d->actions[action] = a;
-            return a;
-        }
-        case Redo: {
-            QAction *a = undoStack()->createRedoAction(d->q);
-            d->actions[action] = a;
-            return a;
-        }
         case MoveToNextChar:
+            command = "MoveForward";
+            break;
         case MoveToPreviousChar:
+            command = "MoveBackward";
+            break;
         case MoveToNextWord:
+            command = "MoveWordForward";
+            break;
         case MoveToPreviousWord:
+            command = "MoveWordBackward";
+            break;
         case MoveToNextLine:
+            command = "MoveDown";
+            break;
         case MoveToPreviousLine:
+            command = "MoveUp";
+            break;
         case MoveToStartOfLine:
+            command = "MoveToBeginningOfLine";
+            break;
         case MoveToEndOfLine:
+            command = "MoveToEndOfLine";
+            break;
         case MoveToStartOfBlock:
+            command = "MoveToBeginningOfParagraph";
+            break;
         case MoveToEndOfBlock:
+            command = "MoveToEndOfParagraph";
+            break;
         case MoveToStartOfDocument:
+            command = "MoveToBeginningOfDocument";
+            break;
         case MoveToEndOfDocument:
+            command = "MoveToEndOfDocument";
+            break;
         case SelectNextChar:
+            command = "MoveForwardAndModifySelection";
+            break;
         case SelectPreviousChar:
+            command = "MoveBackwardAndModifySelection";
+            break;
         case SelectNextWord:
+            command = "MoveWordForwardAndModifySelection";
+            break;
         case SelectPreviousWord:
+            command = "MoveWordBackwardAndModifySelection";
+            break;
         case SelectNextLine:
+            command = "MoveDownAndModifySelection";
+            break;
         case SelectPreviousLine:
+            command = "MoveUpAndModifySelection";
+            break;
         case SelectStartOfLine:
+            command = "MoveToBeginningOfLineAndModifySelection";
+            break;
         case SelectEndOfLine:
+            command = "MoveToEndOfLineAndModifySelection";
+            break;
         case SelectStartOfBlock:
+            command = "MoveToBeginningOfParagraphAndModifySelection";
+            break;
         case SelectEndOfBlock:
+            command = "MoveToEndOfParagraphAndModifySelection";
+            break;
         case SelectStartOfDocument:
+            command = "MoveToBeginningOfDocumentAndModifySelection";
+            break;
         case SelectEndOfDocument:
+            command = "MoveToEndOfDocumentAndModifySelection";
+            break;
         case DeleteStartOfWord:
+            command = "DeleteWordBackward";
+            break;
         case DeleteEndOfWord:
-            break; // ####
+            command = "DeleteWordForward";
+            break;
 
         case SetTextDirectionDefault:
-            text = contextMenuItemTagDefaultDirection();
+            editor->setBaseWritingDirection("inherit");
             break;
         case SetTextDirectionLeftToRight:
-            text = contextMenuItemTagLeftToRight();
-            checkable = true;
+            editor->setBaseWritingDirection("ltr");
             break;
         case SetTextDirectionRightToLeft:
-            text = contextMenuItemTagRightToLeft();
-            checkable = true;
-            break;
-
-        case ToggleBold:
-            text = contextMenuItemTagBold();
-            checkable = true;
-            break;
-        case ToggleItalic:
-            text = contextMenuItemTagItalic();
-            checkable = true;
-            break;
-        case ToggleUnderline:
-            text = contextMenuItemTagUnderline();
-            checkable = true;
-            break;
-
-        case InspectElement:
-            text = contextMenuItemTagInspectElement();
+            editor->setBaseWritingDirection("rtl");
             break;
 
-        case NoWebAction:
-            return 0;
-    }
-
-    if (text.isEmpty())
-        return 0;
-
-    QAction *a = new QAction(d->q);
-    a->setText(text);
-    a->setData(action);
-    a->setCheckable(checkable);
-
-    connect(a, SIGNAL(triggered(bool)),
-            this, SLOT(_q_webActionTriggered(bool)));
-
-    d->actions[action] = a;
-    d->updateAction(action);
-    return a;
-}
-
-/*!
-  Returns true if the page contains unsubmitted form data.
-*/
-bool QWebPage::isModified() const
-{
-    return d->modified;
-}
-
-
-QUndoStack *QWebPage::undoStack() const
-{
-    if (!d->undoStack)
-        d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
-
-    return d->undoStack;
-}
-
-static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
-{
-    unsigned result = 0;
-    if (actions & Qt::CopyAction)
-        result |= DragOperationCopy;
-    if (actions & Qt::MoveAction)
-        result |= DragOperationMove;
-    if (actions & Qt::LinkAction)
-        result |= DragOperationLink;
-    return (DragOperation)result;    
-}
-
-static inline Qt::DropAction dragOpToDropAction(unsigned actions)
-{
-    Qt::DropAction result = Qt::IgnoreAction;
-    if (actions & DragOperationCopy)
-        result = Qt::CopyAction;
-    else if (actions & DragOperationMove)
-        result = Qt::MoveAction;
-    else if (actions & DragOperationLink)
-        result = Qt::LinkAction;
-    return result;    
-}
-
-/*! \reimp
-*/
-bool QWebPage::event(QEvent *ev)
-{
-    switch (ev->type()) {
-    case QEvent::MouseMove:
-        d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
-        break;
-    case QEvent::MouseButtonPress:
-        d->mousePressEvent(static_cast<QMouseEvent*>(ev));
-        break;
-    case QEvent::MouseButtonDblClick:
-        d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
-        break;
-    case QEvent::MouseButtonRelease:
-        d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
-        break;
-    case QEvent::ContextMenu:
-        d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev));
-        break;
-    case QEvent::Wheel:
-        d->wheelEvent(static_cast<QWheelEvent*>(ev));
-        break;
-    case QEvent::KeyPress:
-        d->keyPressEvent(static_cast<QKeyEvent*>(ev));
-        break;
-    case QEvent::KeyRelease:
-        d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
-        break;
-    case QEvent::FocusIn:
-        d->focusInEvent(static_cast<QFocusEvent*>(ev));
-        break;
-    case QEvent::FocusOut:
-        d->focusOutEvent(static_cast<QFocusEvent*>(ev));
-        break;
-    case QEvent::DragEnter:
-        d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
-        break;
-    case QEvent::DragLeave:
-        d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
-        break;
-    case QEvent::DragMove:
-        d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
-        break;
-    case QEvent::Drop:
-        d->dropEvent(static_cast<QDropEvent*>(ev));
-        break;
-    default:
-        return QObject::event(ev);
-    }
-
-    return true;
-}
-
-void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev)
-{
-    QWebFrame *f = currentFrame(ev->pos());
-    if (!f)
-        return;
+        case ToggleBold:
+            command = "ToggleBold";
+            break;
+        case ToggleItalic:
+            command = "ToggleItalic";
+            break;
+        case ToggleUnderline:
+            editor->toggleUnderline();
 
-    QWebFramePrivate *frame = f->d;
-    if (!frame->frameView)
-        return;
+        case InspectElement:
+            d->page->inspectorController()->inspect(d->currentContext.d->innerNonSharedNode.get());
+            break;
 
-    frame->eventHandler->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
-    const int xOffset =
-        frame->horizontalScrollBar() ? frame->horizontalScrollBar()->value() : 0;
-    const int yOffset =
-        frame->verticalScrollBar() ? frame->verticalScrollBar()->value() : 0;
-    IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
-    WebCore::HitTestResult result = frame->eventHandler->hitTestResultAtPoint(pt, false);
-    WebCore::Element *link = result.URLElement();
-    if (link != frame->lastHoverElement) {
-        frame->lastHoverElement = link;
-        emit q->hoveringOverLink(result.absoluteLinkURL().prettyURL(), result.title(), result.textContent());
+        default: break;
     }
-}
 
-void QWebPagePrivate::mousePressEvent(QMouseEvent *ev)
-{
-    frameUnderMouse = frameAt(ev->pos());
-    if (!frameUnderMouse)
-        return;
-
-    QWebFramePrivate *frame = frameUnderMouse->d;
-    if (!frame->eventHandler)
-        return;
-
-    frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
+    if (command)
+        editor->command(command).execute();
 }
 
-void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev)
+QSize QWebPage::viewportSize() const
 {
-    QWebFrame *f = currentFrame(ev->pos());
-    if (!f)
-        return;
-
-    QWebFramePrivate *frame = f->d;
-    if (!frame->eventHandler)
-        return;
-
-    frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 2));
+    QWebFrame *frame = mainFrame();
+    if (frame->d->frame && frame->d->frameView)
+        return frame->d->frameView->frameGeometry().size();
+    return QSize(0, 0);
 }
 
-void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev)
+void QWebPage::setViewportSize(const QSize &size) const
 {
-    QWebFrame *f = currentFrame(ev->pos());
-    if (!f)
-        return;
-
-    QWebFramePrivate *frame = f->d;
-    if (!frame->frameView)
-        return;
+    QWebFrame *frame = mainFrame();
+    if (frame->d->frame && frame->d->frameView) {
+        frame->d->frameView->setFrameGeometry(QRect(QPoint(0, 0), size));
+        frame->d->frame->forceLayout();
+        frame->d->frame->view()->adjustViewSize();
+    }
+}
 
-    frame->eventHandler->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
 
-    frameUnderMouse = 0;
+QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
+{
+    Q_UNUSED(request)
+    return AcceptNavigationRequest;
 }
 
-void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev)
+QString QWebPage::selectedText() const
 {
-    QWebFrame *f = currentFrame(ev->pos());
-    if (!f)
-        return;
-
-    QWebFramePrivate *frame = f->d;
-    if (!frame->eventHandler)
-        return;
-
-    page->contextMenuController()->clearContextMenu();
-    frame->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
-    ContextMenu *menu = page->contextMenuController()->contextMenu();
-
-    QWebPageContext oldContext = currentContext;
-    currentContext = QWebPageContext(menu->hitTestResult());
-
-    const QList<ContextMenuItem> *items = menu->platformDescription();
-    QMenu *qmenu = createContextMenu(menu, items);
-    if (qmenu) {
-        qmenu->exec(ev->globalPos());
-        delete qmenu;
-    }
-    currentContext = oldContext;
+    return d->page->focusController()->focusedOrMainFrame()->selectedText();
 }
 
-void QWebPagePrivate::wheelEvent(QWheelEvent *ev)
+QAction *QWebPage::action(WebAction action) const
 {
-    QWebFramePrivate *frame = currentFrame(ev->pos())->d;
+    if (action == QWebPage::NoWebAction) return 0;
+    if (d->actions[action])
+        return d->actions[action];
 
-    bool accepted = false;
-    if (frame->eventHandler) {
-        WebCore::PlatformWheelEvent pev(ev);
-        accepted = frame->eventHandler->handleWheelEvent(pev);
-    }
+    QString text;
+    bool checkable = false;
 
-    ev->setAccepted(accepted);
-}
+    switch (action) {
+        case OpenLink:
+            text = contextMenuItemTagOpenLink();
+            break;
+        case OpenLinkInNewWindow:
+            text = contextMenuItemTagOpenLinkInNewWindow();
+            break;
+        case OpenFrameInNewWindow:
+            text = contextMenuItemTagOpenFrameInNewWindow();
+            break;
 
-void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
-{
-    if (!mainFrame->d->eventHandler)
-        return;
+        case DownloadLinkToDisk:
+            text = contextMenuItemTagDownloadLinkToDisk();
+            break;
+        case CopyLinkToClipboard:
+            text = contextMenuItemTagCopyLinkToClipboard();
+            break;
 
-    bool handled = false;
-    QWebFrame *frame = mainFrame;
-    WebCore::Editor *editor = frame->d->frame->editor();
-    if (editor->canEdit()) {
-        if (ev == QKeySequence::Cut) {
-            q->triggerAction(QWebPage::Cut);
-            handled = true;
-        } else if (ev == QKeySequence::Copy) {
-            q->triggerAction(QWebPage::Copy);
-            handled = true;
-        } else if (ev == QKeySequence::Paste) {
-            q->triggerAction(QWebPage::Paste);
-            handled = true;
-        } else if (ev == QKeySequence::Undo) {
-            q->triggerAction(QWebPage::Undo);
-            handled = true;
-        } else if (ev == QKeySequence::Redo) {
-            q->triggerAction(QWebPage::Redo);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToNextChar) {
-            q->triggerAction(QWebPage::MoveToNextChar);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToPreviousChar) {
-            q->triggerAction(QWebPage::MoveToPreviousChar);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToNextWord) {
-            q->triggerAction(QWebPage::MoveToNextWord);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToPreviousWord) {
-            q->triggerAction(QWebPage::MoveToPreviousWord);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToNextLine) {
-            q->triggerAction(QWebPage::MoveToNextLine);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToPreviousLine) {
-            q->triggerAction(QWebPage::MoveToPreviousLine);
-            handled = true;
-//             } else if(ev == QKeySequence::MoveToNextPage) {
-//             } else if(ev == QKeySequence::MoveToPreviousPage) {
-        } else if(ev == QKeySequence::MoveToStartOfLine) {
-            q->triggerAction(QWebPage::MoveToStartOfLine);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToEndOfLine) {
-            q->triggerAction(QWebPage::MoveToEndOfLine);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToStartOfBlock) {
-            q->triggerAction(QWebPage::MoveToStartOfBlock);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToEndOfBlock) {
-            q->triggerAction(QWebPage::MoveToEndOfBlock);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToStartOfDocument) {
-            q->triggerAction(QWebPage::MoveToStartOfDocument);
-            handled = true;
-        } else if(ev == QKeySequence::MoveToEndOfDocument) {
-            q->triggerAction(QWebPage::MoveToEndOfDocument);
-            handled = true;
-        } else if(ev == QKeySequence::SelectNextChar) {
-            q->triggerAction(QWebPage::SelectNextChar);
-            handled = true;
-        } else if(ev == QKeySequence::SelectPreviousChar) {
-            q->triggerAction(QWebPage::SelectPreviousChar);
-            handled = true;
-        } else if(ev == QKeySequence::SelectNextWord) {
-            q->triggerAction(QWebPage::SelectNextWord);
-            handled = true;
-        } else if(ev == QKeySequence::SelectPreviousWord) {
-            q->triggerAction(QWebPage::SelectPreviousWord);
-            handled = true;
-        } else if(ev == QKeySequence::SelectNextLine) {
-            q->triggerAction(QWebPage::SelectNextLine);
-            handled = true;
-        } else if(ev == QKeySequence::SelectPreviousLine) {
-            q->triggerAction(QWebPage::SelectPreviousLine);
-            handled = true;
-//             } else if(ev == QKeySequence::SelectNextPage) {
-//             } else if(ev == QKeySequence::SelectPreviousPage) {
-        } else if(ev == QKeySequence::SelectStartOfLine) {
-            q->triggerAction(QWebPage::SelectStartOfLine);
-            handled = true;
-        } else if(ev == QKeySequence::SelectEndOfLine) {
-            q->triggerAction(QWebPage::SelectEndOfLine);
-            handled = true;
-        } else if(ev == QKeySequence::SelectStartOfBlock) {
-            q->triggerAction(QWebPage::SelectStartOfBlock);
-            handled = true;
-        } else if(ev == QKeySequence::SelectEndOfBlock) {
-            q->triggerAction(QWebPage::SelectEndOfBlock);
-            handled = true;
-        } else if(ev == QKeySequence::SelectStartOfDocument) {
-            q->triggerAction(QWebPage::SelectStartOfDocument);
-            handled = true;
-        } else if(ev == QKeySequence::SelectEndOfDocument) {
-            q->triggerAction(QWebPage::SelectEndOfDocument);
-            handled = true;
-        } else if(ev == QKeySequence::DeleteStartOfWord) {
-            q->triggerAction(QWebPage::DeleteStartOfWord);
-            handled = true;
-        } else if(ev == QKeySequence::DeleteEndOfWord) {
-            q->triggerAction(QWebPage::DeleteEndOfWord);
-            handled = true;
-//             } else if(ev == QKeySequence::DeleteEndOfLine) {
-        }
-    }
-    if (!handled) 
-        handled = frame->d->eventHandler->keyEvent(ev);
-    if (!handled) {
-        handled = true;
-        PlatformScrollbar *h, *v;
-        h = mainFrame->d->horizontalScrollBar();
-        v = mainFrame->d->verticalScrollBar();
+        case OpenImageInNewWindow:
+            text = contextMenuItemTagOpenImageInNewWindow();
+            break;
+        case DownloadImageToDisk:
+            text = contextMenuItemTagDownloadImageToDisk();
+            break;
+        case CopyImageToClipboard:
+            text = contextMenuItemTagCopyImageToClipboard();
+            break;
 
-        if (ev == QKeySequence::MoveToNextPage) {
-            if (v)
-                v->setValue(v->value() + q->viewportSize().height());
-        } else if (ev == QKeySequence::MoveToPreviousPage) {
-            if (v)
-                v->setValue(v->value() - q->viewportSize().height());
-        } else {
-            switch (ev->key()) {
-            case Qt::Key_Up:
-                if (v)
-                    v->setValue(v->value() - 10);
-                break;
-            case Qt::Key_Down:
-                if (v)
-                    v->setValue(v->value() + 10);
-                break;
-            case Qt::Key_Left:
-                if (h)
-                    h->setValue(h->value() - 10);
-                break;
-            case Qt::Key_Right:
-                if (h)
-                    h->setValue(h->value() + 10);
-                break;
-            default:
-                handled = false;
-                break;
-            }
+        case GoBack:
+            text = contextMenuItemTagGoBack();
+            break;
+        case GoForward:
+            text = contextMenuItemTagGoForward();
+            break;
+        case Stop:
+            text = contextMenuItemTagStop();
+            break;
+        case Reload:
+            text = contextMenuItemTagReload();
+            break;
+
+        case Cut:
+            text = contextMenuItemTagCut();
+            break;
+        case Copy:
+            text = contextMenuItemTagCopy();
+            break;
+        case Paste:
+            text = contextMenuItemTagPaste();
+            break;
+
+        case Undo: {
+            QAction *a = undoStack()->createUndoAction(d->q);
+            d->actions[action] = a;
+            return a;
         }
-    }
+        case Redo: {
+            QAction *a = undoStack()->createRedoAction(d->q);
+            d->actions[action] = a;
+            return a;
+        }
+        case MoveToNextChar:
+        case MoveToPreviousChar:
+        case MoveToNextWord:
+        case MoveToPreviousWord:
+        case MoveToNextLine:
+        case MoveToPreviousLine:
+        case MoveToStartOfLine:
+        case MoveToEndOfLine:
+        case MoveToStartOfBlock:
+        case MoveToEndOfBlock:
+        case MoveToStartOfDocument:
+        case MoveToEndOfDocument:
+        case SelectNextChar:
+        case SelectPreviousChar:
+        case SelectNextWord:
+        case SelectPreviousWord:
+        case SelectNextLine:
+        case SelectPreviousLine:
+        case SelectStartOfLine:
+        case SelectEndOfLine:
+        case SelectStartOfBlock:
+        case SelectEndOfBlock:
+        case SelectStartOfDocument:
+        case SelectEndOfDocument:
+        case DeleteStartOfWord:
+        case DeleteEndOfWord:
+            break; // ####
 
-    ev->setAccepted(handled);
-}
+        case SetTextDirectionDefault:
+            text = contextMenuItemTagDefaultDirection();
+            break;
+        case SetTextDirectionLeftToRight:
+            text = contextMenuItemTagLeftToRight();
+            checkable = true;
+            break;
+        case SetTextDirectionRightToLeft:
+            text = contextMenuItemTagRightToLeft();
+            checkable = true;
+            break;
 
-void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
-{
-    if (ev->isAutoRepeat()) {
-        ev->setAccepted(true);
-        return;
+        case ToggleBold:
+            text = contextMenuItemTagBold();
+            checkable = true;
+            break;
+        case ToggleItalic:
+            text = contextMenuItemTagItalic();
+            checkable = true;
+            break;
+        case ToggleUnderline:
+            text = contextMenuItemTagUnderline();
+            checkable = true;
+            break;
+
+        case InspectElement:
+            text = contextMenuItemTagInspectElement();
+            break;
+
+        case NoWebAction:
+            return 0;
     }
 
-    if (!mainFrame->d->eventHandler)
-        return;
+    if (text.isEmpty())
+        return 0;
 
-    bool handled = mainFrame->d->eventHandler->keyEvent(ev);
-    ev->setAccepted(handled);
-}
+    QAction *a = new QAction(d->q);
+    a->setText(text);
+    a->setData(action);
+    a->setCheckable(checkable);
 
-void QWebPagePrivate::focusInEvent(QFocusEvent *ev)
-{
-    if (ev->reason() != Qt::PopupFocusReason) 
-        mainFrame->d->frame->page()->focusController()->setFocusedFrame(mainFrame->d->frame);
-}
+    connect(a, SIGNAL(triggered(bool)),
+            this, SLOT(_q_webActionTriggered(bool)));
 
-void QWebPagePrivate::focusOutEvent(QFocusEvent *ev)
-{
-    if (ev->reason() != Qt::PopupFocusReason) {
-        mainFrame->d->frame->selectionController()->clear();
-        mainFrame->d->frame->setIsActive(false);
-    }
+    d->actions[action] = a;
+    d->updateAction(action);
+    return a;
 }
 
-bool QWebPage::focusNextPrevChild(bool next)
+/*!
+  Returns true if the page contains unsubmitted form data.
+*/
+bool QWebPage::isModified() const
 {
-    Q_UNUSED(next)
-    return false;
+    return d->modified;
 }
 
-void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev)
-{
-#ifndef QT_NO_DRAGANDDROP
-    DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
-                      dropActionToDragOp(ev->possibleActions()));
-    Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
-    ev->setDropAction(action);
-    ev->accept();
-#endif
-}
 
-void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev)
+QUndoStack *QWebPage::undoStack() const
 {
-#ifndef QT_NO_DRAGANDDROP
-    DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
-    page->dragController()->dragExited(&dragData);
-    ev->accept();
-#endif
+    if (!d->undoStack)
+        d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
+
+    return d->undoStack;
 }
 
-void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev)
+/*! \reimp
+*/
+bool QWebPage::event(QEvent *ev)
 {
-#ifndef QT_NO_DRAGANDDROP
-    DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
-                      dropActionToDragOp(ev->possibleActions()));
-    Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
-    ev->setDropAction(action);
-    ev->accept();
-#endif
+    switch (ev->type()) {
+    case QEvent::MouseMove:
+        d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
+        break;
+    case QEvent::MouseButtonPress:
+        d->mousePressEvent(static_cast<QMouseEvent*>(ev));
+        break;
+    case QEvent::MouseButtonDblClick:
+        d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
+        break;
+    case QEvent::MouseButtonRelease:
+        d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
+        break;
+    case QEvent::ContextMenu:
+        d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev));
+        break;
+    case QEvent::Wheel:
+        d->wheelEvent(static_cast<QWheelEvent*>(ev));
+        break;
+    case QEvent::KeyPress:
+        d->keyPressEvent(static_cast<QKeyEvent*>(ev));
+        break;
+    case QEvent::KeyRelease:
+        d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
+        break;
+    case QEvent::FocusIn:
+        d->focusInEvent(static_cast<QFocusEvent*>(ev));
+        break;
+    case QEvent::FocusOut:
+        d->focusOutEvent(static_cast<QFocusEvent*>(ev));
+        break;
+    case QEvent::DragEnter:
+        d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
+        break;
+    case QEvent::DragLeave:
+        d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
+        break;
+    case QEvent::DragMove:
+        d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
+        break;
+    case QEvent::Drop:
+        d->dropEvent(static_cast<QDropEvent*>(ev));
+        break;
+    default:
+        return QObject::event(ev);
+    }
+
+    return true;
 }
 
-void QWebPagePrivate::dropEvent(QDropEvent *ev)
+bool QWebPage::focusNextPrevChild(bool next)
 {
-#ifndef QT_NO_DRAGANDDROP
-    DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
-                      dropActionToDragOp(ev->possibleActions()));
-    Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData));
-    ev->accept();
-#endif
+    Q_UNUSED(next)
+    return false;
 }
 
 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)