xref: /trunk/main/toolkit/source/awt/vclxmenu.cxx (revision d026be40)
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 
50 DBG_NAME(VCLXMenu)
51 
52 VCLXMenu::VCLXMenu()
53     : maMenuListeners( *this )
54 {
55     DBG_CTOR( VCLXMenu, 0 );
56     mpMenu = NULL;
57 }
58 
59 VCLXMenu::VCLXMenu( Menu* pMenu )
60     : maMenuListeners( *this )
61 {
62     DBG_CTOR( VCLXMenu, 0 );
63     mpMenu = pMenu;
64 }
65 
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 
81 sal_Bool VCLXMenu::IsPopupMenu() const
82 {
83     return (mpMenu && ! mpMenu->IsMenuBar());
84 }
85 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
579 sal_Int16 VCLXMenu::execute(
580     const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer,
581     const css::awt::Point& 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         const ::Point aPoint = VCLPoint( rPos );
592         nRet = ((PopupMenu*)mpMenu)->Execute( VCLUnoHelper::GetWindow( rxWindowPeer ),
593                                               ::Rectangle(aPoint,aPoint),
594                                               nFlags | POPUPMENU_NOMOUSEUPCLOSE );
595     }
596     return nRet;
597 }
598 
599 
600 void SAL_CALL VCLXMenu::setCommand(
601     sal_Int16 nItemId,
602     const OUString& aCommand )
603 throw (css::uno::RuntimeException)
604 {
605     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
606     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
607 
608     if ( mpMenu )
609         mpMenu->SetItemCommand( nItemId, aCommand );
610 }
611 
612 OUString SAL_CALL VCLXMenu::getCommand(
613     sal_Int16 nItemId )
614 throw (css::uno::RuntimeException)
615 {
616     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
617     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
618 
619     OUString aItemCommand;
620     if ( mpMenu )
621         aItemCommand = mpMenu->GetItemCommand( nItemId );
622     return aItemCommand;
623 }
624 
625 void SAL_CALL VCLXMenu::setHelpCommand(
626     sal_Int16 nItemId,
627     const OUString& aHelp )
628 throw (css::uno::RuntimeException)
629 {
630     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
631     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
632 
633     if ( mpMenu )
634         mpMenu->SetHelpCommand( nItemId, aHelp );
635 }
636 
637 OUString SAL_CALL VCLXMenu::getHelpCommand(
638     sal_Int16 nItemId )
639 throw (css::uno::RuntimeException)
640 {
641     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
642     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
643 
644     OUString aHelpCommand;
645     if ( mpMenu )
646         aHelpCommand = mpMenu->GetHelpCommand( nItemId );
647     return aHelpCommand;
648 }
649 
650 
651 namespace
652 {
653     static Image lcl_XGraphic2VCLImage(
654         const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
655         sal_Bool bResize )
656     {
657         Image aImage;
658         if ( !xGraphic.is() )
659             return aImage;
660 
661         aImage = Image( xGraphic );
662         const ::Size aCurSize = aImage.GetSizePixel();
663         const sal_Int32 nCurWidth = aCurSize.Width();
664         const sal_Int32 nCurHeight = aCurSize.Height();
665         const sal_Int32 nIdeal( 16 );
666 
667         if ( nCurWidth > 0 && nCurHeight > 0 )
668         {
669             if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) )
670             {
671                 sal_Int32 nIdealWidth  = nCurWidth  > nIdeal ? nIdeal : nCurWidth;
672                 sal_Int32 nIdealHeight = nCurHeight > nIdeal ? nIdeal : nCurHeight;
673 
674                 ::Size aNewSize( nIdealWidth, nIdealHeight );
675 
676                 sal_Bool bModified( sal_False );
677                 BitmapEx aBitmapEx = aImage.GetBitmapEx();
678                 bModified = aBitmapEx.Scale( aNewSize, BMP_SCALE_INTERPOLATE );
679 
680                 if ( bModified )
681                     aImage = Image( aBitmapEx );
682             }
683         }
684         return aImage;
685     }
686 
687     /** Copied from svtools/inc/acceleratorexecute.hxx */
688     static css::awt::KeyEvent lcl_VCLKey2AWTKey(
689         const KeyCode& aVCLKey)
690     {
691         css::awt::KeyEvent aAWTKey;
692         aAWTKey.Modifiers = 0;
693         aAWTKey.KeyCode   = (sal_Int16)aVCLKey.GetCode();
694 
695         if (aVCLKey.IsShift())
696             aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
697         if (aVCLKey.IsMod1())
698             aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
699         if (aVCLKey.IsMod2())
700             aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
701         if (aVCLKey.IsMod3())
702             aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
703 
704         return aAWTKey;
705     }
706 
707     KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
708     {
709         sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
710         sal_Bool bMod1  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1  );
711         sal_Bool bMod2  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2  );
712         sal_Bool bMod3  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3  );
713         sal_uInt16   nKey   = (sal_uInt16)aAWTKey.KeyCode;
714 
715         return KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
716     }
717 
718 }
719 
720 
721 ::sal_Bool SAL_CALL VCLXMenu::isPopupMenu(  )
722 throw (css::uno::RuntimeException)
723 {
724     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
725     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
726     return IsPopupMenu();
727 }
728 
729 void SAL_CALL VCLXMenu::clear(  )
730 throw (css::uno::RuntimeException)
731 {
732     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
733     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
734     if ( mpMenu )
735         mpMenu->Clear();
736 }
737 
738 
739 css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType(
740     ::sal_Int16 nItemPos )
741 throw (css::uno::RuntimeException)
742 {
743     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
744     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
745 
746     css::awt::MenuItemType aMenuItemType =
747         css::awt::MenuItemType_DONTKNOW;
748     if ( mpMenu )
749     {
750         aMenuItemType = ( (css::awt::MenuItemType) mpMenu->GetItemType( nItemPos ) );
751     }
752 
753     return aMenuItemType;
754 }
755 
756 void SAL_CALL VCLXMenu::hideDisabledEntries(
757     ::sal_Bool bHide )
758 throw (css::uno::RuntimeException)
759 {
760     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
761     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
762     if ( mpMenu )
763     {
764         if ( bHide )
765             mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
766         else
767             mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MENU_FLAG_HIDEDISABLEDENTRIES );
768     }
769 }
770 
771 
772 ::sal_Bool SAL_CALL VCLXMenu::isInExecute(  )
773 throw (css::uno::RuntimeException)
774 {
775     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
776     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
777 
778     if ( mpMenu && IsPopupMenu() )
779         return ( (PopupMenu*) mpMenu )->IsInExecute();
780     else
781         return sal_False;
782 }
783 
784 
785 void SAL_CALL VCLXMenu::endExecute()
786 throw (css::uno::RuntimeException)
787 {
788     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
789     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
790 
791     if ( mpMenu && IsPopupMenu() )
792         ( (PopupMenu*) mpMenu )->EndExecute();
793 }
794 
795 
796 void SAL_CALL VCLXMenu::enableAutoMnemonics(
797     ::sal_Bool bEnable )
798 throw (css::uno::RuntimeException)
799 {
800     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
801     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
802     if ( mpMenu )
803     {
804         if ( !bEnable )
805             mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
806         else
807             mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MENU_FLAG_NOAUTOMNEMONICS );
808     }
809 }
810 
811 
812 void SAL_CALL VCLXMenu::setAcceleratorKeyEvent(
813     ::sal_Int16 nItemId,
814     const css::awt::KeyEvent& aKeyEvent )
815 throw (css::uno::RuntimeException)
816 {
817     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
818     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
819 
820     if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
821     {
822         KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent );
823         mpMenu->SetAccelKey( nItemId, aVCLKeyCode );
824     }
825 }
826 
827 
828 css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent(
829     ::sal_Int16 nItemId )
830 throw (css::uno::RuntimeException)
831 {
832     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
833     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
834 
835     css::awt::KeyEvent aKeyEvent;
836     if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
837     {
838         KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId );
839         aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode );
840     }
841 
842     return aKeyEvent;
843 }
844 
845 
846 void SAL_CALL VCLXMenu::setHelpText(
847     ::sal_Int16 nItemId,
848     const OUString& sHelpText )
849 throw (css::uno::RuntimeException)
850 {
851     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
852     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
853 
854     if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
855     {
856         mpMenu->SetHelpText( nItemId, sHelpText );
857     }
858 }
859 
860 
861 OUString SAL_CALL VCLXMenu::getHelpText(
862     ::sal_Int16 nItemId )
863 throw (css::uno::RuntimeException)
864 {
865     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
866     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
867 
868     rtl::OUString sHelpText;
869     if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
870     {
871         sHelpText = mpMenu->GetHelpText( nItemId );
872     }
873 
874     return sHelpText;
875 }
876 
877 
878 void SAL_CALL VCLXMenu::setTipHelpText(
879     ::sal_Int16 nItemId,
880     const OUString& sTipHelpText )
881 throw (css::uno::RuntimeException)
882 {
883     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
884     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
885 
886     if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
887     {
888         mpMenu->SetTipHelpText( nItemId, sTipHelpText );
889     }
890 }
891 
892 
893 OUString SAL_CALL VCLXMenu::getTipHelpText(
894     ::sal_Int16 nItemId )
895 throw (css::uno::RuntimeException)
896 {
897     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
898     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
899 
900     rtl::OUString sTipHelpText;
901     if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
902     {
903         sTipHelpText = mpMenu->GetTipHelpText( nItemId );
904     }
905     return sTipHelpText;
906 }
907 
908 
909 void SAL_CALL VCLXMenu::setItemImage(
910     ::sal_Int16 nItemId,
911     const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
912     ::sal_Bool bScale )
913 throw (css::uno::RuntimeException)
914 {
915     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
916     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
917 
918     if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
919     {
920         Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale );
921         mpMenu->SetItemImage( nItemId, aImage );
922     }
923 }
924 
925 
926 css::uno::Reference< css::graphic::XGraphic > SAL_CALL
927 VCLXMenu::getItemImage(
928     ::sal_Int16 nItemId )
929 throw (css::uno::RuntimeException)
930 {
931     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
932     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
933 
934     css::uno::Reference< css::graphic::XGraphic > rxGraphic;
935 
936     if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
937     {
938         Image aImage = mpMenu->GetItemImage( nItemId );
939         if ( !!aImage )
940             rxGraphic = aImage.GetXGraphic();
941     }
942     return rxGraphic;
943 }
944 
945 
946 
947 DBG_NAME(VCLXMenuBar);
948 
949 VCLXMenuBar::VCLXMenuBar()
950 {
951     DBG_CTOR( VCLXMenuBar, 0 );
952     ImplCreateMenu( sal_False );
953 }
954 
955 VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( (Menu *)pMenuBar )
956 {
957     DBG_CTOR( VCLXMenuBar, 0 );
958 }
959 
960 
961 DBG_NAME(VCLXPopupMenu);
962 
963 VCLXPopupMenu::VCLXPopupMenu()
964 {
965     DBG_CTOR( VCLXPopupMenu, 0 );
966     ImplCreateMenu( sal_True );
967 }
968