1 /* 2 * Copyright (C) 2006, 2007 Apple 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 "ContextMenuItem.h" 28 29 #include "ContextMenu.h" 30 31 #include "CString.h" 32 #include <windows.h> 33 34 namespace WebCore { 35 36 ContextMenuItem::ContextMenuItem(LPMENUITEMINFO item) 37 : m_platformDescription(item) 38 { 39 } 40 41 ContextMenuItem::ContextMenuItem(ContextMenu* subMenu) 42 { 43 m_platformDescription = (LPMENUITEMINFO)malloc(sizeof(MENUITEMINFO)); 44 if (!m_platformDescription) 45 return; 46 47 memset(m_platformDescription, 0, sizeof(MENUITEMINFO)); 48 m_platformDescription->cbSize = sizeof(MENUITEMINFO); 49 50 m_platformDescription->wID = ContextMenuItemTagNoAction; 51 if (subMenu) { 52 m_platformDescription->fMask |= MIIM_SUBMENU; 53 m_platformDescription->hSubMenu = subMenu->platformDescription(); 54 } 55 } 56 57 ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu) 58 { 59 m_platformDescription = (LPMENUITEMINFO)malloc(sizeof(MENUITEMINFO)); 60 if (!m_platformDescription) 61 return; 62 63 memset(m_platformDescription, 0, sizeof(MENUITEMINFO)); 64 m_platformDescription->cbSize = sizeof(MENUITEMINFO); 65 m_platformDescription->fMask = MIIM_FTYPE; 66 67 if (type == SeparatorType) { 68 m_platformDescription->fType = MFT_SEPARATOR; 69 return; 70 } 71 72 if (subMenu) { 73 m_platformDescription->fMask |= MIIM_STRING | MIIM_SUBMENU; 74 m_platformDescription->hSubMenu = subMenu->platformDescription(); 75 } else 76 m_platformDescription->fMask |= MIIM_STRING | MIIM_ID; 77 78 m_platformDescription->fType = MFT_STRING; 79 m_platformDescription->wID = action; 80 81 String t = title; 82 m_platformDescription->cch = t.length(); 83 m_platformDescription->dwTypeData = wcsdup(t.charactersWithNullTermination()); 84 } 85 86 ContextMenuItem::~ContextMenuItem() 87 { 88 if (m_platformDescription) { 89 if (m_platformDescription->fType == MFT_STRING) 90 free(m_platformDescription->dwTypeData); 91 free(m_platformDescription); 92 } 93 } 94 95 LPMENUITEMINFO ContextMenuItem::releasePlatformDescription() 96 { 97 LPMENUITEMINFO info = m_platformDescription; 98 m_platformDescription = 0; 99 return info; 100 } 101 102 ContextMenuItemType ContextMenuItem::type() const 103 { 104 ContextMenuItemType type = ActionType; 105 if (((m_platformDescription->fType & ~MFT_OWNERDRAW) == MFT_STRING) && m_platformDescription->hSubMenu) 106 type = SubmenuType; 107 else if (m_platformDescription->fType & MFT_SEPARATOR) 108 type = SeparatorType; 109 110 return type; 111 } 112 113 ContextMenuAction ContextMenuItem::action() const 114 { 115 return static_cast<ContextMenuAction>(m_platformDescription->wID); 116 } 117 118 String ContextMenuItem::title() const 119 { 120 return String(m_platformDescription->dwTypeData, wcslen(m_platformDescription->dwTypeData)); 121 } 122 123 PlatformMenuDescription ContextMenuItem::platformSubMenu() const 124 { 125 return m_platformDescription->hSubMenu; 126 } 127 128 void ContextMenuItem::setType(ContextMenuItemType type) 129 { 130 if (type == SeparatorType) 131 m_platformDescription->fType = MFT_SEPARATOR; 132 else 133 m_platformDescription->fType = MFT_STRING; 134 } 135 136 void ContextMenuItem::setAction(ContextMenuAction action) 137 { 138 m_platformDescription->wID = action; 139 } 140 141 void ContextMenuItem::setTitle(const String& title) 142 { 143 if (m_platformDescription->dwTypeData) 144 free(m_platformDescription->dwTypeData); 145 146 m_platformDescription->cch = title.length(); 147 String titleCopy = title; 148 m_platformDescription->dwTypeData = wcsdup(titleCopy.charactersWithNullTermination()); 149 } 150 151 void ContextMenuItem::setSubMenu(ContextMenu* subMenu) 152 { 153 if (subMenu->platformDescription() == m_platformDescription->hSubMenu) 154 return; 155 156 if (m_platformDescription->hSubMenu) 157 ::DestroyMenu(m_platformDescription->hSubMenu); 158 159 m_platformDescription->fMask |= MIIM_SUBMENU; 160 m_platformDescription->hSubMenu = subMenu->releasePlatformDescription(); 161 } 162 163 void ContextMenuItem::setChecked(bool checked) 164 { 165 m_platformDescription->fMask |= MIIM_STATE; 166 if (checked) { 167 m_platformDescription->fState &= ~MFS_UNCHECKED; 168 m_platformDescription->fState |= MFS_CHECKED; 169 } else { 170 m_platformDescription->fState &= ~MFS_CHECKED; 171 m_platformDescription->fState |= MFS_UNCHECKED; 172 } 173 } 174 175 void ContextMenuItem::setEnabled(bool enabled) 176 { 177 m_platformDescription->fMask |= MIIM_STATE; 178 if (enabled) { 179 m_platformDescription->fState &= ~MFS_DISABLED; 180 m_platformDescription->fState |= MFS_ENABLED; 181 } else { 182 m_platformDescription->fState &= ~MFS_ENABLED; 183 m_platformDescription->fState |= MFS_DISABLED; 184 } 185 } 186 187 bool ContextMenuItem::enabled() const 188 { 189 return !(m_platformDescription->fState & MFS_DISABLED); 190 } 191 192 } 193