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 33 using namespace WebCore; 34 35 namespace WebKit { 36 37 PassRefPtr<WebPopupMenu> WebPopupMenu::create(WebPage* page, PopupMenuClient* client) 38 { 39 return adoptRef(new WebPopupMenu(page, client)); 40 } 41 42 WebPopupMenu::WebPopupMenu(WebPage* page, PopupMenuClient* client) 43 : m_popupClient(client) 44 , m_page(page) 45 { 46 } 47 48 WebPopupMenu::~WebPopupMenu() 49 { 50 } 51 52 void WebPopupMenu::disconnectClient() 53 { 54 m_popupClient = 0; 55 } 56 57 void 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 67 void WebPopupMenu::setTextForIndex(int index) 68 { 69 if (!m_popupClient) 70 return; 71 72 m_popupClient->setTextFromItem(index); 73 } 74 75 Vector<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 97 void 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 118 void 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 127 void 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