[Qt][WK2] Add support for multi-select list
authorpierre.rossi@gmail.com <pierre.rossi@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Jul 2012 14:38:01 +0000 (14:38 +0000)
committerpierre.rossi@gmail.com <pierre.rossi@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Jul 2012 14:38:01 +0000 (14:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85527

Patch by Dinu Jacob <dinu.jacob@nokia.com> on 2012-06-01
Reviewed by Kenneth Rohde Christiansen.

Added support for multi-select list:
- Added multi-selection flag to PlatformPopupMenuData to indicate whether to accept multiple selections or not.
- Added selected state to WebPopupItem.
- Modified WebPopupMenuQt to support multiple selections.

* Shared/PlatformPopupMenuData.cpp:
(WebKit::PlatformPopupMenuData::PlatformPopupMenuData):
(WebKit::PlatformPopupMenuData::encode):
(WebKit::PlatformPopupMenuData::decode):
* Shared/PlatformPopupMenuData.h:
(PlatformPopupMenuData):
* Shared/WebPopupItem.cpp:
(WebKit::WebPopupItem::WebPopupItem):
(WebKit::WebPopupItem::encode):
(WebKit::WebPopupItem::decode):
* Shared/WebPopupItem.h:
* UIProcess/API/qt/tests/qmltests/WebView/tst_multiSelect.qml: Added.
* UIProcess/API/qt/tests/qmltests/common/multiselect.html: Added.
* UIProcess/WebPageProxy.h:
(WebPageProxy):
* UIProcess/WebPopupMenuProxy.h:
(Client):
* UIProcess/qt/WebPageProxyQt.cpp:
(WebKit::WebPageProxy::changeSelectedIndex):
(WebKit):
(WebKit::WebPageProxy::closePopupMenu):
* UIProcess/qt/WebPopupMenuProxyQt.cpp:
(WebKit::PopupMenuItemModel::multiple):
(PopupMenuItemModel):
(WebKit::PopupMenuItemModel::Item::Item):
(ItemSelectorContextObject):
(WebKit::ItemSelectorContextObject::allowMultiSelect):
(WebKit::ItemSelectorContextObject::reject):
(WebKit::ItemSelectorContextObject::dismiss):
(WebKit::ItemSelectorContextObject::ItemSelectorContextObject):
(WebKit):
(WebKit::ItemSelectorContextObject::onIndexUpdate):
(WebKit::ItemSelectorContextObject::accept):
(WebKit::PopupMenuItemModel::PopupMenuItemModel):
(WebKit::PopupMenuItemModel::select):
(WebKit::PopupMenuItemModel::toggleItem):
(WebKit::PopupMenuItemModel::buildItems):
(WebKit::WebPopupMenuProxyQt::showPopupMenu):
(WebKit::WebPopupMenuProxyQt::hidePopupMenu):
(WebKit::WebPopupMenuProxyQt::selectIndex):
(WebKit::WebPopupMenuProxyQt::createItem):
* UIProcess/qt/WebPopupMenuProxyQt.h:
(WebPopupMenuProxyQt):
* WebProcess/WebCoreSupport/WebPopupMenu.cpp:
(WebKit::WebPopupMenu::didChangeSelectedIndex):
(WebKit::WebPopupMenu::populateItems):
* WebProcess/WebCoreSupport/WebPopupMenu.h:
(WebPopupMenu):
* WebProcess/WebCoreSupport/qt/WebPopupMenuQt.cpp:
(WebKit::WebPopupMenu::setUpPlatformData):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didChangeSelectedIndexForActivePopupMenu):
(WebKit):
(WebKit::WebPage::changeSelectedIndex):
* WebProcess/WebPage/WebPage.h:
(WebPage):
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/qt/WebPageQt.cpp:
(WebKit::WebPage::selectedIndex):
(WebKit):
(WebKit::WebPage::hidePopupMenu):

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

17 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/PlatformPopupMenuData.cpp
Source/WebKit2/Shared/PlatformPopupMenuData.h
Source/WebKit2/Shared/WebPopupItem.cpp
Source/WebKit2/Shared/WebPopupItem.h
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPopupMenuProxy.h
Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp
Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.h
Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h
Source/WebKit2/WebProcess/WebCoreSupport/qt/WebPopupMenuQt.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp

