Store a bunch of QActions in QWebPagePrivate, corresponding to QWebPage::WebAction.
authorhausmann <hausmann@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2007 14:29:37 +0000 (14:29 +0000)
committerhausmann <hausmann@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2007 14:29:37 +0000 (14:29 +0000)
Added QWebPageContext to hold context sensitive information (for example used by the context menu).

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@27536 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/qt/Api/qwebpage.cpp
WebKit/qt/Api/qwebpage.h
WebKit/qt/Api/qwebpage_p.h
WebKit/qt/ChangeLog

index 6ce21df5e1f7c86808e5fabe4577355b74fa3ddb..f77f741e316326e1013da2ce7198aaf5eb3b5703 100644 (file)
@@ -53,6 +53,7 @@
 #include "PlatformWheelEvent.h"
 #include "ProgressTracker.h"
 #include "HitTestResult.h"
+#include "LocalizedStrings.h"
 
 #include <QDebug>
 #include <QDragEnterEvent>
@@ -88,6 +89,7 @@ QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
     insideOpenCall = false;
 
     history.d = new QWebPageHistoryPrivate(page->backForwardList());
+    memset(actions, 0, sizeof(actions));
 }
 
 QWebPagePrivate::~QWebPagePrivate()
@@ -124,15 +126,41 @@ void QWebPagePrivate::createMainFrame()
     }
 }
 
