Home | History | Annotate | Download | only in mac
      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