index e92e4af..c15fc61 100644 (file)
@@ -1,3 +1,77 @@
+2012-06-01  Dinu Jacob  <dinu.jacob@nokia.com>
+
+        [Qt][WK2] Add support for multi-select list
+        https://bugs.webkit.org/show_bug.cgi?id=85527
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Added support for multi-select list:
+        - Added multi-selection flag to PlatformPopupMenuData to indicate whether to accept multiple selections or not.
+        - Added selected state to WebPopupItem.
+        - Modified WebPopupMenuQt to support multiple selections.
+
+        * Shared/PlatformPopupMenuData.cpp:
+        (WebKit::PlatformPopupMenuData::PlatformPopupMenuData):
+        (WebKit::PlatformPopupMenuData::encode):
+        (WebKit::PlatformPopupMenuData::decode):
+        * Shared/PlatformPopupMenuData.h:
+        (PlatformPopupMenuData):
+        * Shared/WebPopupItem.cpp:
+        (WebKit::WebPopupItem::WebPopupItem):
+        (WebKit::WebPopupItem::encode):
+        (WebKit::WebPopupItem::decode):
+        * Shared/WebPopupItem.h:
+        * UIProcess/API/qt/tests/qmltests/WebView/tst_multiSelect.qml: Added.
+        * UIProcess/API/qt/tests/qmltests/common/multiselect.html: Added.
+        * UIProcess/WebPageProxy.h:
+        (WebPageProxy):
+        * UIProcess/WebPopupMenuProxy.h:
+        (Client):
+        * UIProcess/qt/WebPageProxyQt.cpp:
+        (WebKit::WebPageProxy::changeSelectedIndex):
+        (WebKit):
+        (WebKit::WebPageProxy::closePopupMenu):
+        * UIProcess/qt/WebPopupMenuProxyQt.cpp:
+        (WebKit::PopupMenuItemModel::multiple):
+        (PopupMenuItemModel):
+        (WebKit::PopupMenuItemModel::Item::Item):
+        (ItemSelectorContextObject):
+        (WebKit::ItemSelectorContextObject::allowMultiSelect):
+        (WebKit::ItemSelectorContextObject::reject):
+        (WebKit::ItemSelectorContextObject::dismiss):
+        (WebKit::ItemSelectorContextObject::ItemSelectorContextObject):
+        (WebKit):
+        (WebKit::ItemSelectorContextObject::onIndexUpdate):
+        (WebKit::ItemSelectorContextObject::accept):
+        (WebKit::PopupMenuItemModel::PopupMenuItemModel):
+        (WebKit::PopupMenuItemModel::select):
+        (WebKit::PopupMenuItemModel::toggleItem):
+        (WebKit::PopupMenuItemModel::buildItems):
+        (WebKit::WebPopupMenuProxyQt::showPopupMenu):
+        (WebKit::WebPopupMenuProxyQt::hidePopupMenu):
+        (WebKit::WebPopupMenuProxyQt::selectIndex):
+        (WebKit::WebPopupMenuProxyQt::createItem):
+        * UIProcess/qt/WebPopupMenuProxyQt.h:
+        (WebPopupMenuProxyQt):
+        * WebProcess/WebCoreSupport/WebPopupMenu.cpp:
+        (WebKit::WebPopupMenu::didChangeSelectedIndex):
+        (WebKit::WebPopupMenu::populateItems):
+        * WebProcess/WebCoreSupport/WebPopupMenu.h:
+        (WebPopupMenu):
+        * WebProcess/WebCoreSupport/qt/WebPopupMenuQt.cpp:
+        (WebKit::WebPopupMenu::setUpPlatformData):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::didChangeSelectedIndexForActivePopupMenu):
+        (WebKit):
+        (WebKit::WebPage::changeSelectedIndex):
+        * WebProcess/WebPage/WebPage.h:
+        (WebPage):
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/qt/WebPageQt.cpp:
+        (WebKit::WebPage::selectedIndex):
+        (WebKit):
+        (WebKit::WebPage::hidePopupMenu):
+
 2012-07-20  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
 
         Unreviewed, rolling out r123085.
