165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * This library is free software; you can redistribute it and/or
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modify it under the terms of the GNU Library General Public
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * License as published by the Free Software Foundation; either
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * version 2 of the License, or (at your option) any later version.
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * This library is distributed in the hope that it will be useful,
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * but WITHOUT ANY WARRANTY; without even the implied warranty of
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Library General Public License for more details.
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * You should have received a copy of the GNU Library General Public License
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * along with this library; see the file COPYING.LIB.  If not, write to
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Boston, MA 02110-1301, USA.
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h"
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebPopupMenu.h"
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "PlatformPopupMenuData.h"
2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebCoreArgumentCoders.h"
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebPage.h"
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebPageProxyMessages.h"
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebProcess.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/FrameView.h>
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/PopupMenuClient.h>
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore;
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit {
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochPassRefPtr<WebPopupMenu> WebPopupMenu::create(WebPage* page, PopupMenuClient* client)
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return adoptRef(new WebPopupMenu(page, client));
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochWebPopupMenu::WebPopupMenu(WebPage* page, PopupMenuClient* client)
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    : m_popupClient(client)
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_page(page)
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochWebPopupMenu::~WebPopupMenu()
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebPopupMenu::disconnectClient()
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_popupClient = 0;
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebPopupMenu::didChangeSelectedIndex(int newIndex)
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_popupClient)
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_popupClient->popupDidHide();
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (newIndex >= 0)
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_popupClient->valueChanged(newIndex);
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebPopupMenu::setTextForIndex(int index)
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_popupClient)
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_popupClient->setTextFromItem(index);
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochVector<WebPopupItem> WebPopupMenu::populateItems()
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    size_t size = m_popupClient->listSize();
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<WebPopupItem> items;
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    items.reserveInitialCapacity(size);
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (size_t i = 0; i < size; ++i) {
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (m_popupClient->itemIsSeparator(i))
842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            items.append(WebPopupItem(WebPopupItem::Separator));
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        else {
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // FIXME: Add support for styling the font.
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // FIXME: Add support for styling the foreground and background colors.
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // FIXME: Find a way to customize text color when an item is highlighted.
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            PopupMenuStyle itemStyle = m_popupClient->itemStyle(i);
902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            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)));
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return items;
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebPopupMenu::show(const IntRect& rect, FrameView* view, int index)
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // FIXME: We should probably inform the client to also close the menu.
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<WebPopupItem> items = populateItems();
10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (items.isEmpty() || !m_page) {
10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_popupClient->popupDidHide();
10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_page->setActivePopupMenu(this);
10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Move to page coordinates
11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    IntRect pageCoordinates(view->contentsToWindow(rect.location()), rect.size());
11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    PlatformPopupMenuData platformData;
11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    setUpPlatformData(pageCoordinates, platformData);
11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    WebProcess::shared().connection()->send(Messages::WebPageProxy::ShowPopupMenu(pageCoordinates, m_popupClient->menuStyle().textDirection(), items, index, platformData), m_page->pageID());
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebPopupMenu::hide()
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_page || !m_popupClient)
12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    WebProcess::shared().connection()->send(Messages::WebPageProxy::HidePopupMenu(), m_page->pageID());
12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_page->setActivePopupMenu(0);
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebPopupMenu::updateFromElement()
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if PLATFORM(WIN)
1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_page || !m_popupClient)
1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    int selectedIndex = m_popupClient->selectedIndex();
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    WebProcess::shared().connection()->send(Messages::WebPageProxy::SetPopupMenuSelectedIndex(selectedIndex), m_page->pageID());
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit
139