1/* 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 3 * Copyright (C) 2010 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22#include "config.h" 23#include "WebPopupMenu.h" 24 25#include "PlatformPopupMenuData.h" 26#include "WebCoreArgumentCoders.h" 27#include "WebPage.h" 28#include "WebPageProxyMessages.h" 29#include "WebProcess.h" 30#include <WebCore/FrameView.h> 31#include <WebCore/PopupMenuClient.h> 32 33using namespace WebCore; 34 35namespace WebKit { 36 37PassRefPtr<WebPopupMenu> WebPopupMenu::create(WebPage* page, PopupMenuClient* client) 38{ 39 return adoptRef(new WebPopupMenu(page, client)); 40} 41 42WebPopupMenu::WebPopupMenu(WebPage* page, PopupMenuClient* client) 43 : m_popupClient(client) 44 , m_page(page) 45{ 46} 47 48WebPopupMenu::~WebPopupMenu() 49{ 50} 51 52void WebPopupMenu::disconnectClient() 53{ 54 m_popupClient = 0; 55} 56 57void WebPopupMenu::didChangeSelectedIndex(int newIndex) 58{ 59 if (!m_popupClient) 60 return; 61 62 m_popupClient->popupDidHide(); 63 if (newIndex >= 0) 64 m_popupClient->valueChanged(newIndex); 65} 66 67void WebPopupMenu::setTextForIndex(int index) 68{ 69 if (!m_popupClient) 70 return; 71 72 m_popupClient->setTextFromItem(index); 73} 74 75Vector<WebPopupItem> WebPopupMenu::populateItems() 76{ 77 size_t size = m_popupClient->listSize(); 78 79 Vector<WebPopupItem> items; 80 items.reserveInitialCapacity(size); 81 82 for (size_t i = 0; i < size; ++i) { 83 if (m_popupClient->itemIsSeparator(i)) 84 items.append(WebPopupItem(WebPopupItem::Separator)); 85 else { 86 // FIXME: Add support for styling the font. 87 // FIXME: Add support for styling the foreground and background colors. 88 // FIXME: Find a way to customize text color when an item is highlighted. 89 PopupMenuStyle itemStyle = m_popupClient->itemStyle(i); 90 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))); 91 } 92 } 93 94 return items; 95} 96 97void WebPopupMenu::show(const IntRect& rect, FrameView* view, int index) 98{ 99 // FIXME: We should probably inform the client to also close the menu. 100 Vector<WebPopupItem> items = populateItems(); 101 102 if (items.isEmpty() || !m_page) { 103 m_popupClient->popupDidHide(); 104 return; 105 } 106 107 m_page->setActivePopupMenu(this); 108 109 // Move to page coordinates 110 IntRect pageCoordinates(view->contentsToWindow(rect.location()), rect.size()); 111 112 PlatformPopupMenuData platformData; 113 setUpPlatformData(pageCoordinates, platformData); 114 115 WebProcess::shared().connection()->send(Messages::WebPageProxy::ShowPopupMenu(pageCoordinates, m_popupClient->menuStyle().textDirection(), items, index, platformData), m_page->pageID()); 116} 117 118void WebPopupMenu::hide() 119{ 120 if (!m_page || !m_popupClient) 121 return; 122 123 WebProcess::shared().connection()->send(Messages::WebPageProxy::HidePopupMenu(), m_page->pageID()); 124 m_page->setActivePopupMenu(0); 125} 126 127void WebPopupMenu::updateFromElement() 128{ 129#if PLATFORM(WIN) 130 if (!m_page || !m_popupClient) 131 return; 132 133 int selectedIndex = m_popupClient->selectedIndex(); 134 WebProcess::shared().connection()->send(Messages::WebPageProxy::SetPopupMenuSelectedIndex(selectedIndex), m_page->pageID()); 135#endif 136} 137 138} // namespace WebKit 139