index 6c4d20e..b627afe 100644 (file)
@@ -38,6 +38,8 @@ PlatformPopupMenuData::PlatformPopupMenuData()
     , m_clientInsetRight(0)
     , m_popupWidth(0)
     , m_itemHeight(0)
+#elif PLATFORM(QT)
+    : multipleSelections(false)
 #endif
 {
 }
@@ -62,6 +64,8 @@ void PlatformPopupMenuData::encode(CoreIPC::ArgumentEncoder* encoder) const
 #elif PLATFORM(MAC)
     encoder->encode(fontInfo);
     encoder->encode(shouldPopOver);
+#elif PLATFORM(QT)
+    encoder->encode(multipleSelections);
 #endif
 }
 
@@ -95,6 +99,9 @@ bool PlatformPopupMenuData::decode(CoreIPC::ArgumentDecoder* decoder, PlatformPo
         return false;
     if (!decoder->decode(data.shouldPopOver))
         return false;
+#elif PLATFORM(QT)
+    if (!decoder->decode(data.multipleSelections))
+        return false;
 #endif
     
     return true;
index f85008a..21abde4 100644 (file)
@@ -55,6 +55,8 @@ struct PlatformPopupMenuData {
 #elif PLATFORM(MAC)
     FontInfo fontInfo;
     bool shouldPopOver;
+#elif PLATFORM(QT)
+    bool multipleSelections;
 #endif
 };
 
index a9ac032..c215f35 100644 (file)
@@ -39,6 +39,7 @@ WebPopupItem::WebPopupItem()
     , m_textDirection(LTR)
     , m_hasTextDirectionOverride(false)
     , m_isEnabled(true)
+    , m_isSelected(false)
 {
 }
 
@@ -48,10 +49,11 @@ WebPopupItem::WebPopupItem(Type type)
     , m_hasTextDirectionOverride(false)
     , m_isEnabled(true)
     , m_isLabel(false)
+    , m_isSelected(false)
 {
 }
 
-WebPopupItem::WebPopupItem(Type type, const String& text, TextDirection textDirection, bool hasTextDirectionOverride, const String& toolTip, const String& accessibilityText, bool isEnabled, bool isLabel)
+WebPopupItem::WebPopupItem(Type type, const String& text, TextDirection textDirection, bool hasTextDirectionOverride, const String& toolTip, const String& accessibilityText, bool isEnabled, bool isLabel, bool isSelected)
     : m_type(type)
     , m_text(text)
     , m_textDirection(textDirection)
@@ -60,12 +62,14 @@ WebPopupItem::WebPopupItem(Type type, const String& text, TextDirection textDire
     , m_accessibilityText(accessibilityText)
     , m_isEnabled(isEnabled)
     , m_isLabel(isLabel)
+    , m_isSelected(isSelected)
 {
 }
 
 void WebPopupItem::encode(CoreIPC::ArgumentEncoder* encoder) const
 {
     encoder->encode(CoreIPC::In(static_cast<uint32_t>(m_type), m_text, static_cast<uint64_t>(m_textDirection), m_hasTextDirectionOverride, m_toolTip, m_accessibilityText, m_isEnabled, m_isLabel));
+    encoder->encode(CoreIPC::In(m_isSelected));
 }
 
 bool WebPopupItem::decode(CoreIPC::ArgumentDecoder* decoder, WebPopupItem& item)
@@ -78,10 +82,15 @@ bool WebPopupItem::decode(CoreIPC::ArgumentDecoder* decoder, WebPopupItem& item)
     String accessibilityText;
     bool isEnabled;
     bool isLabel;
+    bool isSelected;
+
     if (!decoder->decode(CoreIPC::Out(type, text, textDirection, hasTextDirectionOverride, toolTip, accessibilityText, isEnabled, isLabel)))
         return false;
 
-    item = WebPopupItem(static_cast<Type>(type), text, static_cast<TextDirection>(textDirection), hasTextDirectionOverride, toolTip, accessibilityText, isEnabled, isLabel);
+    if (!decoder->decode(CoreIPC::Out(isSelected)))
+        return false;
+
+    item = WebPopupItem(static_cast<Type>(type), text, static_cast<TextDirection>(textDirection), hasTextDirectionOverride, toolTip, accessibilityText, isEnabled, isLabel, isSelected);
     return true;
 }
 
index 3dc61d7..d8584be 100644 (file)
@@ -44,7 +44,7 @@ struct WebPopupItem {
 
     WebPopupItem();
     WebPopupItem(Type);
-    WebPopupItem(Type, const String& text, WebCore::TextDirection, bool hasTextDirectionOverride, const String& toolTip, const String& accessibilityText, bool isEnabled, bool isLabel);
+    WebPopupItem(Type, const String& text, WebCore::TextDirection, bool hasTextDirectionOverride, const String& toolTip, const String& accessibilityText, bool isEnabled, bool isLabel, bool isSelected);
 
     void encode(CoreIPC::ArgumentEncoder*) const;
     static bool decode(CoreIPC::ArgumentDecoder*, WebPopupItem&);
@@ -57,6 +57,7 @@ struct WebPopupItem {
     String m_accessibilityText;
     bool m_isEnabled;
     bool m_isLabel;
+    bool m_isSelected;
 };
 
 } // namespace WebKit
index 29a6c65..e700366 100644 (file)
@@ -719,7 +719,11 @@ private:
     virtual void setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index);
 #if PLATFORM(GTK)
     virtual void failedToShowPopupMenu();
