1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #ifndef _SV_RC_H 32 #include <tools/rc.h> 33 #endif 34 #include <vcl/decoview.hxx> 35 #include <vcl/event.hxx> 36 #include <vcl/menu.hxx> 37 #include <vcl/timer.hxx> 38 #include <vcl/menubtn.hxx> 39 40 41 42 // ======================================================================= 43 44 #define IMAGEBUTTON_BORDER_OFF1 11 45 #define IMAGEBUTTON_BORDER_OFF2 16 46 47 // ======================================================================= 48 49 void MenuButton::ImplInitMenuButtonData() 50 { 51 mnDDStyle = PUSHBUTTON_DROPDOWN_MENUBUTTON; 52 53 mpMenuTimer = NULL; 54 mpMenu = NULL; 55 mpOwnMenu = NULL; 56 mnCurItemId = 0; 57 mnMenuMode = 0; 58 } 59 60 // ----------------------------------------------------------------------- 61 62 void MenuButton::ImplInit( Window* pParent, WinBits nStyle ) 63 { 64 if ( !(nStyle & WB_NOTABSTOP) ) 65 nStyle |= WB_TABSTOP; 66 67 PushButton::ImplInit( pParent, nStyle ); 68 } 69 70 // ----------------------------------------------------------------------- 71 72 void MenuButton::ImplExecuteMenu() 73 { 74 Activate(); 75 76 if ( mpMenu ) 77 { 78 Point aPos( 0, 1 ); 79 Size aSize = GetSizePixel(); 80 Rectangle aRect( aPos, aSize ); 81 SetPressed( sal_True ); 82 EndSelection(); 83 mnCurItemId = mpMenu->Execute( this, aRect, POPUPMENU_EXECUTE_DOWN ); 84 SetPressed( sal_False ); 85 if ( mnCurItemId ) 86 { 87 Select(); 88 mnCurItemId = 0; 89 } 90 } 91 } 92 93 // ----------------------------------------------------------------------- 94 95 MenuButton::MenuButton( Window* pParent, WinBits nWinBits ) : 96 PushButton( WINDOW_MENUBUTTON ) 97 { 98 ImplInitMenuButtonData(); 99 ImplInit( pParent, nWinBits ); 100 } 101 102 // ----------------------------------------------------------------------- 103 104 MenuButton::MenuButton( Window* pParent, const ResId& rResId ) : 105 PushButton( WINDOW_MENUBUTTON ) 106 { 107 ImplInitMenuButtonData(); 108 rResId.SetRT( RSC_MENUBUTTON ); 109 WinBits nStyle = ImplInitRes( rResId ); 110 ImplInit( pParent, nStyle ); 111 ImplLoadRes( rResId ); 112 113 if ( !(nStyle & WB_HIDE) ) 114 Show(); 115 } 116 117 // ----------------------------------------------------------------------- 118 119 void MenuButton::ImplLoadRes( const ResId& rResId ) 120 { 121 Control::ImplLoadRes( rResId ); 122 123 sal_uLong nObjMask = ReadLongRes(); 124 125 if ( RSCMENUBUTTON_MENU & nObjMask ) 126 { 127 mpOwnMenu = new PopupMenu( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ); 128 SetPopupMenu( mpOwnMenu ); 129 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 130 } 131 } 132 133 // ----------------------------------------------------------------------- 134 135 MenuButton::~MenuButton() 136 { 137 if ( mpMenuTimer ) 138 delete mpMenuTimer; 139 if ( mpOwnMenu ) 140 delete mpOwnMenu; 141 } 142 143 // ----------------------------------------------------------------------- 144 145 IMPL_LINK( MenuButton, ImplMenuTimeoutHdl, Timer*, EMPTYARG ) 146 { 147 // Abfragen, ob Button-Benutzung noch aktiv ist, da diese ja auch 148 // vorher abgebrochen wurden sein koennte 149 if ( IsTracking() ) 150 { 151 if ( !(GetStyle() & WB_NOPOINTERFOCUS) ) 152 GrabFocus(); 153 ImplExecuteMenu(); 154 } 155 156 return 0; 157 } 158 159 // ----------------------------------------------------------------------- 160 161 void MenuButton::MouseButtonDown( const MouseEvent& rMEvt ) 162 { 163 bool bExecute = true; 164 if ( mnMenuMode & MENUBUTTON_MENUMODE_TIMED ) 165 { 166 // if the separated dropdown symbol is hit, 167 // execute the popup immediately 168 if( ! ImplGetSymbolRect().IsInside( rMEvt.GetPosPixel() ) ) 169 { 170 if ( !mpMenuTimer ) 171 { 172 mpMenuTimer = new Timer; 173 mpMenuTimer->SetTimeoutHdl( LINK( this, MenuButton, ImplMenuTimeoutHdl ) ); 174 } 175 176 mpMenuTimer->SetTimeout( GetSettings().GetMouseSettings().GetActionDelay() ); 177 mpMenuTimer->Start(); 178 179 PushButton::MouseButtonDown( rMEvt ); 180 bExecute = false; 181 } 182 } 183 if( bExecute ) 184 { 185 if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) ) 186 { 187 if ( !(GetStyle() & WB_NOPOINTERFOCUS) ) 188 GrabFocus(); 189 ImplExecuteMenu(); 190 } 191 } 192 } 193 194 // ----------------------------------------------------------------------- 195 196 void MenuButton::KeyInput( const KeyEvent& rKEvt ) 197 { 198 KeyCode aKeyCode = rKEvt.GetKeyCode(); 199 sal_uInt16 nCode = aKeyCode.GetCode(); 200 if ( (nCode == KEY_DOWN) && aKeyCode.IsMod2() ) 201 ImplExecuteMenu(); 202 else if ( !(mnMenuMode & MENUBUTTON_MENUMODE_TIMED) && 203 !aKeyCode.GetModifier() && 204 ((nCode == KEY_RETURN) || (nCode == KEY_SPACE)) ) 205 ImplExecuteMenu(); 206 else 207 PushButton::KeyInput( rKEvt ); 208 } 209 210 // ----------------------------------------------------------------------- 211 212 void MenuButton::Activate() 213 { 214 maActivateHdl.Call( this ); 215 } 216 217 // ----------------------------------------------------------------------- 218 219 void MenuButton::Select() 220 { 221 maSelectHdl.Call( this ); 222 } 223 224 // ----------------------------------------------------------------------- 225 226 void MenuButton::SetMenuMode( sal_uInt16 nMode ) 227 { 228 // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann 229 // diese Funktion zur 6.0 inline werden 230 mnMenuMode = nMode; 231 } 232 233 // ----------------------------------------------------------------------- 234 235 void MenuButton::SetPopupMenu( PopupMenu* pNewMenu ) 236 { 237 // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann 238 // diese Funktion zur 6.0 inline werden 239 mpMenu = pNewMenu; 240 } 241