+2007-07-09 Qing Zhao <qing@staikos.net>
+
+ Reviewed by George Staikos.
+
+ Add qt context menu support.
+
+ * WebCore.pro:
+ * platform/ContextMenu.h:
+ * platform/ContextMenuItem.h:
+ (WebCore::PlatformMenuItemDescriptionType::PlatformMenuItemDescriptionType):
+ * platform/qt/ContextMenuItemQt.cpp:
+ (WebCore::ContextMenuItem::ContextMenuItem):
+ (WebCore::ContextMenuItem::~ContextMenuItem):
+ (WebCore::ContextMenuItem::releasePlatformDescription):
+ (WebCore::ContextMenuItem::type):
+ (WebCore::ContextMenuItem::setType):
+ (WebCore::ContextMenuItem::action):
+ (WebCore::ContextMenuItem::setAction):
+ (WebCore::ContextMenuItem::title):
+ (WebCore::ContextMenuItem::setTitle):
+ (WebCore::ContextMenuItem::platformSubMenu):
+ (WebCore::ContextMenuItem::setSubMenu):
+ (WebCore::ContextMenuItem::setChecked):
+ (WebCore::ContextMenuItem::setEnabled):
+ (WebCore::ContextMenuItem::enabled):
+ * platform/qt/ContextMenuQt.cpp:
+ (WebCore::ContextMenu::ContextMenu):
+ (WebCore::ContextMenu::~ContextMenu):
+ (WebCore::ContextMenu::appendItem):
+ (WebCore::ContextMenu::itemCount):
+ (WebCore::ContextMenu::insertItem):
+ (WebCore::ContextMenu::setPlatformDescription):
+ (WebCore::ContextMenu::platformDescription):
+
2007-07-09 Anders Carlsson <andersca@apple.com>
Build fix.
qt-port:HEADERS += \
$$PWD/platform/qt/QWebPopup.h \
+ $$PWD/platform/qt/MenuEventProxy.h \
$$PWD/platform/qt/SharedTimerQt.h \
$$PWD/../WebKitQt/Api/qwebframe.h \
$$PWD/../WebKitQt/Api/qwebpage.h \
#include <wtf/RetainPtr.h>
#elif PLATFORM(QT)
#include <QMenu>
-typedef QMenu* PlatformMenuDescription;
#endif
namespace WebCore {
+class MenuEventProxy;
class ContextMenuController;
RetainPtr<NSMutableArray> m_platformDescription;
#elif PLATFORM(QT)
QMenu *m_menu;
+ MenuEventProxy *m_proxy;
#else
PlatformMenuDescription m_platformDescription;
#endif
typedef struct tagMENUITEMINFOW* LPMENUITEMINFO;
#elif PLATFORM(GDK)
typedef struct _GtkMenuItem GtkMenuItem;
+#elif PLATFORM(QT)
+#include <QAction>
#endif
namespace WebCore {
class ContextMenu;
-#if PLATFORM(MAC)
- typedef NSMenuItem* PlatformMenuItemDescription;
-#elif PLATFORM(WIN)
- typedef LPMENUITEMINFO PlatformMenuItemDescription;
-#elif PLATFORM(QT)
- typedef void* PlatformMenuItemDescription;
-#elif PLATFORM(GDK)
- typedef GtkMenuItem* PlatformMenuItemDescription;
-#endif
-
// This enum needs to be in sync with the WebMenuItemTag enum in WebUIDelegate.h and the
// extra values in WebUIDelegatePrivate.h
enum ContextMenuAction {
SubmenuType
};
+#if PLATFORM(MAC)
+ typedef NSMenuItem* PlatformMenuItemDescription;
+#elif PLATFORM(WIN)
+ typedef LPMENUITEMINFO PlatformMenuItemDescription;
+#elif PLATFORM(QT)
+ struct PlatformMenuItemDescriptionType {
+ PlatformMenuItemDescriptionType() : qaction(0), menu(0), action(ContextMenuItemTagNoAction), type(ActionType), subMenu(0) {}
+ QAction *qaction;
+ QMenu *menu;
+ ContextMenuAction action;
+ QString title;
+ ContextMenuItemType type;
+ PlatformMenuDescription subMenu;
+ };
+ typedef PlatformMenuItemDescriptionType* PlatformMenuItemDescription;
+#elif PLATFORM(GDK)
+ typedef GtkMenuItem* PlatformMenuItemDescription;
+#endif
+
class ContextMenuItem {
public:
ContextMenuItem(PlatformMenuItemDescription);
/*
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "config.h"
#include "ContextMenuItem.h"
-
#include "ContextMenu.h"
namespace WebCore {
ContextMenuItem::ContextMenuItem(ContextMenu* subMenu)
{
+ m_platformDescription = new PlatformMenuItemDescriptionType;
}
ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action,
const String& title, ContextMenu* subMenu)
{
+ m_platformDescription = new PlatformMenuItemDescriptionType;
+ m_platformDescription->type = type;
+ m_platformDescription->action = action;
+ m_platformDescription->title = title;
}
ContextMenuItem::~ContextMenuItem()
{
+ delete m_platformDescription;
}
PlatformMenuItemDescription ContextMenuItem::releasePlatformDescription()
{
- return PlatformMenuItemDescription();
+ return m_platformDescription;
}
ContextMenuItemType ContextMenuItem::type() const
{
- return ActionType;
+ return m_platformDescription->type;
}
-void ContextMenuItem::setType(ContextMenuItemType)
+void ContextMenuItem::setType(ContextMenuItemType type)
{
+ m_platformDescription->type = type;
}
ContextMenuAction ContextMenuItem::action() const
{
- return ContextMenuAction();
+ return m_platformDescription->action;
}
void ContextMenuItem::setAction(ContextMenuAction action)
{
+ m_platformDescription->action = action;
}
String ContextMenuItem::title() const
{
- return String();
+ return m_platformDescription->title;
}
void ContextMenuItem::setTitle(const String& title)
{
+#ifndef QT_NO_MENU
+ m_platformDescription->title = title;
+ if (m_platformDescription->qaction)
+ m_platformDescription->qaction->setText(title);
+#endif
}
PlatformMenuDescription ContextMenuItem::platformSubMenu() const
{
- return PlatformMenuDescription();
+ return m_platformDescription->subMenu;
}
void ContextMenuItem::setSubMenu(ContextMenu* menu)
{
+#ifndef QT_NO_MENU
+ m_platformDescription->subMenu = menu->platformDescription();
+#endif
}
-void ContextMenuItem::setChecked(bool)
+void ContextMenuItem::setChecked(bool on)
{
+#ifndef QT_NO_MENU
+ if (m_platformDescription->qaction) {
+ m_platformDescription->qaction->setCheckable(true);
+ m_platformDescription->qaction->setChecked(on);
+ }
+#endif
}
-void ContextMenuItem::setEnabled(bool)
+void ContextMenuItem::setEnabled(bool on)
{
+#ifndef QT_NO_MENU
+ if (m_platformDescription->qaction)
+ m_platformDescription->qaction->setEnabled(on);
+#endif
}
bool ContextMenuItem::enabled() const
{
- return true;
+#ifndef QT_NO_MENU
+ if (m_platformDescription->qaction)
+ return m_platformDescription->qaction->isEnabled();
+#endif
+ return false;
}
}
+// vim: ts=4 sw=4 et
/*
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "config.h"
#include "ContextMenu.h"
+#include "MenuEventProxy.h"
#include <wtf/Assertions.h>
-#include <QMenu>
#include <QAction>
+#include <qwebframe.h>
+#include <qwebpage.h>
+#include <FrameLoaderClientQt.h>
+#include <Document.h>
+#include <Frame.h>
+#include <FrameLoader.h>
+#include <FrameLoaderClient.h>
+
namespace WebCore {
ContextMenu::ContextMenu(const HitTestResult& result)
- : m_hitTestResult(result), m_menu(0)
+ : m_hitTestResult(result)
{
+#ifndef QT_NO_MENU
+ m_menu = new QMenu;
+ //qDebug("Create menu(%p) %p", this, (QMenu*)m_menu);
+ m_proxy = new MenuEventProxy(this);
+#endif
}
ContextMenu::~ContextMenu()
{
+#ifndef QT_NO_MENU
+ //qDebug("Destroy menu(%p) %p", this, (QMenu*)m_menu);
+ delete m_menu;
+ m_menu = 0;
+ delete m_proxy;
+ m_proxy = 0;
+#endif
}
void ContextMenu::appendItem(ContextMenuItem& item)
{
- if (!m_menu)
- m_menu = new QMenu();
-
- QAction* action = m_menu->addAction(item.title());
+ insertItem(999999, item); // yuck! Fix this API!!
}
unsigned ContextMenu::itemCount() const
{
- // FIXME: This method is silly
- return 1;
+#ifndef QT_NO_MENU
+ return m_menu->actions().count();
+#else
+ return 0;
+#endif
}
void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
{
- // FIXME: Another silly method
- appendItem(item);
+#ifndef QT_NO_MENU
+ int id;
+ QAction *action;
+ QAction *before = 0;
+ int p = position;
+ if (p == 999999)
+ p = -1;
+ if (p >= 0)
+ before = m_menu->actions()[p];
+
+ switch (item.type()) {
+ case ActionType:
+ if (!item.title().isEmpty()) {
+ action = m_menu->addAction((QString)item.title());
+ m_menu->removeAction(action);
+ m_menu->insertAction(before, action);
+ QObject::connect(m_menu, SIGNAL(triggered(QAction *)), m_proxy, SLOT(trigger(QAction *)));
+ }
+ break;
+ case SeparatorType:
+ action = m_menu->insertSeparator(before);
+ break;
+ case SubmenuType:
+ if (!item.title().isEmpty()) {
+ QMenu *m = item.platformSubMenu();
+ if (!m)
+ return;
+ action = m_menu->insertMenu(before, m);
+ action->setText(item.title());
+ }
+ break;
+ default:
+ return;
+ }
+ if (action) {
+ m_proxy->map(action, item.action());
+ item.releasePlatformDescription()->qaction = action;
+ }
+#endif
}
void ContextMenu::setPlatformDescription(PlatformMenuDescription menu)
{
- delete m_menu;
- m_menu = static_cast<QMenu*>(menu);
+#ifndef QT_NO_MENU
+ //qDebug("Switch menu(%p) %p to %p", this, (QMenu*)m_menu, menu);
+ if (menu == 0) {
+ FrameLoaderClient *f = m_hitTestResult.innerNode()->document()->frame()->loader()->client();
+ QWidget *page = static_cast<FrameLoaderClientQt*>(f)->webFrame()->page();
+ m_menu->exec(page->mapToGlobal(m_hitTestResult.point()));
+ }
+ if (menu != m_menu) {
+ delete m_menu;
+ m_menu = menu;
+ }
+#endif
}
+PlatformMenuDescription ContextMenu::platformDescription() const
+{
+ return m_menu;
+}
+
+
}
+// vim: ts=4 sw=4 et
--- /dev/null
+/*
+ * Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef MENUEVENTPROXY_H
+#define MENUEVENTPROXY_H
+
+#include "Platform.h"
+#include <qobject.h>
+#include <qmap.h>
+#include "ContextMenu.h"
+#include "ContextMenuItem.h"
+#include "ContextMenuController.h"
+
+namespace WebCore {
+class MenuEventProxy : public QObject {
+ Q_OBJECT
+ public:
+ MenuEventProxy(WebCore::ContextMenu *m) : m_m(m) {}
+ ~MenuEventProxy() {}
+
+ void map(QAction* action, unsigned actionTag) { _map[action] = actionTag; }
+
+ public slots:
+ void trigger(QAction *action) {
+ WebCore::ContextMenuItem item(WebCore::ActionType, static_cast<WebCore::ContextMenuAction>(_map[action]), WebCore::String());
+ m_m->controller()->contextMenuItemSelected(&item);
+ }
+
+ private:
+ WebCore::ContextMenu *m_m;
+ QMap<QAction*, unsigned> _map;
+};
+
+}
+
+#endif
+// vim: ts=4 sw=4 et