-#endif    
+#endif
+#if PLATFORM(QT)
+    virtual void changeSelectedIndex(int32_t newSelectedIndex);
+    virtual void closePopupMenu();
+#endif
 
     // Implemented in generated WebPageProxyMessageReceiver.cpp
     void didReceiveWebPageProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
index 3cefc0d..d5bfa4c 100644 (file)
@@ -55,7 +55,11 @@ public:
         virtual NativeWebMouseEvent* currentlyProcessedMouseDownEvent() = 0;
 #if PLATFORM(GTK)
         virtual void failedToShowPopupMenu() = 0;
-#endif        
+#endif
+#if PLATFORM(QT)
+        virtual void changeSelectedIndex(int32_t newSelectedIndex) = 0;
+        virtual void closePopupMenu() = 0;
+#endif
     };
 
     virtual ~WebPopupMenuProxy()
index 5cafad5..fa2c74f 100644 (file)
@@ -119,4 +119,14 @@ void WebPageProxy::windowedPluginGeometryDidChange(const WebCore::IntRect& frame
 }
 #endif
 
+void WebPageProxy::changeSelectedIndex(int32_t selectedIndex)
+{
+    process()->send(Messages::WebPage::SelectedIndex(selectedIndex), m_pageID);
+}
+
+void WebPageProxy::closePopupMenu()
+{
+    process()->send(Messages::WebPage::HidePopupMenu(), m_pageID);
+}
+
 } // namespace WebKit
index 9d936a6..7512892 100644 (file)
@@ -52,23 +52,28 @@ public:
         IsSeparatorRole = Qt::UserRole + 3
     };
 
-    PopupMenuItemModel(const Vector<WebPopupItem>&, int selectedOriginalIndex);
+    PopupMenuItemModel(const Vector<WebPopupItem>&, bool multiple);
     virtual int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_items.size(); }
     virtual QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const;
 
     Q_INVOKABLE void select(int);
 
     int selectedOriginalIndex() const;
+    bool multiple() const { return m_allowMultiples; }
+    void toggleItem(int);
+
+Q_SIGNALS:
+    void indexUpdated();
 
 private:
     struct Item {
-        Item(const WebPopupItem& webPopupItem, const QString& group, int originalIndex, bool selected)
+        Item(const WebPopupItem& webPopupItem, const QString& group, int originalIndex)
             : text(webPopupItem.m_text)
             , toolTip(webPopupItem.m_toolTip)
             , group(group)
             , originalIndex(originalIndex)
             , enabled(webPopupItem.m_isEnabled)
-            , selected(selected)
+            , selected(webPopupItem.m_isSelected)
             , isSeparator(webPopupItem.m_type == WebPopupItem::Separator)
         { }
 
@@ -82,47 +87,68 @@ private:
         bool isSeparator;
     };
 
