Update ooo320-m1
[ooovba.git] / framework / source / uielement / controlmenucontroller.cxx
blobbb33aa6c89a6b5f72f2eaa766d7c3cc6a47d9ceb
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: controlmenucontroller.cxx,v $
10 * $Revision: 1.11.40.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"
33 #include <uielement/controlmenucontroller.hxx>
35 //_________________________________________________________________________________________________________________
36 // my own includes
37 //_________________________________________________________________________________________________________________
38 #include <threadhelp/resetableguard.hxx>
39 #include "services.h"
41 //_________________________________________________________________________________________________________________
42 // interface includes
43 //_________________________________________________________________________________________________________________
44 #include <com/sun/star/awt/XDevice.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/awt/MenuItemStyle.hpp>
47 #include <com/sun/star/frame/XDispatchProvider.hpp>
48 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
49 #include <com/sun/star/container/XNameContainer.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
52 //_________________________________________________________________________________________________________________
53 // includes of other projects
54 //_________________________________________________________________________________________________________________
56 #ifndef _VCL_MENU_HXX_
57 #include <vcl/menu.hxx>
58 #endif
59 #include <vcl/svapp.hxx>
60 #include <vcl/i18nhelp.hxx>
61 #include <tools/urlobj.hxx>
62 #include <rtl/ustrbuf.hxx>
63 #include <rtl/strbuf.hxx>
64 #ifndef _SOLAR_HRC
65 #include <svtools/solar.hrc>
66 #endif
67 #include <tools/rcid.h>
68 #include <vcl/image.hxx>
69 #include <svtools/menuoptions.hxx>
70 #include <dispatch/uieventloghelper.hxx>
72 // Copied from svx
73 // Function-Id's
74 #define SID_LIB_START 10000
75 #define SID_SVX_START (SID_LIB_START + 0)
77 #define RID_FMSHELL_CONVERSIONMENU (RID_FORMS_START + 4)
78 #define RID_SVXIMGLIST_FMEXPL (RID_FORMS_START + 0)
79 #define RID_SVXIMGLIST_FMEXPL_HC (RID_FORMS_START + 2)
81 // Forms - Ids, used to address images from image list
82 #define SID_FMSLOTS_START (SID_SVX_START + 592)
83 #define SID_MORE_FMSLOTS_START (SID_SVX_START + 702)
85 #define SID_FM_CONVERTTO_EDIT (SID_MORE_FMSLOTS_START + 32)
86 #define SID_FM_CONVERTTO_BUTTON (SID_MORE_FMSLOTS_START + 33)
87 #define SID_FM_CONVERTTO_FIXEDTEXT (SID_MORE_FMSLOTS_START + 34)
88 #define SID_FM_CONVERTTO_LISTBOX (SID_MORE_FMSLOTS_START + 35)
89 #define SID_FM_CONVERTTO_CHECKBOX (SID_MORE_FMSLOTS_START + 36)
90 #define SID_FM_CONVERTTO_RADIOBUTTON (SID_MORE_FMSLOTS_START + 37)
91 #define SID_FM_CONVERTTO_GROUPBOX (SID_MORE_FMSLOTS_START + 38)
92 #define SID_FM_CONVERTTO_COMBOBOX (SID_MORE_FMSLOTS_START + 39)
93 #define SID_FM_CONVERTTO_GRID (SID_MORE_FMSLOTS_START + 40)
94 #define SID_FM_CONVERTTO_IMAGEBUTTON (SID_MORE_FMSLOTS_START + 41)
95 #define SID_FM_CONVERTTO_FILECONTROL (SID_MORE_FMSLOTS_START + 42)
96 #define SID_FM_CONVERTTO_DATE (SID_MORE_FMSLOTS_START + 43)
97 #define SID_FM_CONVERTTO_TIME (SID_MORE_FMSLOTS_START + 44)
98 #define SID_FM_CONVERTTO_NUMERIC (SID_MORE_FMSLOTS_START + 45)
99 #define SID_FM_CONVERTTO_CURRENCY (SID_MORE_FMSLOTS_START + 46)
100 #define SID_FM_CONVERTTO_PATTERN (SID_MORE_FMSLOTS_START + 47)
101 #define SID_FM_CONVERTTO_IMAGECONTROL (SID_MORE_FMSLOTS_START + 48)
102 #define SID_FM_CONVERTTO_FORMATTED (SID_MORE_FMSLOTS_START + 49)
103 #define SID_FM_CONVERTTO_SCROLLBAR (SID_MORE_FMSLOTS_START + 68)
104 #define SID_FM_CONVERTTO_SPINBUTTON (SID_MORE_FMSLOTS_START + 69)
106 #define SID_FM_DATEFIELD (SID_MORE_FMSLOTS_START + 2)
107 #define SID_FM_TIMEFIELD (SID_MORE_FMSLOTS_START + 3)
108 #define SID_FM_NUMERICFIELD (SID_MORE_FMSLOTS_START + 4)
109 #define SID_FM_CURRENCYFIELD (SID_MORE_FMSLOTS_START + 5)
110 #define SID_FM_PATTERNFIELD (SID_MORE_FMSLOTS_START + 6)
111 #define SID_FM_IMAGECONTROL (SID_MORE_FMSLOTS_START + 8)
112 #define SID_FM_FORMATTEDFIELD (SID_MORE_FMSLOTS_START + 26)
113 #define SID_FM_SCROLLBAR (SID_MORE_FMSLOTS_START + 66)
114 #define SID_FM_SPINBUTTON (SID_MORE_FMSLOTS_START + 67)
115 #define SID_FM_CONFIG (SID_FMSLOTS_START + 1)
116 #define SID_FM_PUSHBUTTON (SID_FMSLOTS_START + 2)
117 #define SID_FM_RADIOBUTTON (SID_FMSLOTS_START + 3)
118 #define SID_FM_CHECKBOX (SID_FMSLOTS_START + 4)
119 #define SID_FM_FIXEDTEXT (SID_FMSLOTS_START + 5)
120 #define SID_FM_GROUPBOX (SID_FMSLOTS_START + 6)
121 #define SID_FM_EDIT (SID_FMSLOTS_START + 7)
122 #define SID_FM_LISTBOX (SID_FMSLOTS_START + 8)
123 #define SID_FM_COMBOBOX (SID_FMSLOTS_START + 9)
124 #define SID_FM_URLBUTTON (SID_FMSLOTS_START + 10)
125 #define SID_FM_DBGRID (SID_FMSLOTS_START + 11)
126 #define SID_FM_IMAGEBUTTON (SID_FMSLOTS_START + 12)
127 #define SID_FM_FILECONTROL (SID_FMSLOTS_START + 13)
129 sal_Int16 nConvertSlots[] =
131 SID_FM_CONVERTTO_EDIT,
132 SID_FM_CONVERTTO_BUTTON,
133 SID_FM_CONVERTTO_FIXEDTEXT,
134 SID_FM_CONVERTTO_LISTBOX,
135 SID_FM_CONVERTTO_CHECKBOX,
136 SID_FM_CONVERTTO_RADIOBUTTON,
137 SID_FM_CONVERTTO_GROUPBOX,
138 SID_FM_CONVERTTO_COMBOBOX,
139 // SID_FM_CONVERTTO_GRID,
140 SID_FM_CONVERTTO_IMAGEBUTTON,
141 SID_FM_CONVERTTO_FILECONTROL,
142 SID_FM_CONVERTTO_DATE,
143 SID_FM_CONVERTTO_TIME,
144 SID_FM_CONVERTTO_NUMERIC,
145 SID_FM_CONVERTTO_CURRENCY,
146 SID_FM_CONVERTTO_PATTERN,
147 SID_FM_CONVERTTO_IMAGECONTROL,
148 SID_FM_CONVERTTO_FORMATTED,
149 SID_FM_CONVERTTO_SCROLLBAR,
150 SID_FM_CONVERTTO_SPINBUTTON
153 sal_Int16 nCreateSlots[] =
155 SID_FM_EDIT,
156 SID_FM_PUSHBUTTON,
157 SID_FM_FIXEDTEXT,
158 SID_FM_LISTBOX,
159 SID_FM_CHECKBOX,
160 SID_FM_RADIOBUTTON,
161 SID_FM_GROUPBOX,
162 SID_FM_COMBOBOX,
163 // SID_FM_DBGRID,
164 SID_FM_IMAGEBUTTON,
165 SID_FM_FILECONTROL,
166 SID_FM_DATEFIELD,
167 SID_FM_TIMEFIELD,
168 SID_FM_NUMERICFIELD,
169 SID_FM_CURRENCYFIELD,
170 SID_FM_PATTERNFIELD,
171 SID_FM_IMAGECONTROL,
172 SID_FM_FORMATTEDFIELD,
173 SID_FM_SCROLLBAR,
174 SID_FM_SPINBUTTON
177 const char* aCommands[] =
179 ".uno:ConvertToEdit",
180 ".uno:ConvertToButton",
181 ".uno:ConvertToFixed",
182 ".uno:ConvertToList",
183 ".uno:ConvertToCheckBox",
184 ".uno:ConvertToRadio",
185 ".uno:ConvertToGroup",
186 ".uno:ConvertToCombo",
187 // ".uno:ConvertToGrid",
188 ".uno:ConvertToImageBtn",
189 ".uno:ConvertToFileControl",
190 ".uno:ConvertToDate",
191 ".uno:ConvertToTime",
192 ".uno:ConvertToNumeric",
193 ".uno:ConvertToCurrency",
194 ".uno:ConvertToPattern",
195 ".uno:ConvertToImageControl",
196 ".uno:ConvertToFormatted",
197 ".uno:ConvertToScrollBar",
198 ".uno:ConvertToSpinButton"
201 //_________________________________________________________________________________________________________________
202 // Defines
203 //_________________________________________________________________________________________________________________
206 using namespace com::sun::star::uno;
207 using namespace com::sun::star::lang;
208 using namespace com::sun::star::frame;
209 using namespace com::sun::star::beans;
210 using namespace com::sun::star::util;
211 using namespace com::sun::star::style;
212 using namespace com::sun::star::container;
214 namespace framework
217 DEFINE_XSERVICEINFO_MULTISERVICE ( ControlMenuController ,
218 OWeakObject ,
219 SERVICENAME_POPUPMENUCONTROLLER ,
220 IMPLEMENTATIONNAME_CONTROLMENUCONTROLLER
223 DEFINE_INIT_SERVICE ( ControlMenuController, {} )
225 ControlMenuController::ControlMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
226 PopupMenuControllerBase( xServiceManager ),
227 m_pResPopupMenu( 0 )
229 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
230 m_bWasHiContrast = rSettings.GetHighContrastMode();
231 m_bShowMenuImages = rSettings.GetUseImagesInMenus();
235 ControlMenuController::~ControlMenuController()
239 // private function
240 void ControlMenuController::updateImagesPopupMenu( PopupMenu* pPopupMenu )
242 rtl::OUString aResName( RTL_CONSTASCII_USTRINGPARAM( "svx" ));
244 ResMgr* pResMgr = ResMgr::CreateResMgr( rtl::OUStringToOString( aResName, RTL_TEXTENCODING_ASCII_US ));
245 ResId aResId( m_bWasHiContrast ? RID_SVXIMGLIST_FMEXPL_HC : RID_SVXIMGLIST_FMEXPL, *pResMgr );
246 aResId.SetRT( RSC_IMAGELIST );
248 if ( pResMgr->IsAvailable( aResId ))
250 ImageList aImageList( aResId );
251 for ( sal_uInt32 i=0; i < sizeof(nConvertSlots)/sizeof(nConvertSlots[0]); ++i )
253 // das entsprechende Image dran
254 if ( m_bShowMenuImages )
255 pPopupMenu->SetItemImage( nConvertSlots[i], aImageList.GetImage(nCreateSlots[i]));
256 else
257 pPopupMenu->SetItemImage( nConvertSlots[i], Image() );
261 delete pResMgr;
264 // private function
265 void ControlMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
267 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
268 PopupMenu* pVCLPopupMenu = 0;
270 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
272 resetPopupMenu( rPopupMenu );
273 if ( pPopupMenu )
274 pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
276 if ( pVCLPopupMenu && m_pResPopupMenu )
277 *pVCLPopupMenu = *m_pResPopupMenu;
280 // XEventListener
281 void SAL_CALL ControlMenuController::disposing( const EventObject& ) throw ( RuntimeException )
283 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
285 ResetableGuard aLock( m_aLock );
286 m_xFrame.clear();
287 m_xDispatch.clear();
288 m_xServiceManager.clear();
290 if ( m_xPopupMenu.is() )
291 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
292 m_xPopupMenu.clear();
293 delete m_pResPopupMenu;
296 // XStatusListener
297 void SAL_CALL ControlMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
299 ResetableGuard aLock( m_aLock );
301 USHORT nMenuId = 0;
302 for (sal_uInt32 i=0; i < sizeof(aCommands)/sizeof(aCommands[0]); ++i)
304 if ( Event.FeatureURL.Complete.equalsAscii( aCommands[i] ))
306 nMenuId = nConvertSlots[i];
307 break;
311 if ( nMenuId )
313 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu );
315 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
317 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
319 if ( !Event.IsEnabled && pVCLPopupMenu->GetItemPos( nMenuId ) != MENU_ITEM_NOTFOUND )
320 pVCLPopupMenu->RemoveItem( pVCLPopupMenu->GetItemPos( nMenuId ));
321 else if ( Event.IsEnabled && pVCLPopupMenu->GetItemPos( nMenuId ) == MENU_ITEM_NOTFOUND )
323 sal_Int16 nSourcePos = m_pResPopupMenu->GetItemPos(nMenuId);
324 sal_Int16 nPrevInSource = nSourcePos;
325 sal_uInt16 nPrevInConversion = MENU_ITEM_NOTFOUND;
326 while (nPrevInSource>0)
328 sal_Int16 nPrevId = m_pResPopupMenu->GetItemId(--nPrevInSource);
330 // do we have the source's predecessor in our conversion menu, too ?
331 nPrevInConversion = pVCLPopupMenu->GetItemPos( nPrevId );
332 if ( nPrevInConversion != MENU_ITEM_NOTFOUND )
333 break;
336 if ( MENU_ITEM_NOTFOUND == nPrevInConversion )
337 // none of the items which precede the nSID-slot in the source menu are present in our conversion menu
338 nPrevInConversion = sal::static_int_cast< sal_uInt16 >(-1); // put the item at the first position
340 pVCLPopupMenu->InsertItem( nMenuId, m_pResPopupMenu->GetItemText( nMenuId ), m_pResPopupMenu->GetItemBits( nMenuId ), ++nPrevInConversion );
341 pVCLPopupMenu->SetItemImage( nMenuId, m_pResPopupMenu->GetItemImage( nMenuId ));
342 pVCLPopupMenu->SetHelpId( nMenuId, m_pResPopupMenu->GetHelpId( nMenuId ));
347 // XMenuListener
348 void ControlMenuController::impl_select(const Reference< XDispatch >& /*_xDispatch*/,const ::com::sun::star::util::URL& aURL)
350 UrlToDispatchMap::iterator pIter = m_aURLToDispatchMap.find( aURL.Complete );
351 if ( pIter != m_aURLToDispatchMap.end() )
353 Sequence<PropertyValue> aArgs;
354 Reference< XDispatch > xDispatch = pIter->second;
355 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
356 UiEventLogHelper(::rtl::OUString::createFromAscii("ControlMenuController")).log(m_xServiceManager, m_xFrame, aURL, aArgs);
357 if ( xDispatch.is() )
358 xDispatch->dispatch( aURL, aArgs );
362 void SAL_CALL ControlMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
364 ResetableGuard aLock( m_aLock );
366 if ( m_xPopupMenu.is() )
368 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
370 // Check if some modes have changed so we have to update our menu images
371 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
372 sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
373 sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
374 sal_Bool bUpdateImages = (( m_bWasHiContrast != bIsHiContrast ) || ( bShowMenuImages != m_bShowMenuImages ));
376 if ( bUpdateImages )
378 // The mode has changed or the complete menu so we have to retrieve all images again
379 m_bWasHiContrast = bIsHiContrast;
380 m_bShowMenuImages = bShowMenuImages;
382 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( m_xPopupMenu );
383 if ( pPopupMenu )
385 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
386 if ( pVCLPopupMenu && bUpdateImages )
387 updateImagesPopupMenu( pVCLPopupMenu );
393 // XPopupMenuController
394 void ControlMenuController::impl_setPopupMenu()
396 if ( m_pResPopupMenu == 0 )
398 rtl::OStringBuffer aBuf( 32 );
399 aBuf.append( "svx" );
401 ResMgr* pResMgr = ResMgr::CreateResMgr( aBuf.getStr() );
402 if ( pResMgr )
404 ResId aResId( RID_FMSHELL_CONVERSIONMENU, *pResMgr );
405 aResId.SetRT( RSC_MENU );
406 if ( pResMgr->IsAvailable( aResId ))
407 m_pResPopupMenu = new PopupMenu( aResId );
409 updateImagesPopupMenu( m_pResPopupMenu );
410 delete pResMgr;
412 } // if ( m_pResPopupMenu == 0 )
415 void SAL_CALL ControlMenuController::updatePopupMenu() throw (::com::sun::star::uno::RuntimeException)
417 ResetableGuard aLock( m_aLock );
419 if ( m_bDisposed )
420 throw DisposedException();
422 if ( m_xFrame.is() && m_xPopupMenu.is() )
424 URL aTargetURL;
425 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
426 fillPopupMenu( m_xPopupMenu );
427 m_aURLToDispatchMap.free();
429 for (sal_uInt32 i=0; i<sizeof(aCommands)/sizeof(aCommands[0]); ++i)
431 aTargetURL.Complete = rtl::OUString::createFromAscii( aCommands[i] );
432 m_xURLTransformer->parseStrict( aTargetURL );
434 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
435 if ( xDispatch.is() )
437 xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
438 xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
439 m_aURLToDispatchMap.insert( UrlToDispatchMap::value_type( aTargetURL.Complete, xDispatch ));
445 // XInitialization
446 void SAL_CALL ControlMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
448 ResetableGuard aLock( m_aLock );
449 PopupMenuControllerBase::initialize(aArguments);
450 m_aBaseURL = ::rtl::OUString();