update dev300-m58
[ooovba.git] / framework / source / dispatch / menudispatcher.cxx
blob5fd964341d2a45fa3d3a8087dd8631309acd062f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: menudispatcher.cxx,v $
10 * $Revision: 1.23.82.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
37 #include <dispatch/menudispatcher.hxx>
38 #include <general.h>
39 #include <xml/menuconfiguration.hxx>
40 #include <classes/addonmenu.hxx>
41 #include <services.h>
43 //_________________________________________________________________________________________________________________
44 // interface includes
45 //_________________________________________________________________________________________________________________
46 #include <com/sun/star/frame/FrameSearchFlag.hpp>
47 #include <com/sun/star/awt/XToolkit.hpp>
48 #include <com/sun/star/awt/WindowAttribute.hpp>
49 #include <com/sun/star/awt/WindowDescriptor.hpp>
50 #include <com/sun/star/awt/PosSize.hpp>
51 #include <com/sun/star/awt/XWindowPeer.hpp>
52 #include <com/sun/star/beans/UnknownPropertyException.hpp>
53 #include <com/sun/star/lang/WrappedTargetException.hpp>
54 #include <com/sun/star/beans/XPropertySet.hpp>
55 #include <com/sun/star/container/XEnumeration.hpp>
56 #include <com/sun/star/util/XURLTransformer.hpp>
58 #include <vcl/window.hxx>
59 #include <vcl/syswin.hxx>
60 #include <vcl/menu.hxx>
61 #include <vcl/svapp.hxx>
62 #include <tools/resmgr.hxx>
63 #include <tools/rcid.h>
64 #include <vos/mutex.hxx>
65 #include <toolkit/helper/vclunohelper.hxx>
66 #include <rtl/logfile.hxx>
68 //_________________________________________________________________________________________________________________
69 // includes of other projects
70 //_________________________________________________________________________________________________________________
72 #include <ucbhelper/content.hxx>
74 //_________________________________________________________________________________________________________________
75 // namespace
76 //_________________________________________________________________________________________________________________
78 namespace framework{
80 using namespace ::com::sun::star ;
81 using namespace ::com::sun::star::awt ;
82 using namespace ::com::sun::star::beans ;
83 using namespace ::com::sun::star::container ;
84 using namespace ::com::sun::star::frame ;
85 using namespace ::com::sun::star::lang ;
86 using namespace ::com::sun::star::uno ;
87 using namespace ::com::sun::star::util ;
88 using namespace ::cppu ;
89 using namespace ::osl ;
90 using namespace ::rtl ;
91 using namespace ::vos ;
93 //_________________________________________________________________________________________________________________
94 // non exported const
95 //_________________________________________________________________________________________________________________
97 const USHORT SLOTID_MDIWINDOWLIST = 5610;
99 //_________________________________________________________________________________________________________________
100 // non exported definitions
101 //_________________________________________________________________________________________________________________
103 //_________________________________________________________________________________________________________________
104 // declarations
105 //_________________________________________________________________________________________________________________
107 //*****************************************************************************************************************
108 // constructor
109 //*****************************************************************************************************************
110 MenuDispatcher::MenuDispatcher( const uno::Reference< XMultiServiceFactory >& xFactory ,
111 const uno::Reference< XFrame >& xOwner )
112 // Init baseclasses first
113 : ThreadHelpBase ( &Application::GetSolarMutex() )
114 , OWeakObject ( )
115 // Init member
116 , m_xOwnerWeak ( xOwner )
117 , m_xFactory ( xFactory )
118 , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
119 , m_bAlreadyDisposed ( sal_False )
120 , m_bActivateListener ( sal_False )
121 , m_pMenuManager ( NULL )
123 // Safe impossible cases
124 // We need valid informations about ouer ownerfor work.
125 LOG_ASSERT( impldbg_checkParameter_MenuDispatcher( xFactory, xOwner ), "MenuDispatcher::MenuDispatcher()\nInvalid parameter detected!\n" )
127 m_bActivateListener = sal_True;
128 xOwner->addFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
131 //*****************************************************************************************************************
132 // destructor
133 //*****************************************************************************************************************
134 MenuDispatcher::~MenuDispatcher()
136 // Warn programmer if he forgot to dispose this instance.
137 // We must release all our references ...
138 // and a dtor isn't the best place to do that!
141 //*****************************************************************************************************************
142 // XInterface, XTypeProvider
143 //*****************************************************************************************************************
144 DEFINE_XINTERFACE_4 ( MenuDispatcher ,
145 OWeakObject ,
146 DIRECT_INTERFACE( XTypeProvider ),
147 DIRECT_INTERFACE( XDispatch ),
148 DIRECT_INTERFACE( XEventListener ),
149 DERIVED_INTERFACE( XFrameActionListener, XEventListener )
152 DEFINE_XTYPEPROVIDER_4 ( MenuDispatcher ,
153 XTypeProvider ,
154 XDispatch ,
155 XEventListener ,
156 XFrameActionListener
160 //*****************************************************************************************************************
161 // XDispatch
162 //*****************************************************************************************************************
163 void SAL_CALL MenuDispatcher::dispatch( const URL& /*aURL*/ ,
164 const Sequence< PropertyValue >& /*seqProperties*/ ) throw( RuntimeException )
168 //*****************************************************************************************************************
169 // XDispatch
170 //*****************************************************************************************************************
171 void SAL_CALL MenuDispatcher::addStatusListener( const uno::Reference< XStatusListener >& xControl,
172 const URL& aURL ) throw( RuntimeException )
174 // Ready for multithreading
175 ResetableGuard aGuard( m_aLock );
176 // Safe impossible cases
177 // Method not defined for all incoming parameter
178 LOG_ASSERT( impldbg_checkParameter_addStatusListener( xControl, aURL ), "MenuDispatcher::addStatusListener()\nInvalid parameter detected.\n" )
179 // Add listener to container.
180 m_aListenerContainer.addInterface( aURL.Complete, xControl );
183 //*****************************************************************************************************************
184 // XDispatch
185 //*****************************************************************************************************************
186 void SAL_CALL MenuDispatcher::removeStatusListener( const uno::Reference< XStatusListener >& xControl,
187 const URL& aURL ) throw( RuntimeException )
189 // Ready for multithreading
190 ResetableGuard aGuard( m_aLock );
191 // Safe impossible cases
192 // Method not defined for all incoming parameter
193 LOG_ASSERT( impldbg_checkParameter_removeStatusListener( xControl, aURL ), "MenuDispatcher::removeStatusListener()\nInvalid parameter detected.\n" )
194 // Add listener to container.
195 m_aListenerContainer.removeInterface( aURL.Complete, xControl );
198 //*****************************************************************************************************************
199 // XFrameActionListener
200 //*****************************************************************************************************************
202 void SAL_CALL MenuDispatcher::frameAction( const FrameActionEvent& aEvent ) throw ( RuntimeException )
204 ResetableGuard aGuard( m_aLock );
206 if ( m_pMenuManager && aEvent.Action == FrameAction_FRAME_UI_ACTIVATED )
208 MenuBar* pMenuBar = (MenuBar *)m_pMenuManager->GetMenu();
209 uno::Reference< XFrame > xFrame( m_xOwnerWeak.get(), UNO_QUERY );
210 aGuard.unlock();
212 if ( xFrame.is() && pMenuBar )
214 uno::Reference< ::com::sun::star::awt::XWindow >xContainerWindow = xFrame->getContainerWindow();
216 OGuard aSolarGuard( Application::GetSolarMutex() );
218 Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
219 while ( pWindow && !pWindow->IsSystemWindow() )
220 pWindow = pWindow->GetParent();
222 if ( pWindow )
224 SystemWindow* pSysWindow = (SystemWindow *)pWindow;
225 pSysWindow->SetMenuBar( pMenuBar );
230 else if ( m_pMenuManager && aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING )
232 if ( m_pMenuManager )
233 impl_setMenuBar( NULL );
237 //*****************************************************************************************************************
238 // XEventListener
239 //*****************************************************************************************************************
240 void SAL_CALL MenuDispatcher::disposing( const EventObject& ) throw( RuntimeException )
242 // Ready for multithreading
243 ResetableGuard aGuard( m_aLock );
244 // Safe impossible cases
245 LOG_ASSERT( !(m_bAlreadyDisposed==sal_True), "MenuDispatcher::disposing()\nObject already disposed .. don't call it again!\n" )
247 if( m_bAlreadyDisposed == sal_False )
249 m_bAlreadyDisposed = sal_True;
251 if ( m_bActivateListener )
253 uno::Reference< XFrame > xFrame( m_xOwnerWeak.get(), UNO_QUERY );
254 if ( xFrame.is() )
256 xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
257 m_bActivateListener = sal_False;
258 if ( m_pMenuManager )
260 EventObject aEventObj;
261 aEventObj.Source = xFrame;
262 m_pMenuManager->disposing( aEventObj );
267 // Forget our factory.
268 m_xFactory = uno::Reference< XMultiServiceFactory >();
270 // Remove our menu from system window if it is still there!
271 if ( m_pMenuManager )
272 impl_setMenuBar( NULL );
276 //*****************************************************************************************************************
277 // private method
280 //*****************************************************************************************************************
281 void MenuDispatcher::impl_setAccelerators( Menu* pMenu, const Accelerator& aAccel )
283 for ( USHORT nPos = 0; nPos < pMenu->GetItemCount(); ++nPos )
285 USHORT nId = pMenu->GetItemId(nPos);
286 PopupMenu* pPopup = pMenu->GetPopupMenu(nId);
287 if ( pPopup )
288 impl_setAccelerators( (Menu *)pPopup, aAccel );
289 else if ( nId && !pMenu->GetPopupMenu(nId))
291 KeyCode aCode = aAccel.GetKeyCode( nId );
292 if ( aCode.GetCode() )
293 pMenu->SetAccelKey( nId, aCode );
298 //*****************************************************************************************************************
299 // private method
302 //*****************************************************************************************************************
303 sal_Bool MenuDispatcher::impl_setMenuBar( MenuBar* pMenuBar, sal_Bool bMenuFromResource )
305 uno::Reference< XFrame > xFrame( m_xOwnerWeak.get(), UNO_QUERY );
306 if ( xFrame.is() )
308 uno::Reference< ::com::sun::star::awt::XWindow >xContainerWindow = xFrame->getContainerWindow();
309 Window* pWindow = NULL;
311 // Use SolarMutex for threadsafe code too!
312 OGuard aSolarGuard( Application::GetSolarMutex() );
314 pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
315 while ( pWindow && !pWindow->IsSystemWindow() )
316 pWindow = pWindow->GetParent();
319 if ( pWindow )
321 // Ready for multithreading
322 ResetableGuard aGuard( m_aLock );
324 SystemWindow* pSysWindow = (SystemWindow *)pWindow;
326 if ( m_pMenuManager )
328 // remove old menu from our system window if it was set before
329 if ( m_pMenuManager->GetMenu() == (Menu *)pSysWindow->GetMenuBar() )
330 pSysWindow->SetMenuBar( NULL );
332 // remove listener before we destruct ourself, so we cannot be called back afterwards
333 m_pMenuManager->RemoveListener();
335 SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)m_pMenuManager )->release();
337 m_pMenuManager = 0;
340 if ( pMenuBar != NULL )
342 USHORT nPos = pMenuBar->GetItemPos( SLOTID_MDIWINDOWLIST );
343 if ( nPos != MENU_ITEM_NOTFOUND )
345 OUString aNoContext;
347 uno::Reference< XModel > xModel;
348 uno::Reference< XController > xController( xFrame->getController(), UNO_QUERY );
350 if ( xController.is() )
351 xModel = uno::Reference< XModel >( xController->getModel(), UNO_QUERY );
353 // retrieve addon popup menus and add them to our menu bar
354 AddonMenuManager::MergeAddonPopupMenus( xFrame, xModel, nPos, pMenuBar );
356 // retrieve addon help menu items and add them to our help menu
357 AddonMenuManager::MergeAddonHelpMenu( xFrame, pMenuBar );
360 // set new menu on our system window and create new menu manager
361 if ( bMenuFromResource )
363 // #110897#
364 // m_pMenuManager = new MenuManager( xFrame, pMenuBar, sal_True, sal_False );
365 m_pMenuManager = new MenuManager( m_xFactory, xFrame, pMenuBar, sal_True, sal_False );
367 else
369 // #110897#
370 // m_pMenuManager = new MenuManager( xFrame, pMenuBar, sal_True, sal_True );
371 m_pMenuManager = new MenuManager( m_xFactory, xFrame, pMenuBar, sal_True, sal_True );
374 pSysWindow->SetMenuBar( pMenuBar );
377 return sal_True;
381 return sal_False;
384 IMPL_LINK( MenuDispatcher, Close_Impl, void*, EMPTYARG )
386 css::uno::Reference < css::frame::XFrame > xFrame( m_xOwnerWeak.get(), css::uno::UNO_QUERY );
387 if ( !xFrame.is() )
388 return 0;
390 css::util::URL aURL;
391 aURL.Complete = ::rtl::OUString::createFromAscii(".uno:CloseWin");
392 css::uno::Reference< css::util::XURLTransformer > xTrans ( m_xFactory->createInstance(
393 SERVICENAME_URLTRANSFORMER ), css::uno::UNO_QUERY );
394 if( xTrans.is() )
396 // Datei laden
397 xTrans->parseStrict( aURL );
398 uno::Reference< XDispatchProvider > xProv( xFrame, UNO_QUERY );
399 if ( xProv.is() )
401 css::uno::Reference < css::frame::XDispatch > aDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
402 if ( aDisp.is() )
403 aDisp->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue>() );
407 return 0;
411 //_________________________________________________________________________________________________________________
412 // debug methods
413 //_________________________________________________________________________________________________________________
415 /*-----------------------------------------------------------------------------------------------------------------
416 The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
417 we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
419 ATTENTION
421 If you miss a test for one of this parameters, contact the autor or add it himself !(?)
422 But ... look for right testing! See using of this methods!
423 -----------------------------------------------------------------------------------------------------------------*/
425 #ifdef ENABLE_ASSERTIONS
427 //*****************************************************************************************************************
428 sal_Bool MenuDispatcher::impldbg_checkParameter_MenuDispatcher( const uno::Reference< XMultiServiceFactory >& xFactory ,
429 const uno::Reference< XFrame >& xOwner )
431 // Set default return value.
432 sal_Bool bOK = sal_True;
433 // Check parameter.
434 if (
435 ( &xFactory == NULL ) ||
436 ( &xOwner == NULL ) ||
437 ( xFactory.is() == sal_False ) ||
438 ( xOwner.is() == sal_False )
441 bOK = sal_False ;
443 // Return result of check.
444 return bOK ;
447 //*****************************************************************************************************************
448 // We don't know anything about right values of aURL and seqArguments!
449 // Check valid references only.
450 sal_Bool MenuDispatcher::impldbg_checkParameter_dispatch( const URL& aURL ,
451 const Sequence< PropertyValue >& seqArguments)
453 // Set default return value.
454 sal_Bool bOK = sal_True;
455 // Check parameter.
456 if (
457 ( &aURL == NULL ) ||
458 ( &seqArguments == NULL )
461 bOK = sal_False ;
463 // Return result of check.
464 return bOK ;
467 //*****************************************************************************************************************
468 // We need a valid URL. What is meaning with "register for nothing"?!
469 // xControl must correct to - nobody can advised otherwise!
470 sal_Bool MenuDispatcher::impldbg_checkParameter_addStatusListener( const uno::Reference< XStatusListener >& xControl,
471 const URL& aURL )
473 // Set default return value.
474 sal_Bool bOK = sal_True;
475 // Check parameter.
476 if (
477 ( &xControl == NULL ) ||
478 ( &aURL == NULL ) ||
479 ( aURL.Complete.getLength() < 1 )
482 bOK = sal_False ;
484 // Return result of check.
485 return bOK ;
488 //*****************************************************************************************************************
489 // The same goes for these case! We have added valid listener for correct URL only.
490 // We can't remove invalid listener for nothing!
491 sal_Bool MenuDispatcher::impldbg_checkParameter_removeStatusListener( const uno::Reference< XStatusListener >& xControl,
492 const URL& aURL )
494 // Set default return value.
495 sal_Bool bOK = sal_True;
496 // Check parameter.
497 if (
498 ( &xControl == NULL ) ||
499 ( &aURL == NULL ) ||
500 ( aURL.Complete.getLength() < 1 )
503 bOK = sal_False ;
505 // Return result of check.
506 return bOK ;
509 #endif // #ifdef ENABLE_ASSERTIONS
511 } // namespace framework