-    void buildItems(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex);
+    void buildItems(const Vector<WebPopupItem>& webPopupItems);
 
     Vector<Item> m_items;
     int m_selectedModelIndex;
+    bool m_allowMultiples;
 };
 
 class ItemSelectorContextObject : public QObject {
     Q_OBJECT
     Q_PROPERTY(QRectF elementRect READ elementRect CONSTANT FINAL)
     Q_PROPERTY(QObject* items READ items CONSTANT FINAL)
+    Q_PROPERTY(bool allowMultiSelect READ allowMultiSelect CONSTANT FINAL)
 
 public:
-    ItemSelectorContextObject(const QRectF& elementRect, const Vector<WebPopupItem>&, int selectedIndex);
+    ItemSelectorContextObject(const QRectF& elementRect, const Vector<WebPopupItem>&, bool multiple);
 
     QRectF elementRect() const { return m_elementRect; }
     PopupMenuItemModel* items() { return &m_items; }
+    bool allowMultiSelect() { return m_items.multiple(); }
 
     Q_INVOKABLE void accept(int index = -1);
-    Q_INVOKABLE void reject() { emit rejected(); }
+    Q_INVOKABLE void reject() { emit done(); }
+    Q_INVOKABLE void dismiss() { emit done(); }
 
 Q_SIGNALS:
     void acceptedWithOriginalIndex(int);
-    void rejected();
+    void done();
+
+private Q_SLOTS:
+    void onIndexUpdate();
 
 private:
     QRectF m_elementRect;
     PopupMenuItemModel m_items;
 };
 
-ItemSelectorContextObject::ItemSelectorContextObject(const QRectF& elementRect, const Vector<WebPopupItem>& webPopupItems, int selectedIndex)
+ItemSelectorContextObject::ItemSelectorContextObject(const QRectF& elementRect, const Vector<WebPopupItem>& webPopupItems, bool multiple)
     : m_elementRect(elementRect)
-    , m_items(webPopupItems, selectedIndex)
+    , m_items(webPopupItems, multiple)
 {
+    connect(&m_items, SIGNAL(indexUpdated()), SLOT(onIndexUpdate()));
 }
 
+void ItemSelectorContextObject::onIndexUpdate()
+{
+    // Send the update for multi-select list.
+    if (m_items.multiple())
+        emit acceptedWithOriginalIndex(m_items.selectedOriginalIndex());
+}
+
+
 void ItemSelectorContextObject::accept(int index)
 {
-    if (index != -1)
-        m_items.select(index);
-    int originalIndex = m_items.selectedOriginalIndex();
-    emit acceptedWithOriginalIndex(originalIndex);
+    // If the index is not valid for multi-select lists, just hide the pop up as the selected indices have
+    // already been sent.
+    if ((index == -1) && m_items.multiple())
+        emit done();
+    else {
+        if (index != -1)
+            m_items.toggleItem(index);
+        emit acceptedWithOriginalIndex(m_items.selectedOriginalIndex());
+    }
 }
 
 static QHash<int, QByteArray> createRoleNamesHash()
@@ -137,12 +163,13 @@ static QHash<int, QByteArray> createRoleNamesHash()
     return roles;
 }
 
-PopupMenuItemModel::PopupMenuItemModel(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex)
+PopupMenuItemModel::PopupMenuItemModel(const Vector<WebPopupItem>& webPopupItems, bool multiple)
     : m_selectedModelIndex(-1)
+    , m_allowMultiples(multiple)
 {
     static QHash<int, QByteArray> roles = createRoleNamesHash();
     setRoleNames(roles);
-    buildItems(webPopupItems, selectedOriginalIndex);
+    buildItems(webPopupItems);
 }
 
 QVariant PopupMenuItemModel::data(const QModelIndex& index, int role) const
