1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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 //_________________________________________________________________________________________________________________
37 //_________________________________________________________________________________________________________________
38 #include <threadhelp/resetableguard.hxx>
41 //_________________________________________________________________________________________________________________
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>
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>
65 #include <svtools/solar.hrc>
67 #include <tools/rcid.h>
68 #include <vcl/image.hxx>
69 #include <svtools/menuoptions.hxx>
70 #include <dispatch/uieventloghelper.hxx>
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
[] =
169 SID_FM_CURRENCYFIELD
,
172 SID_FM_FORMATTEDFIELD
,
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 //_________________________________________________________________________________________________________________
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
;
217 DEFINE_XSERVICEINFO_MULTISERVICE ( ControlMenuController
,
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
),
229 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
230 m_bWasHiContrast
= rSettings
.GetMenuColor().IsDark();
231 m_bShowMenuImages
= rSettings
.GetUseImagesInMenus();
235 ControlMenuController::~ControlMenuController()
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
]));
257 pPopupMenu
->SetItemImage( nConvertSlots
[i
], Image() );
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
);
274 pVCLPopupMenu
= (PopupMenu
*)pPopupMenu
->GetMenu();
276 if ( pVCLPopupMenu
&& m_pResPopupMenu
)
277 *pVCLPopupMenu
= *m_pResPopupMenu
;
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
);
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
;
297 void SAL_CALL
ControlMenuController::statusChanged( const FeatureStateEvent
& Event
) throw ( RuntimeException
)
299 ResetableGuard
aLock( m_aLock
);
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
];
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
)
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
));
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
.GetMenuColor().IsDark();
373 sal_Bool bShowMenuImages
= rSettings
.GetUseImagesInMenus();
374 sal_Bool bUpdateImages
= (( m_bWasHiContrast
!= bIsHiContrast
) || ( bShowMenuImages
!= m_bShowMenuImages
));
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
);
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() );
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
);
412 } // if ( m_pResPopupMenu == 0 )
415 void SAL_CALL
ControlMenuController::updatePopupMenu() throw (::com::sun::star::uno::RuntimeException
)
417 ResetableGuard
aLock( m_aLock
);
420 throw DisposedException();
422 if ( m_xFrame
.is() && m_xPopupMenu
.is() )
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
));
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();