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