@@ -177,22 +204,31 @@ QVariant PopupMenuItemModel::data(const QModelIndex& index, int role) const
 
 void PopupMenuItemModel::select(int index)
 {
+    toggleItem(index);
+    emit indexUpdated();
+}
+
+void PopupMenuItemModel::toggleItem(int index)
+{
     int oldIndex = m_selectedModelIndex;
-    if (index == oldIndex)
-        return;
     if (index < 0 || index >= m_items.size())
         return;
     Item& item = m_items[index];
     if (!item.enabled)
         return;
 
-    item.selected = true;
     m_selectedModelIndex = index;
-
-    if (oldIndex != -1) {
-        Item& oldItem = m_items[oldIndex];
-        oldItem.selected = false;
-        emit dataChanged(this->index(oldIndex), this->index(oldIndex));
+    if (m_allowMultiples)
+        item.selected = !item.selected;
+    else {
+        if (index == oldIndex)
+            return;
+        item.selected = true;
+        if (oldIndex != -1) {
+            Item& oldItem = m_items[oldIndex];
+            oldItem.selected = false;
+            emit dataChanged(this->index(oldIndex), this->index(oldIndex));
+        }
     }
 
     emit dataChanged(this->index(index), this->index(index));
@@ -205,7 +241,7 @@ int PopupMenuItemModel::selectedOriginalIndex() const
     return m_items[m_selectedModelIndex].originalIndex;
 }
 
-void PopupMenuItemModel::buildItems(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex)
+void PopupMenuItemModel::buildItems(const Vector<WebPopupItem>& webPopupItems)
 {
     QString currentGroup;
     m_items.reserveInitialCapacity(webPopupItems.size());
@@ -215,10 +251,9 @@ void PopupMenuItemModel::buildItems(const Vector<WebPopupItem>& webPopupItems, i
             currentGroup = webPopupItem.m_text;
             continue;
         }
-        const bool selected = i == selectedOriginalIndex;
-        if (selected)
+        if (webPopupItem.m_isSelected && !m_allowMultiples)
             m_selectedModelIndex = m_items.size();
-        m_items.append(Item(webPopupItem, currentGroup, i, selected));
+        m_items.append(Item(webPopupItem, currentGroup, i));
     }
 }
 
@@ -232,15 +267,15 @@ WebPopupMenuProxyQt::~WebPopupMenuProxyQt()
 {
 }
 
-void WebPopupMenuProxyQt::showPopupMenu(const IntRect& rect, WebCore::TextDirection, double, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex)
+void WebPopupMenuProxyQt::showPopupMenu(const IntRect& rect, WebCore::TextDirection, double, const Vector<WebPopupItem>& items, const PlatformPopupMenuData& data, int32_t)
 {
-    m_selectedIndex = selectedIndex;
+    m_selectionType = (data.multipleSelections) ? WebPopupMenuProxyQt::MultipleSelection : WebPopupMenuProxyQt::SingleSelection;
 
     const QRectF mappedRect= m_webView->mapRectFromWebContent(QRect(rect));
-    ItemSelectorContextObject* contextObject = new ItemSelectorContextObject(mappedRect, items, m_selectedIndex);
+    ItemSelectorContextObject* contextObject = new ItemSelectorContextObject(mappedRect, items, (m_selectionType == WebPopupMenuProxyQt::MultipleSelection));
     createItem(contextObject);
     if (!m_itemSelector) {
-        notifyValueChanged();
+        hidePopupMenu();
         return;
     }
     QQuickWebViewPrivate::get(m_webView)->setDialogActive(true);
@@ -251,12 +286,16 @@ void WebPopupMenuProxyQt::hidePopupMenu()
     m_itemSelector.clear();
     QQuickWebViewPrivate::get(m_webView)->setDialogActive(false);
     m_context.clear();
-    notifyValueChanged();
+
+    if (m_client) {
+        m_client->closePopupMenu();
+        invalidate();
+    }
 }
 
 void WebPopupMenuProxyQt::selectIndex(int index)
 {
-    m_selectedIndex = index;
+    m_client->changeSelectedIndex(index);
 }
 
 void WebPopupMenuProxyQt::createItem(QObject* contextObject)
@@ -269,23 +308,19 @@ void WebPopupMenuProxyQt::createItem(QObject* contextObject)
 
     createContext(component, contextObject);
     QObject* object = component->beginCreate(m_context.get());