+static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
+{
+    switch (action) {
+        case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
+        case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
+        case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
+        case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
+        case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
+        case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
+        case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
+        case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
+        case WebCore::ContextMenuItemTagGoBack: return QWebPage::GoBack;
+        case WebCore::ContextMenuItemTagGoForward: return QWebPage::GoForward;
+        case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
+        case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
+        case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
+        case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
+        default: break;
+    }
+    return QWebPage::NoWebAction;
+}
+
 QMenu *QWebPagePrivate::createContextMenu(QList<WebCore::ContextMenuItem> *items)
 {
     QMenu *menu = new QMenu;
     for (int i = 0; i < items->count(); ++i) {
         const ContextMenuItem &item = items->at(i);
         switch (item.type()) {
-            case WebCore::ActionType:
-                menu->addAction(item.title());
+            case WebCore::ActionType: {
+                QWebPage::WebAction action = webActionForContextMenuAction(item.action());
+                QAction *a = q->webAction(action);
+                if (a)
+                    menu->addAction(a);
                 break;
+            }
             case WebCore::SeparatorType:
                 menu->addSeparator();
                 break;
@@ -164,6 +192,15 @@ redo:
     return 0;
 }
 
+void QWebPagePrivate::_q_webActionTriggered(bool checked)
+{
+    QAction *a = qobject_cast<QAction *>(q->sender());
+    if (!a)
+        return;
+    QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
+    q->webActionTriggered(action, checked);
+}
+
 QWebPage::QWebPage(QWidget *parent)
     : QWidget(parent)
     , d(new QWebPagePrivate(this))
@@ -321,11 +358,13 @@ void QWebPage::webActionTriggered(WebAction action, bool checked)
     const char *command = 0;
 
     switch (action) {
-        // ### these need a context...
         case OpenLinkInNewWindow:
+            break;
         case OpenFrameInNewWindow:
         case DownloadLinkToDisk:
         case CopyLinkToClipboard:
+            editor->copyURL(WebCore::KURL(d->currentContext.linkUrl().toString()), d->currentContext.text());
+            break;
         case OpenImageInNewWindow:
         case DownloadImageToDisk:
         case CopyImageToClipboard:
@@ -486,6 +525,114 @@ void QWebPage::paste()
     webActionTriggered(Paste);
 }
 
+QAction *QWebPage::webAction(WebAction action) const
+{
+    if (action == QWebPage::NoWebAction) return 0;
+    if (d->actions[action])
+        return d->actions[action];
+
+    QString text;
+
+    switch (action) {
+        case OpenLinkInNewWindow:
+            text = contextMenuItemTagOpenLinkInNewWindow();
+            break;
+        case OpenFrameInNewWindow:
+            text = contextMenuItemTagOpenFrameInNewWindow();
+            break;
+
+        case DownloadLinkToDisk:
+            text = contextMenuItemTagDownloadLinkToDisk();
+            break;
+        case CopyLinkToClipboard:
+            text = contextMenuItemTagCopyLinkToClipboard();
+            break;
+
+        case OpenImageInNewWindow:
+            text = contextMenuItemTagOpenImageInNewWindow();
+            break;
+        case DownloadImageToDisk:
+            text = contextMenuItemTagDownloadImageToDisk();
+            break;
+        case CopyImageToClipboard:
+            text = contextMenuItemTagCopyImageToClipboard();
+            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:
+            text = tr("Undo");
+            break;
+        case Redo:
+            text = tr("Redo");
+            break;
+        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; // ####
+
+        case NoWebAction:
+            return 0;
+    }
+
+    if (text.isEmpty())
+        return 0;
+
+    QAction *a = new QAction(d->q);
+    a->setText(text);
+    a->setData(action);
+
+    connect(a, SIGNAL(triggered(bool)),
+            this, SLOT(_q_webActionTriggered(bool)));
+
+    d->actions[action] = a;
+    return a;
+}
+
 /*!
   Returns true if the page contains unsubmitted form data.
 */
@@ -627,12 +774,16 @@ void QWebPage::contextMenuEvent(QContextMenuEvent *ev)
     frame->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
     ContextMenu *menu = d->page->contextMenuController()->contextMenu();
 
+    QWebPageContext oldContext = d->currentContext;
+    d->currentContext = QWebPageContext(menu->hitTestResult());
+
     QList<ContextMenuItem> *items = menu->platformDescription();
     QMenu *qmenu = d->createContextMenu(items);
     if (qmenu) {
         qmenu->exec(ev->globalPos());
         delete qmenu;
     }
+    d->currentContext = oldContext;
 }
 
 void QWebPage::wheelEvent(QWheelEvent *ev)
@@ -1040,4 +1191,96 @@ quint64 QWebPage::bytesReceived() const {
     return d->m_totalBytes;
 }
 
+QWebPageContext::QWebPageContext(const WebCore::HitTestResult &hitTest)
+    : d(new QWebPageContextPrivate)
+{
+    d->pos = hitTest.point();
+    d->text = hitTest.textContent();
+    d->linkUrl = hitTest.absoluteLinkURL().url();
+    d->imageUrl = hitTest.absoluteImageURL().url();
+    WebCore::Image *img = hitTest.image();
+    if (img) {
+        QPixmap *pix = img->getPixmap();
+        if (pix)
+            d->image = *pix;
+    }
+    WebCore::Frame *frame = hitTest.targetFrame();
+    if (frame)
+        d->targetFrame = frame->view()->qwebframe();
+}
+
+QWebPageContext::QWebPageContext()
+    : d(0)
+{
+}
+
+QWebPageContext::QWebPageContext(const QWebPageContext &other)
+    : d(0)
+{
+    if (other.d)
+        d = new QWebPageContextPrivate(*other.d);
+}
+
+QWebPageContext &QWebPageContext::operator=(const QWebPageContext &other)
+{
+    if (this != &other) {
+        if (other.d) {
+            if (!d)
+                d = new QWebPageContextPrivate;
+            *d = *other.d;
+        } else {
+            delete d;
+            d = 0;
+        }
+    }
+    return *this;
+}
+
+QWebPageContext::~QWebPageContext()
+{
+    delete d;
+}
+
+QPoint QWebPageContext::pos() const
+{
+    if (!d)
+        return QPoint();
+    return d->pos;
+}
+
+QString QWebPageContext::text() const
+{
+    if (!d)
+        return QString();
+    return d->text;
+}
+
+QUrl QWebPageContext::linkUrl() const
+{
+    if (!d)
+        return QUrl();
+    return d->linkUrl;
+}
+
+QUrl QWebPageContext::imageUrl() const
+{
+    if (!d)
+        return QUrl();
+    return d->linkUrl;
+}
+
+QPixmap QWebPageContext::image() const
+{
+    if (!d)
+        return QPixmap();
+    return d->image;
+}
+
+QWebFrame *QWebPageContext::targetFrame() const
+{
+    if (!d)
+        return 0;
+    return d->targetFrame;
+}
+
 #include "moc_qwebpage.cpp"
index bc55b62ca10976e580c43a49fcc6fff5deeda3ad..28559f851b0b87a5fcb4f3ff7915dc7dd48117a4 100644 (file)
@@ -45,6 +45,7 @@ namespace WebCore {
     class FrameLoadRequest;
     class EditorClientQt;
     class ResourceHandle;
+    class HitTestResult;
 }
 
 class QWEBKIT_EXPORT QWebPage : public QWidget
@@ -182,6 +183,8 @@ public slots:
     void paste();
     // ### should we have execCommand() or something similar?
 
+    QAction *webAction(WebAction action) const;
+
 signals:
     /**
      * Signal is emitted when load is started on one of the child
@@ -273,6 +276,7 @@ protected:
 
 private:
     Q_PRIVATE_SLOT(d, void _q_onLoadProgressChanged(int))
+    Q_PRIVATE_SLOT(d, void _q_webActionTriggered(bool checked));
     friend class QWebFrame;
     friend class QWebPagePrivate;
     friend class WebCore::ChromeClientQt;
index 368a2332107a917d1093157d2eec5ca9ddd94943..33d2a38d4c6945412fa36562a9eb5f07d374268c 100644 (file)
@@ -40,6 +40,41 @@ namespace WebCore
 class QUndoStack;
 class QMenu;
 
+class QWebPageContextPrivate
+{
+public:
+    QPoint pos;
+    QString text;
+    QUrl linkUrl;
+    QUrl imageUrl;
+    QPixmap image;
+    QPointer<QWebFrame> targetFrame;
+};
+
+class QWebPageContext
+{
+public:
+    QWebPageContext();
+    QWebPageContext(const QWebPageContext &other);
+    QWebPageContext &operator=(const QWebPageContext &other);
+    ~QWebPageContext();
+
+    QPoint pos() const;
+    QString text() const;
+    QUrl linkUrl() const;
+    QUrl imageUrl() const;
+    // ### we have a pixmap internally, should this be called pixmap() instead?
+    QPixmap image() const;
+
+    QWebFrame *targetFrame() const;
+
+private:
+    QWebPageContext(const WebCore::HitTestResult &hitTest);
+    QWebPageContextPrivate *d;
+
+    friend class QWebPage;
+};
+
 class QWebPagePrivate
 {
 public:
@@ -51,6 +86,7 @@ public:
     QWebFrame *frameAt(const QPoint &pos) const;
 
     void _q_onLoadProgressChanged(int);
+    void _q_webActionTriggered(bool checked);
 
     WebCore::ChromeClientQt *chromeClient;
     WebCore::ContextMenuClientQt *contextMenuClient;
@@ -80,6 +116,9 @@ public:
 #endif
 
     QWebPageHistory history;
+    QWebPageContext currentContext;
+
+    QAction *actions[QWebPage::NumWebActions];
 };
 
 #endif
index 92ba58cab06475a14da9513da886c94ebcc7eed8..e8dd18d03a01ab220c3f035e81d90ad7f268899a 100644 (file)
@@ -1,3 +1,30 @@
+2007-11-07  Simon Hausmann  <hausmann@kde.org>
+
+        Reviewed by Lars.
+
+        Store a bunch of QActions in QWebPagePrivate, corresponding to QWebPage::WebAction.
+        Added QWebPageContext to hold context sensitive information (for example used by the context menu).
+
+        * Api/qwebpage.cpp:
+        (QWebPagePrivate::QWebPagePrivate):
+        (webActionForContextMenuAction):
+        (QWebPagePrivate::createContextMenu):
+        (QWebPagePrivate::_q_webActionTriggered):
+        (QWebPage::webActionTriggered):
+        (QWebPage::webAction):
+        (QWebPage::contextMenuEvent):
+        (QWebPageContext::QWebPageContext):
+        (QWebPageContext::operator=):
+        (QWebPageContext::~QWebPageContext):
+        (QWebPageContext::pos):
+        (QWebPageContext::text):
+        (QWebPageContext::linkUrl):
+        (QWebPageContext::imageUrl):
+        (QWebPageContext::image):
+        (QWebPageContext::targetFrame):
+        * Api/qwebpage.h:
+        * Api/qwebpage_p.h:
+
 2007-11-07  Simon Hausmann  <hausmann@kde.org>
 
         Reviewed by Lars.