1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_toolkit.hxx"
26
27 #include <toolkit/awt/vclxmenu.hxx>
28 #include <toolkit/helper/convert.hxx>
29 #include <toolkit/helper/macros.hxx>
30 #include <toolkit/helper/servicenames.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32
33 #include <cppuhelper/typeprovider.hxx>
34 #include <rtl/memory.h>
35 #include <rtl/ustrbuf.hxx>
36 #include <rtl/uuid.h>
37 #include <vcl/image.hxx>
38 #include <vcl/keycod.hxx>
39 #include <vcl/menu.hxx>
40 #include <vcl/mnemonic.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vos/mutex.hxx>
43
44 #include <com/sun/star/awt/KeyModifier.hpp>
45
46 using rtl::OUString;
47 using rtl::OUStringBuffer;
48
49
DBG_NAME(VCLXMenu)50 DBG_NAME(VCLXMenu)
51
52 VCLXMenu::VCLXMenu()
53 : maMenuListeners( *this )
54 {
55 DBG_CTOR( VCLXMenu, 0 );
56 mpMenu = NULL;
57 }
58
VCLXMenu(Menu * pMenu)59 VCLXMenu::VCLXMenu( Menu* pMenu )
60 : maMenuListeners( *this )
61 {
62 DBG_CTOR( VCLXMenu, 0 );
63 mpMenu = pMenu;
64 }
65
~VCLXMenu()66 VCLXMenu::~VCLXMenu()
67 {
68 DBG_DTOR( VCLXMenu, 0 );
69 for ( sal_uInt32 n = maPopupMenueRefs.Count(); n; )
70 {
71 css::uno::Reference< css::awt::XPopupMenu > * pRef = maPopupMenueRefs.GetObject( --n );
72 delete pRef;
73 }
74 if ( mpMenu )
75 {
76 mpMenu->RemoveEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
77 delete mpMenu;
78 }
79 }
80
IsPopupMenu() const81 sal_Bool VCLXMenu::IsPopupMenu() const
82 {
83 return (mpMenu && ! mpMenu->IsMenuBar());
84 }
85
ImplCreateMenu(sal_Bool bPopup)86 void VCLXMenu::ImplCreateMenu( sal_Bool bPopup )
87 {
88 DBG_ASSERT( !mpMenu, "CreateMenu: Menu exists!" );
89
90 if ( bPopup )
91 mpMenu = new PopupMenu;
92 else
93 mpMenu = new MenuBar;
94
95 mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
96 }
97
IMPL_LINK(VCLXMenu,MenuEventListener,VclSimpleEvent *,pEvent)98 IMPL_LINK( VCLXMenu, MenuEventListener, VclSimpleEvent*, pEvent )
99 {
100 DBG_ASSERT( pEvent && pEvent->ISA( VclMenuEvent ), "Unknown Event!" );
101 if ( pEvent && pEvent->ISA( VclMenuEvent ) )
102 {
103 DBG_ASSERT( ((VclMenuEvent*)pEvent)->GetMenu() && mpMenu, "Menu???" );
104
105 VclMenuEvent* pMenuEvent = (VclMenuEvent*)pEvent;
106 if ( pMenuEvent->GetMenu() == mpMenu ) // Also called for the root menu
107 {
108 switch ( pMenuEvent->GetId() )
109 {
110 case VCLEVENT_MENU_SELECT:
111 {
112 if ( maMenuListeners.getLength() )
113 {
114 css::awt::MenuEvent aEvent;
115 aEvent.Source = (::cppu::OWeakObject*)this;
116 aEvent.MenuId = mpMenu->GetCurItemId();
117 maMenuListeners.itemSelected( aEvent );
118 }
119 }
120 break;
121 case VCLEVENT_OBJECT_DYING:
122 {
123 mpMenu = NULL;
124 }
125 break;
126 case VCLEVENT_MENU_HIGHLIGHT:
127 {
128 if ( maMenuListeners.getLength() )
129 {
130 css::awt::MenuEvent aEvent;
131 aEvent.Source = (::cppu::OWeakObject*)this;
132 aEvent.MenuId = mpMenu->GetCurItemId();
133 maMenuListeners.itemHighlighted( aEvent );
134 }
135 }
136 break;
137 case VCLEVENT_MENU_ACTIVATE:
138 {
139 if ( maMenuListeners.getLength() )
140 {
141 css::awt::MenuEvent aEvent;
142 aEvent.Source = (::cppu::OWeakObject*)this;
143 aEvent.MenuId = mpMenu->GetCurItemId();
144 maMenuListeners.itemActivated( aEvent );
145 }
146 }
147 break;
148 case VCLEVENT_MENU_DEACTIVATE:
149 {
150 if ( maMenuListeners.getLength() )
151 {
152 css::awt::MenuEvent aEvent;
153 aEvent.Source = (::cppu::OWeakObject*)this;
154 aEvent.MenuId = mpMenu->GetCurItemId();
155 maMenuListeners.itemDeactivated( aEvent );
156 }
157 }
158 break;
159
160 // ignore accessibility events
161 case VCLEVENT_MENU_ENABLE:
162 case VCLEVENT_MENU_INSERTITEM:
163 case VCLEVENT_MENU_REMOVEITEM:
164 case VCLEVENT_MENU_SUBMENUACTIVATE:
165 case VCLEVENT_MENU_SUBMENUDEACTIVATE:
166 case VCLEVENT_MENU_SUBMENUCHANGED:
167 case VCLEVENT_MENU_DEHIGHLIGHT:
168 case VCLEVENT_MENU_DISABLE:
169 case VCLEVENT_MENU_ITEMTEXTCHANGED:
170 case VCLEVENT_MENU_ITEMCHECKED:
171 case VCLEVENT_MENU_ITEMUNCHECKED:
172 case VCLEVENT_MENU_SHOW:
173 case VCLEVENT_MENU_HIDE:
174 break;
175
176 default: DBG_ERROR( "MenuEventListener - Unknown event!" );
177 }
178 }
179 }
180 return 0;
181 }
182
183
getImplementationName()184 OUString SAL_CALL VCLXMenu::getImplementationName( )
185 throw (css::uno::RuntimeException)
186 {
187 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() );
188 const sal_Bool bIsPopupMenu = IsPopupMenu();
189 aGuard.clear();
190
191 OUStringBuffer implName;
192 implName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "stardiv.Toolkit." ) );
193 if ( bIsPopupMenu )
194 implName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VCLXPopupMenu" ) );
195 else
196 implName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VCLXMenuBar" ) );
197
198 return implName.makeStringAndClear();
199 }
200
201
getSupportedServiceNames()202 css::uno::Sequence< OUString > SAL_CALL VCLXMenu::getSupportedServiceNames( )
203 throw (css::uno::RuntimeException)
204 {
205 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() );
206 const sal_Bool bIsPopupMenu = IsPopupMenu();
207 aGuard.clear();
208
209 css::uno::Sequence< OUString > aNames( 1 );
210 if ( bIsPopupMenu )
211 aNames[ 0 ] = OUString::createFromAscii( szServiceName2_PopupMenu );
212 else
213 aNames[ 0 ] = OUString::createFromAscii( szServiceName2_MenuBar );
214
215 return aNames;
216 }
217
218
supportsService(const OUString & rServiceName)219 ::sal_Bool SAL_CALL VCLXMenu::supportsService(
220 const OUString& rServiceName )
221 throw (css::uno::RuntimeException)
222 {
223 css::uno::Sequence< OUString > aServiceNames( getSupportedServiceNames() );
224
225 if ( aServiceNames[ 0 ] == rServiceName )
226 return sal_True;
227
228 return sal_False;
229 }
230
231
queryInterface(const css::uno::Type & rType)232 css::uno::Any VCLXMenu::queryInterface(
233 const css::uno::Type & rType )
234 throw(css::uno::RuntimeException)
235 {
236 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() );
237 const sal_Bool bIsPopupMenu = IsPopupMenu();
238 aGuard.clear();
239
240 css::uno::Any aRet;
241
242 if ( bIsPopupMenu )
243 aRet = ::cppu::queryInterface( rType,
244 SAL_STATIC_CAST( css::awt::XMenu*, (css::awt::XPopupMenu*) this ),
245 SAL_STATIC_CAST( css::awt::XPopupMenu*, this ),
246 SAL_STATIC_CAST( css::lang::XTypeProvider*, this ),
247 SAL_STATIC_CAST( css::lang::XServiceInfo*, this ),
248 SAL_STATIC_CAST( css::lang::XUnoTunnel*, this ) );
249 else
250 aRet = ::cppu::queryInterface( rType,
251 SAL_STATIC_CAST( css::awt::XMenu*, (css::awt::XMenuBar*) this ),
252 SAL_STATIC_CAST( css::awt::XMenuBar*, this ),
253 SAL_STATIC_CAST( css::lang::XTypeProvider*, this ),
254 SAL_STATIC_CAST( css::lang::XServiceInfo*, this ),
255 SAL_STATIC_CAST( css::lang::XUnoTunnel*, this ) );
256
257 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
258 }
259
260
IMPL_XUNOTUNNEL(VCLXMenu)261 IMPL_XUNOTUNNEL( VCLXMenu )
262
263
264 css::uno::Sequence< css::uno::Type > VCLXMenu::getTypes()
265 throw(css::uno::RuntimeException)
266 {
267 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() );
268 const sal_Bool bIsPopupMenu = IsPopupMenu();
269 aGuard.clear();
270
271 static ::cppu::OTypeCollection* pCollectionMenuBar = NULL;
272 static ::cppu::OTypeCollection* pCollectionPopupMenu = NULL;
273
274 if ( bIsPopupMenu )
275 {
276 if( !pCollectionPopupMenu )
277 {
278 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() );
279 if( !pCollectionPopupMenu )
280 {
281 static ::cppu::OTypeCollection collectionPopupMenu(
282 getCppuType( ( css::uno::Reference< css::lang::XTypeProvider>* ) NULL ),
283 getCppuType( ( css::uno::Reference< css::awt::XMenu>* ) NULL ),
284 getCppuType( ( css::uno::Reference< css::awt::XPopupMenu>* ) NULL ),
285 getCppuType( ( css::uno::Reference< css::lang::XServiceInfo>* ) NULL ) );
286 pCollectionPopupMenu = &collectionPopupMenu;
287 }
288 }
289
290 return (*pCollectionPopupMenu).getTypes();
291 }
292 else
293 {
294 if( !pCollectionMenuBar )
295 {
296 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() );
297 if( !pCollectionMenuBar )
298 {
299 static ::cppu::OTypeCollection collectionMenuBar(
300 getCppuType( ( css::uno::Reference< css::lang::XTypeProvider>* ) NULL ),
301 getCppuType( ( css::uno::Reference< css::awt::XMenu>* ) NULL ),
302 getCppuType( ( css::uno::Reference< css::awt::XMenuBar>* ) NULL ),
303 getCppuType( ( css::uno::Reference< css::lang::XServiceInfo>* ) NULL ) );
304 pCollectionMenuBar = &collectionMenuBar;
305 }
306 }
307 return (*pCollectionMenuBar).getTypes();
308 }
309 }
310
311
getImplementationId()312 css::uno::Sequence< sal_Int8 > VCLXMenu::getImplementationId()
313 throw(css::uno::RuntimeException)
314 {
315 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() );
316 const sal_Bool bIsPopupMenu = IsPopupMenu();
317 aGuard.clear();
318
319 static ::cppu::OImplementationId* pIdMenuBar = NULL;
320 static ::cppu::OImplementationId* pIdPopupMenu = NULL;
321
322 if ( bIsPopupMenu )
323 {
324 if( !pIdPopupMenu )
325 {
326 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() );
327 if( !pIdPopupMenu )
328 {
329 static ::cppu::OImplementationId idPopupMenu( sal_False );
330 pIdPopupMenu = &idPopupMenu;
331 }
332 }
333
334 return (*pIdPopupMenu).getImplementationId();
335 }
336 else
337 {
338 if( !pIdMenuBar )
339 {
340 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() );
341 if( !pIdMenuBar )
342 {
343 static ::cppu::OImplementationId idMenuBar( sal_False );
344 pIdMenuBar = &idMenuBar;
345 }
346 }
347
348 return (*pIdMenuBar).getImplementationId();
349 }
350 }
351
addMenuListener(const css::uno::Reference<css::awt::XMenuListener> & rxListener)352 void VCLXMenu::addMenuListener(
353 const css::uno::Reference< css::awt::XMenuListener >& rxListener )
354 throw(css::uno::RuntimeException)
355 {
356 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
357
358 maMenuListeners.addInterface( rxListener );
359 }
360
removeMenuListener(const css::uno::Reference<css::awt::XMenuListener> & rxListener)361 void VCLXMenu::removeMenuListener(
362 const css::uno::Reference< css::awt::XMenuListener >& rxListener )
363 throw(css::uno::RuntimeException)
364 {
365 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
366
367 maMenuListeners.removeInterface( rxListener );
368 }
369
insertItem(sal_Int16 nItemId,const OUString & aText,sal_Int16 nItemStyle,sal_Int16 nPos)370 void VCLXMenu::insertItem(
371 sal_Int16 nItemId,
372 const OUString& aText,
373 sal_Int16 nItemStyle,
374 sal_Int16 nPos )
375 throw(css::uno::RuntimeException)
376 {
377 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
378 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
379
380 if ( mpMenu )
381 mpMenu->InsertItem( nItemId, aText, (MenuItemBits)nItemStyle, nPos );
382 }
383
removeItem(sal_Int16 nPos,sal_Int16 nCount)384 void VCLXMenu::removeItem(
385 sal_Int16 nPos,
386 sal_Int16 nCount )
387 throw(css::uno::RuntimeException)
388 {
389 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
390 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
391
392 sal_Int32 nItemCount = (sal_Int32)mpMenu->GetItemCount();
393 if ( mpMenu && ( nCount > 0 ) && ( nPos >= 0 ) && ( nPos < nItemCount ) && ( nItemCount > 0 ))
394 {
395 sal_Int16 nP = sal::static_int_cast< sal_Int16 >(
396 Min( (int)(nPos+nCount), (int)nItemCount ));
397 while( nP-nPos > 0 )
398 mpMenu->RemoveItem( --nP );
399 }
400 }
401
getItemCount()402 sal_Int16 VCLXMenu::getItemCount( )
403 throw(css::uno::RuntimeException)
404 {
405 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
406 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
407
408 return mpMenu ? mpMenu->GetItemCount() : 0;
409 }
410
getItemId(sal_Int16 nPos)411 sal_Int16 VCLXMenu::getItemId(
412 sal_Int16 nPos )
413 throw(css::uno::RuntimeException)
414 {
415 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
416 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
417
418 return mpMenu ? mpMenu->GetItemId( nPos ) : 0;
419 }
420
getItemPos(sal_Int16 nId)421 sal_Int16 VCLXMenu::getItemPos(
422 sal_Int16 nId )
423 throw(css::uno::RuntimeException)
424 {
425 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
426 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
427
428 return mpMenu ? mpMenu->GetItemPos( nId ) : 0;
429 }
430
enableItem(sal_Int16 nItemId,sal_Bool bEnable)431 void VCLXMenu::enableItem(
432 sal_Int16 nItemId,
433 sal_Bool bEnable )
434 throw(css::uno::RuntimeException)
435 {
436 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
437 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
438
439 if ( mpMenu )
440 mpMenu->EnableItem( nItemId, bEnable );
441 }
442
isItemEnabled(sal_Int16 nItemId)443 sal_Bool VCLXMenu::isItemEnabled(
444 sal_Int16 nItemId )
445 throw(css::uno::RuntimeException)
446 {
447 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
448 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
449
450 return mpMenu ? mpMenu->IsItemEnabled( nItemId ) : sal_False;
451 }
452
setItemText(sal_Int16 nItemId,const OUString & aText)453 void VCLXMenu::setItemText(
454 sal_Int16 nItemId,
455 const OUString& aText )
456 throw(css::uno::RuntimeException)
457 {
458 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
459 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
460
461 if ( mpMenu )
462 mpMenu->SetItemText( nItemId, aText );
463 }
464
getItemText(sal_Int16 nItemId)465 OUString VCLXMenu::getItemText(
466 sal_Int16 nItemId )
467 throw(css::uno::RuntimeException)
468 {
469 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
470 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
471
472 OUString aItemText;
473 if ( mpMenu )
474 aItemText = mpMenu->GetItemText( nItemId );
475 return aItemText;
476 }
477
setPopupMenu(sal_Int16 nItemId,const css::uno::Reference<css::awt::XPopupMenu> & rxPopupMenu)478 void VCLXMenu::setPopupMenu(
479 sal_Int16 nItemId,
480 const css::uno::Reference< css::awt::XPopupMenu >& rxPopupMenu )
481 throw(css::uno::RuntimeException)
482 {
483 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
484 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
485
486 VCLXMenu* pVCLMenu = VCLXMenu::GetImplementation( rxPopupMenu );
487 DBG_ASSERT( pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu(), "setPopupMenu: Invalid Menu!" );
488
489 if ( mpMenu && pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu() )
490 {
491 // Selbst eine Ref halten!
492 css::uno::Reference< css::awt::XPopupMenu > * pNewRef = new css::uno::Reference< css::awt::XPopupMenu > ;
493 *pNewRef = rxPopupMenu;
494 maPopupMenueRefs.Insert( pNewRef, LIST_APPEND );
495
496 mpMenu->SetPopupMenu( nItemId, (PopupMenu*) pVCLMenu->GetMenu() );
497 }
498 }
499
getPopupMenu(sal_Int16 nItemId)500 css::uno::Reference< css::awt::XPopupMenu > VCLXMenu::getPopupMenu(
501 sal_Int16 nItemId )
502 throw(css::uno::RuntimeException)
503 {
504 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
505 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
506
507 css::uno::Reference< css::awt::XPopupMenu > aRef;
508 Menu* pMenu = mpMenu ? mpMenu->GetPopupMenu( nItemId ) : NULL;
509 if ( pMenu )
510 {
511 for ( sal_uInt32 n = maPopupMenueRefs.Count(); n; )
512 {
513 css::uno::Reference< css::awt::XPopupMenu > * pRef = maPopupMenueRefs.GetObject( --n );
514 Menu* pM = ((VCLXMenu*)pRef->get())->GetMenu();
515 if ( pM == pMenu )
516 {
517 aRef = *pRef;
518 break;
519 }
520 }
521 }
522 return aRef;
523 }
524
525 // css::awt::XPopupMenu
insertSeparator(sal_Int16 nPos)526 void VCLXMenu::insertSeparator(
527 sal_Int16 nPos )
528 throw(css::uno::RuntimeException)
529 {
530 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
531 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
532
533 if ( mpMenu )
534 mpMenu->InsertSeparator( nPos );
535 }
536
setDefaultItem(sal_Int16 nItemId)537 void VCLXMenu::setDefaultItem(
538 sal_Int16 nItemId )
539 throw(css::uno::RuntimeException)
540 {
541 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
542 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
543
544 if ( mpMenu )
545 mpMenu->SetDefaultItem( nItemId );
546 }
547
getDefaultItem()548 sal_Int16 VCLXMenu::getDefaultItem( )
549 throw(css::uno::RuntimeException)
550 {
551 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
552 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
553
554 return mpMenu ? mpMenu->GetDefaultItem() : 0;
555 }
556
checkItem(sal_Int16 nItemId,sal_Bool bCheck)557 void VCLXMenu::checkItem(
558 sal_Int16 nItemId,
559 sal_Bool bCheck )
560 throw(css::uno::RuntimeException)
561 {
562 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
563 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
564
565 if ( mpMenu )
566 mpMenu->CheckItem( nItemId, bCheck );
567 }
568
isItemChecked(sal_Int16 nItemId)569 sal_Bool VCLXMenu::isItemChecked(
570 sal_Int16 nItemId )
571 throw(css::uno::RuntimeException)
572 {
573 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
574 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
575
576 return mpMenu ? mpMenu->IsItemChecked( nItemId ) : sal_False;
577 }
578
execute(const css::uno::Reference<css::awt::XWindowPeer> & rxWindowPeer,const css::awt::Rectangle & rPos,sal_Int16 nFlags)579 sal_Int16 VCLXMenu::execute(
580 const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer,
581 const css::awt::Rectangle& rPos,
582 sal_Int16 nFlags )
583 throw(css::uno::RuntimeException)
584 {
585 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
586 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
587
588 sal_Int16 nRet = 0;
589 if ( mpMenu && IsPopupMenu() )
590 {
591 nRet = ((PopupMenu*)mpMenu)->Execute( VCLUnoHelper::GetWindow( rxWindowPeer ),
592 VCLRectangle( rPos ),
593 nFlags | POPUPMENU_NOMOUSEUPCLOSE );
594 }
595 return nRet;
596 }
597
598
setCommand(sal_Int16 nItemId,const OUString & aCommand)599 void SAL_CALL VCLXMenu::setCommand(
600 sal_Int16 nItemId,
601 const OUString& aCommand )
602 throw (css::uno::RuntimeException)
603 {
604 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
605 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
606
607 if ( mpMenu )
608 mpMenu->SetItemCommand( nItemId, aCommand );
609 }
610
getCommand(sal_Int16 nItemId)611 OUString SAL_CALL VCLXMenu::getCommand(
612 sal_Int16 nItemId )
613 throw (css::uno::RuntimeException)
614 {
615 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
616 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
617
618 OUString aItemCommand;
619 if ( mpMenu )
620 aItemCommand = mpMenu->GetItemCommand( nItemId );
621 return aItemCommand;
622 }
623
setHelpCommand(sal_Int16 nItemId,const OUString & aHelp)624 void SAL_CALL VCLXMenu::setHelpCommand(
625 sal_Int16 nItemId,
626 const OUString& aHelp )
627 throw (css::uno::RuntimeException)
628 {
629 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
630 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
631
632 if ( mpMenu )
633 mpMenu->SetHelpCommand( nItemId, aHelp );
634 }
635
getHelpCommand(sal_Int16 nItemId)636 OUString SAL_CALL VCLXMenu::getHelpCommand(
637 sal_Int16 nItemId )
638 throw (css::uno::RuntimeException)
639 {
640 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
641 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
642
643 OUString aHelpCommand;
644 if ( mpMenu )
645 aHelpCommand = mpMenu->GetHelpCommand( nItemId );
646 return aHelpCommand;
647 }
648
649
650 namespace
651 {
lcl_XGraphic2VCLImage(const css::uno::Reference<css::graphic::XGraphic> & xGraphic,sal_Bool bResize)652 static Image lcl_XGraphic2VCLImage(
653 const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
654 sal_Bool bResize )
655 {
656 Image aImage;
657 if ( !xGraphic.is() )
658 return aImage;
659
660 aImage = Image( xGraphic );
661 const ::Size aCurSize = aImage.GetSizePixel();
662 const sal_Int32 nCurWidth = aCurSize.Width();
663 const sal_Int32 nCurHeight = aCurSize.Height();
664 const sal_Int32 nIdeal( 16 );
665
666 if ( nCurWidth > 0 && nCurHeight > 0 )
667 {
668 if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) )
669 {
670 sal_Int32 nIdealWidth = nCurWidth > nIdeal ? nIdeal : nCurWidth;
671 sal_Int32 nIdealHeight = nCurHeight > nIdeal ? nIdeal : nCurHeight;
672
673 ::Size aNewSize( nIdealWidth, nIdealHeight );
674
675 sal_Bool bModified( sal_False );
676 BitmapEx aBitmapEx = aImage.GetBitmapEx();
677 bModified = aBitmapEx.Scale( aNewSize, BMP_SCALE_INTERPOLATE );
678
679 if ( bModified )
680 aImage = Image( aBitmapEx );
681 }
682 }
683 return aImage;
684 }
685
686 /** Copied from svtools/inc/acceleratorexecute.hxx */
lcl_VCLKey2AWTKey(const KeyCode & aVCLKey)687 static css::awt::KeyEvent lcl_VCLKey2AWTKey(
688 const KeyCode& aVCLKey)
689 {
690 css::awt::KeyEvent aAWTKey;
691 aAWTKey.Modifiers = 0;
692 aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode();
693
694 if (aVCLKey.IsShift())
695 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
696 if (aVCLKey.IsMod1())
697 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
698 if (aVCLKey.IsMod2())
699 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
700 if (aVCLKey.IsMod3())
701 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
702
703 return aAWTKey;
704 }
705
lcl_AWTKey2VCLKey(const css::awt::KeyEvent & aAWTKey)706 KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
707 {
708 sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
709 sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 );
710 sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 );
711 sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 );
712 sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode;
713
714 return KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
715 }
716
717 }
718
719
isPopupMenu()720 ::sal_Bool SAL_CALL VCLXMenu::isPopupMenu( )
721 throw (css::uno::RuntimeException)
722 {
723 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
724 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
725 return IsPopupMenu();
726 }
727
clear()728 void SAL_CALL VCLXMenu::clear( )
729 throw (css::uno::RuntimeException)
730 {
731 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
732 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
733 if ( mpMenu )
734 mpMenu->Clear();
735 }
736
737
getItemType(::sal_Int16 nItemPos)738 css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType(
739 ::sal_Int16 nItemPos )
740 throw (css::uno::RuntimeException)
741 {
742 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
743 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
744
745 css::awt::MenuItemType aMenuItemType =
746 css::awt::MenuItemType_DONTKNOW;
747 if ( mpMenu )
748 {
749 aMenuItemType = ( (css::awt::MenuItemType) mpMenu->GetItemType( nItemPos ) );
750 }
751
752 return aMenuItemType;
753 }
754
hideDisabledEntries(::sal_Bool bHide)755 void SAL_CALL VCLXMenu::hideDisabledEntries(
756 ::sal_Bool bHide )
757 throw (css::uno::RuntimeException)
758 {
759 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
760 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
761 if ( mpMenu )
762 {
763 if ( bHide )
764 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
765 else
766 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MENU_FLAG_HIDEDISABLEDENTRIES );
767 }
768 }
769
770
isInExecute()771 ::sal_Bool SAL_CALL VCLXMenu::isInExecute( )
772 throw (css::uno::RuntimeException)
773 {
774 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
775 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
776
777 if ( mpMenu && IsPopupMenu() )
778 return ( (PopupMenu*) mpMenu )->IsInExecute();
779 else
780 return sal_False;
781 }
782
783
endExecute()784 void SAL_CALL VCLXMenu::endExecute()
785 throw (css::uno::RuntimeException)
786 {
787 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
788 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
789
790 if ( mpMenu && IsPopupMenu() )
791 ( (PopupMenu*) mpMenu )->EndExecute();
792 }
793
794
enableAutoMnemonics(::sal_Bool bEnable)795 void SAL_CALL VCLXMenu::enableAutoMnemonics(
796 ::sal_Bool bEnable )
797 throw (css::uno::RuntimeException)
798 {
799 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
800 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
801 if ( mpMenu )
802 {
803 if ( !bEnable )
804 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
805 else
806 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MENU_FLAG_NOAUTOMNEMONICS );
807 }
808 }
809
810
setAcceleratorKeyEvent(::sal_Int16 nItemId,const css::awt::KeyEvent & aKeyEvent)811 void SAL_CALL VCLXMenu::setAcceleratorKeyEvent(
812 ::sal_Int16 nItemId,
813 const css::awt::KeyEvent& aKeyEvent )
814 throw (css::uno::RuntimeException)
815 {
816 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
817 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
818
819 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
820 {
821 KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent );
822 mpMenu->SetAccelKey( nItemId, aVCLKeyCode );
823 }
824 }
825
826
getAcceleratorKeyEvent(::sal_Int16 nItemId)827 css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent(
828 ::sal_Int16 nItemId )
829 throw (css::uno::RuntimeException)
830 {
831 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
832 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
833
834 css::awt::KeyEvent aKeyEvent;
835 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
836 {
837 KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId );
838 aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode );
839 }
840
841 return aKeyEvent;
842 }
843
844
setHelpText(::sal_Int16 nItemId,const OUString & sHelpText)845 void SAL_CALL VCLXMenu::setHelpText(
846 ::sal_Int16 nItemId,
847 const OUString& sHelpText )
848 throw (css::uno::RuntimeException)
849 {
850 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
851 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
852
853 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
854 {
855 mpMenu->SetHelpText( nItemId, sHelpText );
856 }
857 }
858
859
getHelpText(::sal_Int16 nItemId)860 OUString SAL_CALL VCLXMenu::getHelpText(
861 ::sal_Int16 nItemId )
862 throw (css::uno::RuntimeException)
863 {
864 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
865 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
866
867 rtl::OUString sHelpText;
868 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
869 {
870 sHelpText = mpMenu->GetHelpText( nItemId );
871 }
872
873 return sHelpText;
874 }
875
876
setTipHelpText(::sal_Int16 nItemId,const OUString & sTipHelpText)877 void SAL_CALL VCLXMenu::setTipHelpText(
878 ::sal_Int16 nItemId,
879 const OUString& sTipHelpText )
880 throw (css::uno::RuntimeException)
881 {
882 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
883 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
884
885 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
886 {
887 mpMenu->SetTipHelpText( nItemId, sTipHelpText );
888 }
889 }
890
891
getTipHelpText(::sal_Int16 nItemId)892 OUString SAL_CALL VCLXMenu::getTipHelpText(
893 ::sal_Int16 nItemId )
894 throw (css::uno::RuntimeException)
895 {
896 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
897 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
898
899 rtl::OUString sTipHelpText;
900 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
901 {
902 sTipHelpText = mpMenu->GetTipHelpText( nItemId );
903 }
904 return sTipHelpText;
905 }
906
907
setItemImage(::sal_Int16 nItemId,const css::uno::Reference<css::graphic::XGraphic> & xGraphic,::sal_Bool bScale)908 void SAL_CALL VCLXMenu::setItemImage(
909 ::sal_Int16 nItemId,
910 const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
911 ::sal_Bool bScale )
912 throw (css::uno::RuntimeException)
913 {
914 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
915 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
916
917 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
918 {
919 Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale );
920 mpMenu->SetItemImage( nItemId, aImage );
921 }
922 }
923
924
925 css::uno::Reference< css::graphic::XGraphic > SAL_CALL
getItemImage(::sal_Int16 nItemId)926 VCLXMenu::getItemImage(
927 ::sal_Int16 nItemId )
928 throw (css::uno::RuntimeException)
929 {
930 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
931 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
932
933 css::uno::Reference< css::graphic::XGraphic > rxGraphic;
934
935 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
936 {
937 Image aImage = mpMenu->GetItemImage( nItemId );
938 if ( !!aImage )
939 rxGraphic = aImage.GetXGraphic();
940 }
941 return rxGraphic;
942 }
943
944
945
946 DBG_NAME(VCLXMenuBar);
947
VCLXMenuBar()948 VCLXMenuBar::VCLXMenuBar()
949 {
950 DBG_CTOR( VCLXMenuBar, 0 );
951 ImplCreateMenu( sal_False );
952 }
953
VCLXMenuBar(MenuBar * pMenuBar)954 VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( (Menu *)pMenuBar )
955 {
956 DBG_CTOR( VCLXMenuBar, 0 );
957 }
958
959
960 DBG_NAME(VCLXPopupMenu);
961
VCLXPopupMenu()962 VCLXPopupMenu::VCLXPopupMenu()
963 {
964 DBG_CTOR( VCLXPopupMenu, 0 );
965 ImplCreateMenu( sal_True );
966 }
967