-    if (!object) {
-        m_context.clear();
+    if (!object)
         return;
-    }
 
     m_itemSelector = adoptPtr(qobject_cast<QQuickItem*>(object));
-    if (!m_itemSelector) {
-        m_context.clear();
-        m_itemSelector.clear();
+    if (!m_itemSelector)
         return;
-    }
 
     connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(selectIndex(int)));
 
     // We enqueue these because they are triggered by m_itemSelector and will lead to its destruction.
-    connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(hidePopupMenu()), Qt::QueuedConnection);
-    connect(contextObject, SIGNAL(rejected()), SLOT(hidePopupMenu()), Qt::QueuedConnection);
+    connect(contextObject, SIGNAL(done()), SLOT(hidePopupMenu()), Qt::QueuedConnection);
+    if (m_selectionType == WebPopupMenuProxyQt::SingleSelection)
+        connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(hidePopupMenu()), Qt::QueuedConnection);
 
     QQuickWebViewPrivate::get(m_webView)->addAttachedPropertyTo(m_itemSelector.get());
     m_itemSelector->setParentItem(m_webView);
@@ -308,14 +343,6 @@ void WebPopupMenuProxyQt::createContext(QQmlComponent* component, QObject* conte
     m_context->setContextObject(contextObject);
 }
 
-void WebPopupMenuProxyQt::notifyValueChanged()
-{
-    if (m_client) {
-        m_client->valueChangedForPopupMenu(this, m_selectedIndex);
-        invalidate();
-    }
-}
-
 } // namespace WebKit
 
 // Since we define QObjects in WebPopupMenuProxyQt.cpp, this will trigger moc to run on .cpp.
index 21eec5d..3eb544d 100644 (file)
@@ -42,6 +42,11 @@ class WebPopupMenuProxyQt : public QObject, public WebPopupMenuProxy {
     Q_OBJECT
 
 public:
+    enum SelectionType {
+        SingleSelection,
+        MultipleSelection
+    };
+
     static PassRefPtr<WebPopupMenuProxyQt> create(WebPopupMenuProxy::Client* client, QQuickWebView* webView)
     {
         return adoptRef(new WebPopupMenuProxyQt(client, webView));
@@ -61,13 +66,11 @@ private:
     void createItem(QObject*);
     void createContext(QQmlComponent*, QObject*);
 
-    void notifyValueChanged();
-
     OwnPtr<QQmlContext> m_context;
     OwnPtr<QQuickItem> m_itemSelector;
 
     QQuickWebView* m_webView;
-    int32_t m_selectedIndex;
+    SelectionType m_selectionType;
 };
 
 } // namespace WebKit
index 940cb95..4c309dc 100644 (file)
@@ -59,9 +59,14 @@ void WebPopupMenu::didChangeSelectedIndex(int newIndex)
     if (!m_popupClient)
         return;
 
+#if PLATFORM(QT)
+    if (newIndex >= 0)
+        m_popupClient->listBoxSelectItem(newIndex, m_popupClient->multiple(), false);
+#else
     m_popupClient->popupDidHide();
     if (newIndex >= 0)
         m_popupClient->valueChanged(newIndex);
+#endif
 }
 
 void WebPopupMenu::setTextForIndex(int index)
@@ -87,7 +92,7 @@ Vector<WebPopupItem> WebPopupMenu::populateItems()
             // FIXME: Add support for styling the foreground and background colors.
             // FIXME: Find a way to customize text color when an item is highlighted.
             PopupMenuStyle itemStyle = m_popupClient->itemStyle(i);
-            items.append(WebPopupItem(WebPopupItem::Item, m_popupClient->itemText(i), itemStyle.textDirection(), itemStyle.hasTextDirectionOverride(), m_popupClient->itemToolTip(i), m_popupClient->itemAccessibilityText(i), m_popupClient->itemIsEnabled(i), m_popupClient->itemIsLabel(i)));
+            items.append(WebPopupItem(WebPopupItem::Item, m_popupClient->itemText(i), itemStyle.textDirection(), itemStyle.hasTextDirectionOverride(), m_popupClient->itemToolTip(i), m_popupClient->itemAccessibilityText(i), m_popupClient->itemIsEnabled(i), m_popupClient->itemIsLabel(i), m_popupClient->itemIsSelected(i)));
         }
     }
 
