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_framework.hxx"
26
27
28 //_________________________________________________________________________________________________________________
29 // my own includes
30 //_________________________________________________________________________________________________________________
31 #include <classes/menumanager.hxx>
32 #include <framework/menuconfiguration.hxx>
33 #include <framework/bmkmenu.hxx>
34 #include <framework/addonmenu.hxx>
35 #include <framework/imageproducer.hxx>
36 #include <threadhelp/resetableguard.hxx>
37 #include "framework/addonsoptions.hxx"
38 #include <classes/fwkresid.hxx>
39 #include <services.h>
40 #include "classes/resource.hrc"
41
42 //_________________________________________________________________________________________________________________
43 // interface includes
44 //_________________________________________________________________________________________________________________
45 #include <com/sun/star/frame/XDispatchProvider.hpp>
46 #include <com/sun/star/frame/XDispatch.hpp>
47 #include <com/sun/star/util/XURLTransformer.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/frame/XFramesSupplier.hpp>
51 #include <com/sun/star/frame/XDesktop.hpp>
52 #include <com/sun/star/container/XEnumeration.hpp>
53 #include <com/sun/star/util/XStringWidth.hpp>
54
55 //_________________________________________________________________________________________________________________
56 // includes of other projects
57 //_________________________________________________________________________________________________________________
58 #include <comphelper/processfactory.hxx>
59
60 #include <comphelper/extract.hxx>
61 #include <svtools/menuoptions.hxx>
62 #include <unotools/historyoptions.hxx>
63 #include <unotools/pathoptions.hxx>
64 #include <unotools/localfilehelper.hxx>
65
66 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
67 #include <toolkit/helper/vclunohelper.hxx>
68 #endif
69 #include <tools/urlobj.hxx>
70
71 #include <vcl/svapp.hxx>
72 #include <vcl/window.hxx>
73 #include <vos/mutex.hxx>
74 #include <vcl/svapp.hxx>
75 #include <osl/file.hxx>
76 #include <cppuhelper/implbase1.hxx>
77
78 //_________________________________________________________________________________________________________________
79 // namespace
80 //_________________________________________________________________________________________________________________
81
82 using namespace ::cppu;
83 using namespace ::vos;
84 using namespace ::com::sun::star::uno;
85 using namespace ::com::sun::star::util;
86 using namespace ::com::sun::star::beans;
87 using namespace ::com::sun::star::frame;
88 using namespace ::com::sun::star::lang;
89 using namespace ::com::sun::star::container;
90
91
92 class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
93 {
94 public:
StringLength()95 StringLength() {}
~StringLength()96 virtual ~StringLength() {}
97
98 // XStringWidth
queryStringWidth(const::rtl::OUString & aString)99 sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
100 {
101 return aString.getLength();
102 }
103 };
104
105 namespace framework
106 {
107
108 // special menu ids/command ids for dynamic popup menus
109 #define SID_SFX_START 5000
110 #define SID_NEWDOCDIRECT (SID_SFX_START + 537)
111 #define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
112 #define SID_PICKLIST (SID_SFX_START + 510)
113 #define SID_MDIWINDOWLIST (SID_SFX_START + 610)
114 #define SID_ADDONLIST (SID_SFX_START + 1677)
115 #define SID_HELPMENU (SID_SFX_START + 410)
116
117 #define SFX_REFERER_USER "private:user"
118
119 const ::rtl::OUString aSlotNewDocDirect( RTL_CONSTASCII_USTRINGPARAM( "slot:5537" ));
120 const ::rtl::OUString aSlotAutoPilot( RTL_CONSTASCII_USTRINGPARAM( "slot:6381" ));
121
122 const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" ));
123 const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" ));
124 const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" ));
125 const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" ));
126 const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" ));
127
128 // special uno commands for picklist and window list
129 const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( "PickList" ));
130 const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( "WindowList" ));
131
132 const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
133
134 // #110897#
MenuManager(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & xServiceFactory,REFERENCE<XFRAME> & rFrame,Menu * pMenu,sal_Bool bDelete,sal_Bool bDeleteChildren)135 MenuManager::MenuManager(
136 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
137 REFERENCE< XFRAME >& rFrame, Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
138 : // #110897#
139 ThreadHelpBase( &Application::GetSolarMutex() ),
140 mxServiceFactory(xServiceFactory)
141 {
142 m_bActive = sal_False;
143 m_bDeleteMenu = bDelete;
144 m_bDeleteChildren = bDeleteChildren;
145 m_pVCLMenu = pMenu;
146 m_xFrame = rFrame;
147 m_bInitialized = sal_False;
148 m_bIsBookmarkMenu = sal_False;
149
150 acquire();
151
152 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
153 m_bWasHiContrast = rSettings.GetHighContrastMode();
154 m_bShowMenuImages = rSettings.GetUseImagesInMenus();
155
156 sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
157 #if 0
158 ::std::vector< sal_uInt16 > aQueryLabelItemIdVector;
159 #endif
160
161 sal_uInt16 nItemCount = pMenu->GetItemCount();
162 m_aMenuItemHandlerVector.reserve(nItemCount);
163 ::rtl::OUString aItemCommand;
164 for ( sal_uInt16 i = 0; i < nItemCount; i++ )
165 {
166 sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i );
167 bool bShowMenuImages( m_bShowMenuImages );
168 MenuItemBits nBits = pMenu->GetItemBits( nItemId );
169 // overwrite the default?
170 if ( nBits )
171 bShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
172
173
174 PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nItemId );
175 if ( pPopupMenu )
176 {
177 AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
178 if (! (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
179 ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) )
180 {
181 // #110897#
182 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
183 #if 0
184 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
185 aQueryLabelItemIdVector.push_back( nItemId );
186 #endif
187
188 // Create addon popup menu if there exist elements and this is the tools popup menu
189 if (( nItemId == SID_ADDONLIST ||
190 aItemCommand == aSlotSpecialToolsMenu ) &&
191 AddonMenuManager::HasAddonMenuElements() )
192 {
193 sal_uInt16 nCount = 0;
194 AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame, xServiceFactory );
195 if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
196 {
197 if ( pPopupMenu->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
198 pPopupMenu->InsertSeparator();
199
200 // Use resource to load popup menu title
201 String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
202 pPopupMenu->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
203 pPopupMenu->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
204
205 // Set item command for popup menu to enable it for GetImageFromURL
206 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
207 aItemCommand = aSlotString;
208 aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
209 pPopupMenu->SetItemCommand( ITEMID_ADDONLIST, aItemCommand );
210
211 // #110897#
212 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
213 AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
214 #if 0
215 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
216 aQueryLabelItemIdVector.push_back( nItemId );
217 #endif
218 // Set image for the addon popup menu item
219 if ( bShowMenuImages && !pPopupMenu->GetItemImage( ITEMID_ADDONLIST ))
220 {
221 Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
222 if ( !!aImage )
223 pPopupMenu->SetItemImage( ITEMID_ADDONLIST, aImage );
224 }
225 }
226 else
227 delete pSubMenu;
228 }
229 }
230 }
231 else
232 {
233 if ( nItemId == SID_NEWDOCDIRECT ||
234 aItemCommand == aSlotNewDocDirect )
235 {
236 // #110897#
237 // Reference< ::com::sun::star::lang::XMultiServiceFactory > aMultiServiceFactory(::comphelper::getProcessServiceFactory());
238 // MenuConfiguration aMenuCfg( aMultiServiceFactory );
239 MenuConfiguration aMenuCfg( getServiceFactory() );
240 BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_NEWMENU );
241 pMenu->SetPopupMenu( nItemId, pSubMenu );
242
243 // #110897#
244 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
245 AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
246 #if 0
247 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
248 aQueryLabelItemIdVector.push_back( nItemId );
249 #endif
250
251 if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
252 {
253 Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
254 if ( !!aImage )
255 pMenu->SetItemImage( nItemId, aImage );
256 }
257 }
258 else if ( nItemId == SID_AUTOPILOTMENU ||
259 aItemCommand == aSlotAutoPilot )
260 {
261 // #110897#
262 // Reference< ::com::sun::star::lang::XMultiServiceFactory > aMultiServiceFactory(::comphelper::getProcessServiceFactory());
263 // MenuConfiguration aMenuCfg( aMultiServiceFactory );
264 MenuConfiguration aMenuCfg( getServiceFactory() );
265 BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_WIZARDMENU );
266 pMenu->SetPopupMenu( nItemId, pSubMenu );
267
268 // #110897#
269 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
270 AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
271 #if 0
272 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
273 aQueryLabelItemIdVector.push_back( nItemId );
274 #endif
275
276 if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
277 {
278 Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
279 if ( !!aImage )
280 pMenu->SetItemImage( nItemId, aImage );
281 }
282 }
283 else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
284 {
285 if ( bShowMenuImages )
286 {
287 if ( AddonMenuManager::IsAddonMenuId( nItemId ))
288 {
289 // Add-Ons uses a images from different places
290 Image aImage;
291 rtl::OUString aImageId;
292
293 MenuConfiguration::Attributes* pMenuAttributes =
294 (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
295
296 if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
297 {
298 // Retrieve image id from menu attributes
299 aImage = GetImageFromURL( rFrame, aImageId, sal_False, m_bWasHiContrast );
300 }
301
302 if ( !aImage )
303 {
304 aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
305 if ( !aImage )
306 aImage = AddonsOptions().GetImageFromURL( aItemCommand, sal_False, m_bWasHiContrast );
307 }
308
309 if ( !!aImage )
310 pMenu->SetItemImage( nItemId, aImage );
311 }
312 else if ( !pMenu->GetItemImage( nItemId ))
313 {
314 Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
315 if ( !!aImage )
316 pMenu->SetItemImage( nItemId, aImage );
317 }
318 }
319
320 REFERENCE< XDISPATCH > aXDispatchRef;
321 m_aMenuItemHandlerVector.push_back( new MenuItemHandler( nItemId, NULL, aXDispatchRef ));
322 #if 0
323 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
324 aQueryLabelItemIdVector.push_back( nItemId );
325 #endif
326 }
327 }
328 }
329
330
331 // retrieve label information for all menu items without item text
332 #if 0
333 if ( aQueryLabelItemIdVector.size() > 0 )
334 {
335 Sequence< ::rtl::OUString > aURLSequence( aQueryLabelItemIdVector.size() );
336 Sequence< ::rtl::OUString > aLabelSequence( aQueryLabelItemIdVector.size() );
337
338 sal_uInt32 nPos = 0;
339 ::std::vector< sal_uInt16 >::iterator p;
340 for ( p = aQueryLabelItemIdVector.begin(); p != aQueryLabelItemIdVector.end(); p++ )
341 aURLSequence[nPos++] = pMenu->GetItemCommand( *p );
342
343 Reference< XDispatchInformationProvider > xDIP( xFrame, UNO_QUERY );
344 if ( xDIP.is() )
345 {
346 nPos = 0;
347 xDIP->queryDispatchInformations( aURLSequence, aLabelSequence );
348 for ( p = aQueryLabelItemIdVector.begin(); p != aQueryLabelItemIdVector.end(); p++ )
349 pMenu->SetItemText( *p, aLabelSequence( nPos++ ));
350 }
351 }
352 #endif
353 SetHdl();
354 }
355
356 #if 0
357 // #110897#
358 MenuManager::MenuManager(
359 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
360 REFERENCE< XFRAME >& rFrame, AddonMenu* pAddonMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
361 : // #110897#
362 ThreadHelpBase( &Application::GetSolarMutex() ),
363 mxServiceFactory(xServiceFactory)
364 {
365 m_bActive = sal_False;
366 m_bDeleteMenu = bDelete;
367 m_bDeleteChildren = bDeleteChildren;
368 m_pVCLMenu = pAddonMenu;
369 m_xFrame = rFrame;
370 m_bInitialized = sal_False;
371 m_bIsBookmarkMenu = sal_True;
372
373 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
374 m_bWasHiContrast = rSettings.GetHighContrastMode();
375
376 SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)this )->acquire();
377
378 sal_uInt16 nItemCount = pAddonMenu->GetItemCount();
379 m_aMenuItemHandlerVector.reserve(nItemCount);
380 ::rtl::OUString aItemCommand;
381 for ( sal_uInt16 i = 0; i < nItemCount; i++ )
382 {
383 sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
384
385 PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
386 if ( pPopupMenu )
387 {
388 // #110897#
389 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
390 AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
391 }
392 else
393 {
394 if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
395 {
396 MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId ));
397 REFERENCE< XDISPATCH > aXDispatchRef;
398 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, NULL, aXDispatchRef );
399
400 if ( pAddonAttributes )
401 {
402 // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
403 pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
404 }
405
406 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
407 }
408 }
409 }
410
411 SetHdl();
412 }
413 #endif
414
SetHdl()415 void MenuManager::SetHdl()
416 {
417 m_pVCLMenu->SetHighlightHdl( LINK( this, MenuManager, Highlight ));
418 m_pVCLMenu->SetActivateHdl( LINK( this, MenuManager, Activate ));
419 m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuManager, Deactivate ));
420 m_pVCLMenu->SetSelectHdl( LINK( this, MenuManager, Select ));
421
422 if ( mxServiceFactory.is() )
423 m_xURLTransformer.set( mxServiceFactory->createInstance(SERVICENAME_URLTRANSFORMER),UNO_QUERY );
424 }
425
~MenuManager()426 MenuManager::~MenuManager()
427 {
428 std::vector< MenuItemHandler* >::iterator p;
429 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
430 {
431 MenuItemHandler* pItemHandler = *p;
432 pItemHandler->xMenuItemDispatch.clear();
433 if ( pItemHandler->pSubMenuManager )
434 SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)pItemHandler->pSubMenuManager )->release();
435 delete pItemHandler;
436 }
437
438 if ( m_bDeleteMenu )
439 delete m_pVCLMenu;
440 }
441
442
GetMenuItemHandler(sal_uInt16 nItemId)443 MenuManager::MenuItemHandler* MenuManager::GetMenuItemHandler( sal_uInt16 nItemId )
444 {
445 ResetableGuard aGuard( m_aLock );
446
447 std::vector< MenuItemHandler* >::iterator p;
448 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
449 {
450 MenuItemHandler* pItemHandler = *p;
451 if ( pItemHandler->nItemId == nItemId )
452 return pItemHandler;
453 }
454
455 return 0;
456 }
457
458
statusChanged(const FEATURSTATEEVENT & Event)459 void SAL_CALL MenuManager::statusChanged( const FEATURSTATEEVENT& Event )
460 {
461 ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
462 MenuItemHandler* pStatusChangedMenu = NULL;
463
464 {
465 ResetableGuard aGuard( m_aLock );
466
467 std::vector< MenuItemHandler* >::iterator p;
468 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
469 {
470 MenuItemHandler* pMenuItemHandler = *p;
471 if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
472 {
473 pStatusChangedMenu = pMenuItemHandler;
474 break;
475 }
476 }
477 }
478
479 if ( pStatusChangedMenu )
480 {
481 OGuard aSolarGuard( Application::GetSolarMutex() );
482 {
483 ResetableGuard aGuard( m_aLock );
484
485 sal_Bool bSetCheckmark = sal_False;
486 sal_Bool bCheckmark = sal_False;
487 sal_Bool bMenuItemEnabled = m_pVCLMenu->IsItemEnabled( pStatusChangedMenu->nItemId );
488
489 if ( Event.IsEnabled != bMenuItemEnabled )
490 m_pVCLMenu->EnableItem( pStatusChangedMenu->nItemId, Event.IsEnabled );
491
492 if ( Event.State >>= bCheckmark )
493 bSetCheckmark = sal_True;
494
495 if ( bSetCheckmark )
496 m_pVCLMenu->CheckItem( pStatusChangedMenu->nItemId, bCheckmark );
497 }
498
499 if ( Event.Requery )
500 {
501 URL aTargetURL;
502 aTargetURL.Complete = pStatusChangedMenu->aMenuItemURL;
503
504 // #110897#
505 m_xURLTransformer->parseStrict( aTargetURL );
506
507 REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
508 REFERENCE< XDISPATCH > xMenuItemDispatch = xDispatchProvider->queryDispatch(
509 aTargetURL, ::rtl::OUString(), 0 );
510
511 if ( xMenuItemDispatch.is() )
512 {
513 pStatusChangedMenu->xMenuItemDispatch = xMenuItemDispatch;
514 pStatusChangedMenu->aMenuItemURL = aTargetURL.Complete;
515 xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
516 }
517 }
518 }
519 }
520
521
RemoveListener()522 void MenuManager::RemoveListener()
523 {
524 ResetableGuard aGuard( m_aLock );
525 ClearMenuDispatch();
526 }
527
ClearMenuDispatch(const EVENTOBJECT & Source,bool _bRemoveOnly)528 void MenuManager::ClearMenuDispatch(const EVENTOBJECT& Source,bool _bRemoveOnly)
529 {
530 // disposing called from parent dispatcher
531 // remove all listener to prepare shutdown
532
533 // #110897#
534 std::vector< MenuItemHandler* >::iterator p;
535 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
536 {
537 MenuItemHandler* pItemHandler = *p;
538 if ( pItemHandler->xMenuItemDispatch.is() )
539 {
540 URL aTargetURL;
541 aTargetURL.Complete = pItemHandler->aMenuItemURL;
542 m_xURLTransformer->parseStrict( aTargetURL );
543
544 pItemHandler->xMenuItemDispatch->removeStatusListener(
545 SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
546 }
547
548 pItemHandler->xMenuItemDispatch.clear();
549 if ( pItemHandler->pSubMenuManager )
550 {
551 if ( _bRemoveOnly )
552 pItemHandler->pSubMenuManager->RemoveListener();
553 else
554 pItemHandler->pSubMenuManager->disposing( Source );
555 }
556 }
557 }
558
559
disposing(const EVENTOBJECT & Source)560 void SAL_CALL MenuManager::disposing( const EVENTOBJECT& Source )
561 {
562 if ( Source.Source == m_xFrame )
563 {
564 ResetableGuard aGuard( m_aLock );
565 ClearMenuDispatch(Source,false);
566 }
567 else
568 {
569 // disposing called from menu item dispatcher, remove listener
570 MenuItemHandler* pMenuItemDisposing = NULL;
571
572 {
573 ResetableGuard aGuard( m_aLock );
574
575 std::vector< MenuItemHandler* >::iterator p;
576 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
577 {
578 MenuItemHandler* pMenuItemHandler = *p;
579 if ( pMenuItemHandler->xMenuItemDispatch == Source.Source )
580 {
581 pMenuItemDisposing = pMenuItemHandler;
582 break;
583 }
584 }
585
586 if ( pMenuItemDisposing )
587 {
588 URL aTargetURL;
589 aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
590
591 // #110897#
592 m_xURLTransformer->parseStrict( aTargetURL );
593
594 pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
595 pMenuItemDisposing->xMenuItemDispatch.clear();
596 }
597 }
598 }
599 }
600
601
UpdateSpecialFileMenu(Menu * pMenu)602 void MenuManager::UpdateSpecialFileMenu( Menu* pMenu )
603 {
604 // update picklist
605 Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
606 ::std::vector< MenuItemHandler* > aNewPickVector;
607 Reference< XStringWidth > xStringLength( new StringLength );
608
609 sal_uInt16 nPickItemId = START_ITEMID_PICKLIST;
610 int nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
611
612 aNewPickVector.reserve(nPickListMenuItems);
613 for ( int i = 0; i < nPickListMenuItems; i++ )
614 {
615 Sequence< PropertyValue > aPickListEntry = aHistoryList[i];
616
617 REFERENCE< XDISPATCH > aXDispatchRef;
618 MenuItemHandler* pNewMenuItemHandler = new MenuItemHandler(
619 nPickItemId++,
620 NULL,
621 aXDispatchRef );
622
623 for ( int j = 0; j < aPickListEntry.getLength(); j++ )
624 {
625 Any a = aPickListEntry[j].Value;
626
627 if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
628 a >>= pNewMenuItemHandler->aMenuItemURL;
629 else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
630 a >>= pNewMenuItemHandler->aFilter;
631 else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
632 a >>= pNewMenuItemHandler->aTitle;
633 else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
634 a >>= pNewMenuItemHandler->aPassword;
635 }
636
637 aNewPickVector.push_back( pNewMenuItemHandler );
638 }
639
640 if ( !aNewPickVector.empty() )
641 {
642 URL aTargetURL;
643 REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
644
645 // #110897#
646 REFERENCE< XDISPATCH > xMenuItemDispatch;
647
648 static const ::rtl::OUString s_sDefault(RTL_CONSTASCII_USTRINGPARAM("_default"));
649 // query for dispatcher
650 std::vector< MenuItemHandler* >::iterator p;
651 for ( p = aNewPickVector.begin(); p != aNewPickVector.end(); p++ )
652 {
653 MenuItemHandler* pMenuItemHandler = *p;
654
655 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
656 m_xURLTransformer->parseStrict( aTargetURL );
657
658 if ( !xMenuItemDispatch.is() )
659 {
660 // attention: this code assume that "_blank" can only be consumed by desktop service
661 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, s_sDefault, 0 );
662 }
663
664 if ( xMenuItemDispatch.is() )
665 {
666 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
667 pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
668 }
669 }
670
671 {
672 ResetableGuard aGuard( m_aLock );
673
674 int nRemoveItemCount = 0;
675 int nItemCount = pMenu->GetItemCount();
676
677 if ( nItemCount > 0 )
678 {
679 // remove all old picklist entries from menu
680 sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_PICKLIST );
681 for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
682 {
683 pMenu->RemoveItem( n );
684 ++nRemoveItemCount;
685 }
686
687 if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
688 pMenu->RemoveItem( pMenu->GetItemCount()-1 );
689
690 // remove all old picklist entries from menu handler
691 if ( nRemoveItemCount > 0 )
692 {
693 for( sal_uInt32 nIndex = m_aMenuItemHandlerVector.size() - nRemoveItemCount;
694 nIndex < m_aMenuItemHandlerVector.size(); )
695 {
696 delete m_aMenuItemHandlerVector.at( nIndex );
697 m_aMenuItemHandlerVector.erase( m_aMenuItemHandlerVector.begin() + nIndex );
698 }
699 }
700 }
701
702 // append new picklist menu entries
703 aNewPickVector.reserve(aNewPickVector.size());
704 pMenu->InsertSeparator();
705 const sal_uInt32 nCount = aNewPickVector.size();
706 for ( sal_uInt32 i = 0; i < nCount; i++ )
707 {
708 char menuShortCut[5] = "~n: ";
709
710 ::rtl::OUString aMenuShortCut;
711 if ( i <= 9 )
712 {
713 if ( i == 9 )
714 aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
715 else
716 {
717 menuShortCut[1] = (char)( '1' + i );
718 aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
719 }
720 }
721 else
722 {
723 aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
724 aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
725 }
726
727 // Abbreviate URL
728 rtl::OUString aURLString( aNewPickVector.at( i )->aMenuItemURL );
729 rtl::OUString aTipHelpText;
730 rtl::OUString aMenuTitle;
731 INetURLObject aURL( aURLString );
732
733 if ( aURL.GetProtocol() == INET_PROT_FILE )
734 {
735 // Do handle file URL differently => convert it to a system
736 // path and abbreviate it with a special function:
737 String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
738
739 ::rtl::OUString aSystemPath( aFileSystemPath );
740 ::rtl::OUString aCompactedSystemPath;
741
742 aTipHelpText = aSystemPath;
743 oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
744 if ( !nError )
745 aMenuTitle = String( aCompactedSystemPath );
746 else
747 aMenuTitle = aSystemPath;
748 }
749 else
750 {
751 // Use INetURLObject to abbreviate all other URLs
752 String aShortURL;
753 aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
754 aMenuTitle += aShortURL;
755 aTipHelpText = aURLString;
756 }
757
758 ::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
759
760 MenuItemHandler* pMenuItemHandler = aNewPickVector.at( i );
761 pMenu->InsertItem( pMenuItemHandler->nItemId, aTitle );
762 pMenu->SetTipHelpText( pMenuItemHandler->nItemId, aTipHelpText );
763 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
764 }
765 }
766 }
767 }
768
UpdateSpecialWindowMenu(Menu * pMenu,const Reference<XMultiServiceFactory> & xServiceFactory,framework::IMutex & _rMutex)769 void MenuManager::UpdateSpecialWindowMenu( Menu* pMenu,const Reference< XMultiServiceFactory >& xServiceFactory,framework::IMutex& _rMutex )
770 {
771 // update window list
772 ::std::vector< ::rtl::OUString > aNewWindowListVector;
773
774 // #110897#
775 Reference< XDesktop > xDesktop( xServiceFactory->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
776
777 sal_uInt16 nActiveItemId = 0;
778 sal_uInt16 nItemId = START_ITEMID_WINDOWLIST;
779
780 if ( xDesktop.is() )
781 {
782 Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
783 Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
784 Reference< XIndexAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
785 sal_Int32 nCount = xList->getCount();
786 aNewWindowListVector.reserve(nCount);
787 for (sal_Int32 i=0; i<nCount; ++i )
788 {
789 Reference< XFrame > xFrame;
790 xList->getByIndex(i) >>= xFrame;
791
792 if (xFrame.is())
793 {
794 if ( xFrame == xCurrentFrame )
795 nActiveItemId = nItemId;
796
797 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
798 if ( pWin && pWin->IsVisible() )
799 {
800 aNewWindowListVector.push_back( pWin->GetText() );
801 ++nItemId;
802 }
803 }
804 }
805 }
806
807 {
808 ResetableGuard aGuard( _rMutex );
809
810 int nItemCount = pMenu->GetItemCount();
811
812 if ( nItemCount > 0 )
813 {
814 // remove all old window list entries from menu
815 sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
816 for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
817 pMenu->RemoveItem( n );
818
819 if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
820 pMenu->RemoveItem( pMenu->GetItemCount()-1 );
821 }
822
823 if ( !aNewWindowListVector.empty() )
824 {
825 // append new window list entries to menu
826 pMenu->InsertSeparator();
827 nItemId = START_ITEMID_WINDOWLIST;
828 const sal_uInt32 nCount = aNewWindowListVector.size();
829 for ( sal_uInt32 i = 0; i < nCount; i++ )
830 {
831 pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK );
832 if ( nItemId == nActiveItemId )
833 pMenu->CheckItem( nItemId );
834 ++nItemId;
835 }
836 }
837 }
838 }
839
840
CreatePicklistArguments(Sequence<PropertyValue> & aArgsList,const MenuItemHandler * pMenuItemHandler)841 void MenuManager::CreatePicklistArguments( Sequence< PropertyValue >& aArgsList, const MenuItemHandler* pMenuItemHandler )
842 {
843 int NUM_OF_PICKLIST_ARGS = 3;
844
845 Any a;
846 aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
847
848 aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ));
849 a <<= pMenuItemHandler->aMenuItemURL;
850 aArgsList[0].Value = a;
851
852 aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
853 a <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
854 aArgsList[1].Value = a;
855
856 ::rtl::OUString aFilter( pMenuItemHandler->aFilter );
857
858 sal_Int32 nPos = aFilter.indexOf( '|' );
859 if ( nPos >= 0 )
860 {
861 ::rtl::OUString aFilterOptions;
862
863 if ( nPos < ( aFilter.getLength() - 1 ) )
864 aFilterOptions = aFilter.copy( nPos+1 );
865
866 aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
867 a <<= aFilterOptions;
868 aArgsList[2].Value = a;
869
870 aFilter = aFilter.copy( 0, nPos-1 );
871 aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
872 }
873
874 aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
875 a <<= aFilter;
876 aArgsList[NUM_OF_PICKLIST_ARGS-1].Value = a;
877 }
878
879
880 //_________________________________________________________________________________________________________________
881 // vcl handler
882 //_________________________________________________________________________________________________________________
883
IMPL_LINK(MenuManager,Activate,Menu *,pMenu)884 IMPL_LINK( MenuManager, Activate, Menu *, pMenu )
885 {
886 if ( pMenu == m_pVCLMenu )
887 {
888 // set/unset hiding disabled menu entries
889 sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
890 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
891 sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
892
893 sal_uInt16 nFlag = pMenu->GetMenuFlags();
894 if ( bDontHide )
895 nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
896 else
897 nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
898 pMenu->SetMenuFlags( nFlag );
899
900 if ( m_bActive )
901 return 0;
902
903 m_bActive = sal_True;
904
905 ::rtl::OUString aCommand( m_aMenuItemCommand );
906 if ( m_aMenuItemCommand.matchIgnoreAsciiCase( UNO_COMMAND, 0 ))
907 {
908 // Remove protocol part from command so we can use an easier comparison method
909 aCommand = aCommand.copy( UNO_COMMAND.getLength() );
910 }
911
912 if ( m_aMenuItemCommand == aSpecialFileMenu ||
913 m_aMenuItemCommand == aSlotSpecialFileMenu ||
914 aCommand == aSpecialFileCommand )
915 UpdateSpecialFileMenu( pMenu );
916 else if ( m_aMenuItemCommand == aSpecialWindowMenu ||
917 m_aMenuItemCommand == aSlotSpecialWindowMenu ||
918 aCommand == aSpecialWindowCommand )
919 UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
920
921 // Check if some modes have changed so we have to update our menu images
922 sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
923
924 if ( m_bWasHiContrast != bIsHiContrast || bShowMenuImages != m_bShowMenuImages )
925 {
926 // The mode changed so we have to replace all images
927 m_bWasHiContrast = bIsHiContrast;
928 m_bShowMenuImages = bShowMenuImages;
929 FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages);
930 }
931
932 if ( m_bInitialized )
933 return 0;
934 else
935 {
936 URL aTargetURL;
937
938 // #110897#
939 ResetableGuard aGuard( m_aLock );
940
941 REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
942 if ( xDispatchProvider.is() )
943 {
944 std::vector< MenuItemHandler* >::iterator p;
945 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
946 {
947 MenuItemHandler* pMenuItemHandler = *p;
948 if ( pMenuItemHandler &&
949 pMenuItemHandler->pSubMenuManager == 0 &&
950 !pMenuItemHandler->xMenuItemDispatch.is() )
951 {
952 // There is no dispatch mechanism for the special window list menu items,
953 // because they are handled directly through XFrame->activate!!!
954 if ( pMenuItemHandler->nItemId < START_ITEMID_WINDOWLIST ||
955 pMenuItemHandler->nItemId > END_ITEMID_WINDOWLIST )
956 {
957 ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
958 if ( !aItemCommand.getLength() )
959 {
960 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
961 aItemCommand = aSlotString;
962 aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
963 pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
964 }
965
966 aTargetURL.Complete = aItemCommand;
967
968 m_xURLTransformer->parseStrict( aTargetURL );
969
970 REFERENCE< XDISPATCH > xMenuItemDispatch;
971 if ( m_bIsBookmarkMenu )
972 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
973 else
974 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
975
976 if ( xMenuItemDispatch.is() )
977 {
978 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
979 pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
980 xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
981 }
982 else
983 pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
984 }
985 }
986 }
987 }
988 }
989 }
990
991 return 1;
992 }
993
994
IMPL_LINK(MenuManager,Deactivate,Menu *,pMenu)995 IMPL_LINK( MenuManager, Deactivate, Menu *, pMenu )
996 {
997 if ( pMenu == m_pVCLMenu )
998 m_bActive = sal_False;
999
1000 return 1;
1001 }
1002
1003
IMPL_LINK(MenuManager,Select,Menu *,pMenu)1004 IMPL_LINK( MenuManager, Select, Menu *, pMenu )
1005 {
1006 URL aTargetURL;
1007 Sequence<PropertyValue> aArgs;
1008 REFERENCE< XDISPATCH > xDispatch;
1009
1010 {
1011 ResetableGuard aGuard( m_aLock );
1012
1013 sal_uInt16 nCurItemId = pMenu->GetCurItemId();
1014 if ( pMenu == m_pVCLMenu &&
1015 pMenu->GetItemType( nCurItemId ) != MENUITEM_SEPARATOR )
1016 {
1017 if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
1018 nCurItemId <= END_ITEMID_WINDOWLIST )
1019 {
1020 // window list menu item selected
1021
1022 // #110897#
1023 // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
1024 // DESKTOP_SERVICE ), UNO_QUERY );
1025 Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
1026
1027 if ( xDesktop.is() )
1028 {
1029 sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
1030 Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
1031 sal_Int32 nCount = xList->getCount();
1032 for ( sal_Int32 i=0; i<nCount; ++i )
1033 {
1034 Reference< XFrame > xFrame;
1035 xList->getByIndex(i) >>= xFrame;
1036
1037 if ( xFrame.is() && nTaskId == nCurItemId )
1038 {
1039 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1040 pWin->GrabFocus();
1041 pWin->ToTop( TOTOP_RESTOREWHENMIN );
1042 break;
1043 }
1044
1045 nTaskId++;
1046 }
1047 }
1048 }
1049 else
1050 {
1051 MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
1052 if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
1053 {
1054 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1055 m_xURLTransformer->parseStrict( aTargetURL );
1056
1057 if ( nCurItemId >= START_ITEMID_PICKLIST &&
1058 nCurItemId < START_ITEMID_WINDOWLIST )
1059 {
1060 // picklist menu item selected
1061 CreatePicklistArguments( aArgs, pMenuItemHandler );
1062 }
1063 else if ( m_bIsBookmarkMenu )
1064 {
1065 // bookmark menu item selected
1066 aArgs.realloc( 1 );
1067 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
1068 aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
1069 }
1070
1071 xDispatch = pMenuItemHandler->xMenuItemDispatch;
1072 }
1073 }
1074 }
1075 }
1076
1077 if ( xDispatch.is() )
1078 xDispatch->dispatch( aTargetURL, aArgs );
1079
1080 return 1;
1081 }
1082
1083
IMPL_LINK(MenuManager,Highlight,Menu *,EMPTYARG)1084 IMPL_LINK( MenuManager, Highlight, Menu *, EMPTYARG )
1085 {
1086 return 0;
1087 }
1088
1089 // #110897#
getServiceFactory()1090 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuManager::getServiceFactory()
1091 {
1092 // #110897#
1093 return mxServiceFactory;
1094 }
1095
AddMenu(PopupMenu * _pPopupMenu,const::rtl::OUString & _sItemCommand,sal_uInt16 _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)1096 void MenuManager::AddMenu(PopupMenu* _pPopupMenu,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)
1097 {
1098 MenuManager* pSubMenuManager = new MenuManager( getServiceFactory(), m_xFrame, _pPopupMenu, _bDelete, _bDeleteChildren );
1099
1100 // store menu item command as we later have to know which menu is active (see Activate handler)
1101 pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
1102
1103 REFERENCE< XDISPATCH > aXDispatchRef;
1104 MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
1105 _nItemId,
1106 pSubMenuManager,
1107 aXDispatchRef );
1108 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
1109 }
1110
FillItemCommand(::rtl::OUString & _rItemCommand,Menu * _pMenu,sal_uInt16 _nIndex) const1111 sal_uInt16 MenuManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const
1112 {
1113 sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
1114
1115 _rItemCommand = _pMenu->GetItemCommand( nItemId );
1116 if ( !_rItemCommand.getLength() )
1117 {
1118 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
1119 _rItemCommand = aSlotString;
1120 _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
1121 _pMenu->SetItemCommand( nItemId, _rItemCommand );
1122 }
1123 return nItemId;
1124 }
FillMenuImages(Reference<XFrame> & _xFrame,Menu * _pMenu,sal_Bool bIsHiContrast,sal_Bool bShowMenuImages)1125 void MenuManager::FillMenuImages(Reference< XFrame >& _xFrame,Menu* _pMenu,sal_Bool bIsHiContrast,sal_Bool bShowMenuImages)
1126 {
1127 AddonsOptions aAddonOptions;
1128
1129 for ( sal_uInt16 nPos = 0; nPos < _pMenu->GetItemCount(); nPos++ )
1130 {
1131 sal_uInt16 nId = _pMenu->GetItemId( nPos );
1132 if ( _pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
1133 {
1134 bool bTmpShowMenuImages( bShowMenuImages );
1135 MenuItemBits nBits = _pMenu->GetItemBits( nId );
1136 // overwrite the default?
1137 if ( nBits )
1138 bTmpShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
1139
1140 if ( bTmpShowMenuImages )
1141 {
1142 sal_Bool bImageSet = sal_False;
1143 ::rtl::OUString aImageId;
1144
1145 ::framework::MenuConfiguration::Attributes* pMenuAttributes =
1146 (::framework::MenuConfiguration::Attributes*)_pMenu->GetUserValue( nId );
1147
1148 if ( pMenuAttributes )
1149 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
1150
1151 if ( aImageId.getLength() > 0 )
1152 {
1153 Image aImage = GetImageFromURL( _xFrame, aImageId, sal_False, bIsHiContrast );
1154 if ( !!aImage )
1155 {
1156 bImageSet = sal_True;
1157 _pMenu->SetItemImage( nId, aImage );
1158 }
1159 }
1160
1161 if ( !bImageSet )
1162 {
1163 rtl::OUString aMenuItemCommand = _pMenu->GetItemCommand( nId );
1164 Image aImage = GetImageFromURL( _xFrame, aMenuItemCommand, sal_False, bIsHiContrast );
1165 if ( !aImage )
1166 aImage = aAddonOptions.GetImageFromURL( aMenuItemCommand, sal_False, bIsHiContrast );
1167
1168 _pMenu->SetItemImage( nId, aImage );
1169 }
1170 }
1171 else
1172 _pMenu->SetItemImage( nId, Image() );
1173 }
1174 }
1175 }
1176 }
1177