1 /* 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "ContextMenu.h" 28 29 #if ENABLE(CONTEXT_MENUS) 30 31 #include "ContextMenuController.h" 32 33 @interface WebCoreMenuTarget : NSObject { 34 WebCore::ContextMenuController* _menuController; 35 } 36 + (WebCoreMenuTarget*)sharedMenuTarget; 37 - (WebCore::ContextMenuController*)menuController; 38 - (void)setMenuController:(WebCore::ContextMenuController*)menuController; 39 - (void)forwardContextMenuAction:(id)sender; 40 - (BOOL)validateMenuItem:(NSMenuItem *)item; 41 @end 42 43 static WebCoreMenuTarget* target; 44 45 @implementation WebCoreMenuTarget 46 47 + (WebCoreMenuTarget*)sharedMenuTarget 48 { 49 if (!target) 50 target = [[WebCoreMenuTarget alloc] init]; 51 return target; 52 } 53 54 - (WebCore::ContextMenuController*)menuController 55 { 56 return _menuController; 57 } 58 59 - (void)setMenuController:(WebCore::ContextMenuController*)menuController 60 { 61 _menuController = menuController; 62 } 63 64 - (void)forwardContextMenuAction:(id)sender 65 { 66 WebCore::ContextMenuItem item(WebCore::ActionType, static_cast<WebCore::ContextMenuAction>([sender tag]), [sender title]); 67 _menuController->contextMenuItemSelected(&item); 68 } 69 70 - (BOOL)validateMenuItem:(NSMenuItem *)item 71 { 72 WebCore::ContextMenuItem coreItem(item); 73 ASSERT(_menuController->contextMenu()); 74 _menuController->contextMenu()->checkOrEnableIfNeeded(coreItem); 75 return coreItem.enabled(); 76 } 77 78 @end 79 80 namespace WebCore { 81 82 ContextMenu::ContextMenu(const HitTestResult& result) 83 : m_hitTestResult(result) 84 { 85 NSMutableArray* array = [[NSMutableArray alloc] init]; 86 m_platformDescription = array; 87 [array release]; 88 89 [[WebCoreMenuTarget sharedMenuTarget] setMenuController:controller()]; 90 } 91 92 ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu) 93 : m_hitTestResult(result) 94 , m_platformDescription(menu) 95 { 96 [[WebCoreMenuTarget sharedMenuTarget] setMenuController:controller()]; 97 } 98 99 ContextMenu::~ContextMenu() 100 { 101 } 102 103 static void setMenuItemTarget(NSMenuItem* menuItem) 104 { 105 [menuItem setTarget:[WebCoreMenuTarget sharedMenuTarget]]; 106 [menuItem setAction:@selector(forwardContextMenuAction:)]; 107 } 108 109 void ContextMenu::appendItem(ContextMenuItem& item) 110 { 111 checkOrEnableIfNeeded(item); 112 113 ContextMenuItemType type = item.type(); 114 NSMenuItem* platformItem = item.releasePlatformDescription(); 115 if (type == ActionType) 116 setMenuItemTarget(platformItem); 117 118 [m_platformDescription.get() addObject:platformItem]; 119 [platformItem release]; 120 } 121 122 void ContextMenu::insertItem(unsigned position, ContextMenuItem& item) 123 { 124 checkOrEnableIfNeeded(item); 125 126 ContextMenuItemType type = item.type(); 127 NSMenuItem* platformItem = item.releasePlatformDescription(); 128 if (type == ActionType) 129 setMenuItemTarget(platformItem); 130 131 [m_platformDescription.get() insertObject:platformItem atIndex:position]; 132 [platformItem release]; 133 } 134 135 unsigned ContextMenu::itemCount() const 136 { 137 return [m_platformDescription.get() count]; 138 } 139 140 void ContextMenu::setPlatformDescription(NSMutableArray* menu) 141 { 142 if (m_platformDescription.get() != menu) 143 m_platformDescription = menu; 144 } 145 146 NSMutableArray* ContextMenu::platformDescription() const 147 { 148 return m_platformDescription.get(); 149 } 150 151 NSMutableArray* ContextMenu::releasePlatformDescription() 152 { 153 return m_platformDescription.releaseRef(); 154 } 155 156 } // namespace WebCore 157 158 #endif // ENABLE(CONTEXT_MENUS) 159