index 8e66250..6319b9d 100644 (file)
@@ -48,7 +48,7 @@ public:
     void disconnectFromPage() { m_page = 0; }
     void didChangeSelectedIndex(int newIndex);
     void setTextForIndex(int newIndex);
-#if PLATFORM(GTK)    
+#if PLATFORM(GTK) || PLATFORM(QT)
     WebCore::PopupMenuClient* client() const { return m_popupClient; }
 #endif
 
index b21f06c..f0a8f77 100644 (file)
 #include "WebPopupMenu.h"
 
 #include "PlatformPopupMenuData.h"
+#include <WebCore/PopupMenuClient.h>
 
 using namespace WebCore;
 
 namespace WebKit {
 
-void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData&)
+void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData& data)
 {
+    data.multipleSelections = m_popupClient->multiple();
 }
 
 } // namespace WebKit
index e723461..9571ffb 100644 (file)
@@ -2401,11 +2401,16 @@ void WebPage::countStringMatches(const String& string, uint32_t options, uint32_
 
 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
 {
+    changeSelectedIndex(newIndex);
+    m_activePopupMenu = 0;
+}
+
+void WebPage::changeSelectedIndex(int32_t index)
+{
     if (!m_activePopupMenu)
         return;
 
-    m_activePopupMenu->didChangeSelectedIndex(newIndex);
-    m_activePopupMenu = 0;
+    m_activePopupMenu->didChangeSelectedIndex(index);
 }
 
 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
index 4d20421..1b7708a 100644 (file)
@@ -697,6 +697,10 @@ private:
 #if PLATFORM(GTK)
     void failedToShowPopupMenu();
 #endif
+#if PLATFORM(QT)
+    void hidePopupMenu();
+    void selectedIndex(int32_t newIndex);
+#endif
 
     void didChooseFilesForOpenPanel(const Vector<String>&);
     void didCancelForOpenPanel();
@@ -724,6 +728,7 @@ private:
     void didSelectItemFromActiveContextMenu(const WebContextMenuItemData&);
 #endif
 
+    void changeSelectedIndex(int32_t index);
     void setCanStartMediaTimerFired();
 
     static bool platformCanHandleRequest(const WebCore::ResourceRequest&);
index 4c260eb..39c8114 100644 (file)
@@ -166,7 +166,11 @@ messages -> WebPage {
     SetTextForActivePopupMenu(int32_t index);
 #if PLATFORM(GTK)    
     FailedToShowPopupMenu();
-#endif    
+#endif
+#if PLATFORM(QT)
+    HidePopupMenu();
+    SelectedIndex(int32_t newIndex);
+#endif
     
 #if ENABLE(CONTEXT_MENUS)
     # Context menu.
index 2e90a73..18e4f94 100644 (file)
 #include "WebPage.h"
 
 #include "NotImplemented.h"
+#include "PopupMenuClient.h"
 #include "WebEditorClient.h"
 #include "WebEvent.h"
 #include "WebPageProxyMessages.h"
+#include "WebPopupMenu.h"
 #include "WebProcess.h"
 #include <WebCore/DOMWrapperWorld.h>
 #include <WebCore/FocusController.h>
@@ -422,4 +424,18 @@ void WebPage::setUserScripts(const Vector<String>& scripts)
         pageGroup->addUserScriptToWorld(mainThreadNormalWorld(), scripts.at(i), KURL(), nullptr, nullptr, InjectAtDocumentEnd, InjectInTopFrameOnly);
 }
 
+void WebPage::selectedIndex(int32_t newIndex)
+{
+    changeSelectedIndex(newIndex);
+}
+
+void WebPage::hidePopupMenu()
+{
+    if (!m_activePopupMenu)
+        return;
+
+    m_activePopupMenu->client()->popupDidHide();
+    m_activePopupMenu = 0;
+}
+
 } // namespace WebKit