Home | History | Annotate | Download | only in qt
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     24  * THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "WebContextMenuProxyQt.h"
     29 
     30 #include <IntPoint.h>
     31 #include <OwnPtr.h>
     32 #include <WebContextMenuItemData.h>
     33 #include <qmenu.h>
     34 #include <qwkpage.h>
     35 
     36 using namespace WebCore;
     37 
     38 namespace WebKit {
     39 
     40 static QWKPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
     41 {
     42     switch (action) {
     43     case WebCore::ContextMenuItemTagOpenLink:
     44         return QWKPage::OpenLink;
     45     case WebCore::ContextMenuItemTagOpenLinkInNewWindow:
     46         return QWKPage::OpenLinkInNewWindow;
     47     case WebCore::ContextMenuItemTagCopyLinkToClipboard:
     48         return QWKPage::CopyLinkToClipboard;
     49     case WebCore::ContextMenuItemTagOpenImageInNewWindow:
     50         return QWKPage::OpenImageInNewWindow;
     51     case WebCore::ContextMenuItemTagGoBack:
     52         return QWKPage::Back;
     53     case WebCore::ContextMenuItemTagGoForward:
     54         return QWKPage::Forward;
     55     case WebCore::ContextMenuItemTagStop:
     56         return QWKPage::Stop;
     57     case WebCore::ContextMenuItemTagReload:
     58         return QWKPage::Reload;
     59     case WebCore::ContextMenuItemTagCut:
     60         return QWKPage::Cut;
     61     case WebCore::ContextMenuItemTagCopy:
     62         return QWKPage::Copy;
     63     case WebCore::ContextMenuItemTagPaste:
     64         return QWKPage::Paste;
     65     case WebCore::ContextMenuItemTagSelectAll:
     66         return QWKPage::SelectAll;
     67     default:
     68         break;
     69     }
     70     return QWKPage::NoWebAction;
     71 }
     72 
     73 WebContextMenuProxyQt::WebContextMenuProxyQt(QWKPage* page)
     74     : m_page(page)
     75 {
     76 }
     77 
     78 PassRefPtr<WebContextMenuProxyQt> WebContextMenuProxyQt::create(QWKPage* page)
     79 {
     80     return adoptRef(new WebContextMenuProxyQt(page));
     81 }
     82 
     83 void WebContextMenuProxyQt::showContextMenu(const IntPoint& position, const Vector<WebContextMenuItemData>& items)
     84 {
     85     if (items.isEmpty())
     86         return;
     87 
     88     OwnPtr<QMenu> menu = createContextMenu(items);
     89 
     90     // We send the signal, even with no items, because the client should be able to show custom items
     91     // even if WebKit has nothing to show.
     92     if (!menu)
     93         menu = adoptPtr(new QMenu);
     94 
     95     menu->move(position);
     96     emit m_page->showContextMenu(QSharedPointer<QMenu>(menu.leakPtr()));
     97 }
     98 
     99 void WebContextMenuProxyQt::hideContextMenu()
    100 {
    101 }
    102 
    103 PassOwnPtr<QMenu> WebContextMenuProxyQt::createContextMenu(const Vector<WebContextMenuItemData>& items) const
    104 {
    105     OwnPtr<QMenu> menu = adoptPtr(new QMenu);
    106     for (int i = 0; i < items.size(); ++i) {
    107         const WebContextMenuItemData& item = items.at(i);
    108         switch (item.type()) {
    109         case WebCore::CheckableActionType: /* fall through */
    110         case WebCore::ActionType: {
    111             QWKPage::WebAction action = webActionForContextMenuAction(item.action());
    112             QAction* qtAction = m_page->action(action);
    113             if (qtAction) {
    114                 qtAction->setEnabled(item.enabled());
    115                 qtAction->setChecked(item.checked());
    116                 qtAction->setCheckable(item.type() == WebCore::CheckableActionType);
    117 
    118                 menu->addAction(qtAction);
    119             }
    120             break;
    121         }
    122         case WebCore::SeparatorType:
    123             menu->addSeparator();
    124             break;
    125         case WebCore::SubmenuType:
    126             if (OwnPtr<QMenu> subMenu = createContextMenu(item.submenu())) {
    127                 subMenu->setParent(menu.get());
    128                 QMenu* const subMenuPtr = subMenu.leakPtr();
    129                 subMenu->setTitle(item.title());
    130                 menu->addMenu(subMenuPtr);
    131             }
    132 
    133             break;
    134         }
    135     }
    136 
    137     // Do not show sub-menus with just disabled actions.
    138     if (menu->isEmpty())
    139         return PassOwnPtr<QMenu>();
    140 
    141     bool isAnyActionEnabled = false;
    142     QList<QAction *> actions = menu->actions();
    143     for (int i = 0; i < actions.count(); ++i) {
    144         if (actions.at(i)->isVisible())
    145             isAnyActionEnabled |= actions.at(i)->isEnabled();
    146     }
    147     if (!isAnyActionEnabled)
    148         return PassOwnPtr<QMenu>();
    149 
    150     return menu.release();
    151 }
    152 
    153 } // namespace WebKit
    154