1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <classes/menumanager.hxx>
21 #include <framework/menuconfiguration.hxx>
22 #include <framework/bmkmenu.hxx>
23 #include <framework/addonmenu.hxx>
24 #include <framework/imageproducer.hxx>
25 #include <threadhelp/resetableguard.hxx>
26 #include "framework/addonsoptions.hxx"
27 #include <classes/fwkresid.hxx>
29 #include "classes/resource.hrc"
31 #include <com/sun/star/frame/XDispatchProvider.hpp>
32 #include <com/sun/star/frame/XDispatch.hpp>
33 #include <com/sun/star/util/URLTransformer.hpp>
34 #include <com/sun/star/util/XURLTransformer.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/frame/XFramesSupplier.hpp>
37 #include <com/sun/star/frame/Desktop.hpp>
38 #include <com/sun/star/container/XEnumeration.hpp>
39 #include <com/sun/star/util/XStringWidth.hpp>
41 #include <comphelper/processfactory.hxx>
43 #include <comphelper/extract.hxx>
44 #include <svtools/menuoptions.hxx>
45 #include <unotools/historyoptions.hxx>
46 #include <unotools/pathoptions.hxx>
47 #include <unotools/localfilehelper.hxx>
49 #include <toolkit/unohlp.hxx>
50 #include <tools/urlobj.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vcl/window.hxx>
54 #include <osl/mutex.hxx>
55 #include <osl/file.hxx>
56 #include <cppuhelper/implbase1.hxx>
58 using namespace ::cppu
;
59 using namespace ::com::sun::star::uno
;
60 using namespace ::com::sun::star::util
;
61 using namespace ::com::sun::star::beans
;
62 using namespace ::com::sun::star::frame
;
63 using namespace ::com::sun::star::lang
;
64 using namespace ::com::sun::star::container
;
66 class StringLength
: public ::cppu::WeakImplHelper1
< XStringWidth
>
70 virtual ~StringLength() {}
73 sal_Int32 SAL_CALL
queryStringWidth( const OUString
& aString
)
74 throw (RuntimeException
)
76 return aString
.getLength();
83 // special menu ids/command ids for dynamic popup menus
84 #define SID_SFX_START 5000
85 #define SID_NEWDOCDIRECT (SID_SFX_START + 537)
86 #define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
87 #define SID_ADDONLIST (SID_SFX_START + 1677)
89 #define SFX_REFERER_USER "private:user"
91 #define aSlotNewDocDirect "slot:5537"
92 #define aSlotAutoPilot "slot:6381"
94 #define aSpecialFileMenu "file"
95 #define aSpecialWindowMenu "window"
96 #define aSlotSpecialFileMenu "slot:5510"
97 #define aSlotSpecialWindowMenu "slot:5610"
98 #define aSlotSpecialToolsMenu "slot:6677"
100 // special uno commands for picklist and window list
101 #define aSpecialFileCommand "PickList"
102 #define aSpecialWindowCommand "WindowList"
104 const char UNO_COMMAND
[] = ".uno:";
106 MenuManager::MenuManager(
107 const Reference
< XComponentContext
>& rxContext
,
108 Reference
< XFrame
>& rFrame
, Menu
* pMenu
, sal_Bool bDelete
, sal_Bool bDeleteChildren
)
110 ThreadHelpBase( &Application::GetSolarMutex() ),
111 m_xContext(rxContext
)
113 m_bActive
= sal_False
;
114 m_bDeleteMenu
= bDelete
;
115 m_bDeleteChildren
= bDeleteChildren
;
118 m_bInitialized
= sal_False
;
119 m_bIsBookmarkMenu
= sal_False
;
121 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
122 m_bShowMenuImages
= rSettings
.GetUseImagesInMenus();
124 sal_Int32 nAddonsURLPrefixLength
= ADDONSPOPUPMENU_URL_PREFIX
.getLength();
127 sal_uInt16 nItemCount
= pMenu
->GetItemCount();
128 m_aMenuItemHandlerVector
.reserve(nItemCount
);
129 OUString aItemCommand
;
130 for ( sal_uInt16 i
= 0; i
< nItemCount
; i
++ )
132 sal_uInt16 nItemId
= FillItemCommand(aItemCommand
,pMenu
, i
);
133 bool bShowMenuImages( m_bShowMenuImages
);
135 // overwrite the show icons on menu option?
136 if (!bShowMenuImages
)
138 MenuItemBits nBits
= pMenu
->GetItemBits( nItemId
);
139 bShowMenuImages
= ( ( nBits
& MIB_ICON
) == MIB_ICON
);
142 PopupMenu
* pPopupMenu
= pMenu
->GetPopupMenu( nItemId
);
145 AddMenu(pPopupMenu
,aItemCommand
,nItemId
,bDeleteChildren
,bDeleteChildren
);
146 if (! (( aItemCommand
.getLength() > nAddonsURLPrefixLength
) &&
147 ( aItemCommand
.indexOf( ADDONSPOPUPMENU_URL_PREFIX
) == 0 )) )
150 // Create addon popup menu if there exist elements and this is the tools popup menu
151 if ( ( nItemId
== SID_ADDONLIST
|| aItemCommand
== aSlotSpecialToolsMenu
)
152 && AddonMenuManager::HasAddonMenuElements() )
154 AddonMenu
* pSubMenu
= AddonMenuManager::CreateAddonMenu( rFrame
);
155 if ( pSubMenu
&& ( pSubMenu
->GetItemCount() > 0 ))
157 sal_uInt16 nCount
= 0;
158 if ( pPopupMenu
->GetItemType( nCount
-1 ) != MENUITEM_SEPARATOR
)
159 pPopupMenu
->InsertSeparator();
161 // Use resource to load popup menu title
162 String aAddonsStrRes
= String( FwkResId( STR_MENU_ADDONS
));
163 pPopupMenu
->InsertItem( ITEMID_ADDONLIST
, aAddonsStrRes
);
164 pPopupMenu
->SetPopupMenu( ITEMID_ADDONLIST
, pSubMenu
);
166 // Set item command for popup menu to enable it for GetImageFromURL
167 const static OUString
aSlotString( "slot:" );
168 aItemCommand
= aSlotString
;
169 aItemCommand
+= OUString::valueOf( (sal_Int32
)ITEMID_ADDONLIST
);
170 pPopupMenu
->SetItemCommand( ITEMID_ADDONLIST
, aItemCommand
);
172 AddMenu(pSubMenu
,OUString(),nItemId
,sal_True
,sal_False
);
173 // Set image for the addon popup menu item
174 if ( bShowMenuImages
&& !pPopupMenu
->GetItemImage( ITEMID_ADDONLIST
))
176 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
178 pPopupMenu
->SetItemImage( ITEMID_ADDONLIST
, aImage
);
188 if ( nItemId
== SID_NEWDOCDIRECT
|| aItemCommand
== aSlotNewDocDirect
)
190 MenuConfiguration
aMenuCfg( m_xContext
);
191 BmkMenu
* pSubMenu
= (BmkMenu
*)aMenuCfg
.CreateBookmarkMenu( rFrame
, BOOKMARK_NEWMENU
);
192 pMenu
->SetPopupMenu( nItemId
, pSubMenu
);
194 AddMenu(pSubMenu
,OUString(),nItemId
,sal_True
,sal_False
);
195 if ( bShowMenuImages
&& !pMenu
->GetItemImage( nItemId
))
197 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
199 pMenu
->SetItemImage( nItemId
, aImage
);
202 else if ( nItemId
== SID_AUTOPILOTMENU
|| aItemCommand
== aSlotAutoPilot
)
204 MenuConfiguration
aMenuCfg( m_xContext
);
205 BmkMenu
* pSubMenu
= (BmkMenu
*)aMenuCfg
.CreateBookmarkMenu( rFrame
, BOOKMARK_WIZARDMENU
);
206 pMenu
->SetPopupMenu( nItemId
, pSubMenu
);
208 AddMenu(pSubMenu
,OUString(),nItemId
,sal_True
,sal_False
);
211 if ( bShowMenuImages
&& !pMenu
->GetItemImage( nItemId
))
213 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
215 pMenu
->SetItemImage( nItemId
, aImage
);
218 else if ( pMenu
->GetItemType( i
) != MENUITEM_SEPARATOR
)
220 if ( bShowMenuImages
)
222 if ( AddonMenuManager::IsAddonMenuId( nItemId
))
224 // Add-Ons uses a images from different places
228 MenuConfiguration::Attributes
* pMenuAttributes
=
229 (MenuConfiguration::Attributes
*)pMenu
->GetUserValue( nItemId
);
231 if ( pMenuAttributes
&& !pMenuAttributes
->aImageId
.isEmpty() )
233 // Retrieve image id from menu attributes
234 aImage
= GetImageFromURL( rFrame
, aImageId
, false );
239 aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
241 aImage
= AddonsOptions().GetImageFromURL( aItemCommand
, false );
245 pMenu
->SetItemImage( nItemId
, aImage
);
247 else if ( !pMenu
->GetItemImage( nItemId
))
249 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
251 pMenu
->SetItemImage( nItemId
, aImage
);
255 Reference
< XDispatch
> aXDispatchRef
;
256 m_aMenuItemHandlerVector
.push_back( new MenuItemHandler( nItemId
, NULL
, aXDispatchRef
));
262 // retrieve label information for all menu items without item text
268 void MenuManager::SetHdl()
270 m_pVCLMenu
->SetHighlightHdl( LINK( this, MenuManager
, Highlight
));
271 m_pVCLMenu
->SetActivateHdl( LINK( this, MenuManager
, Activate
));
272 m_pVCLMenu
->SetDeactivateHdl( LINK( this, MenuManager
, Deactivate
));
273 m_pVCLMenu
->SetSelectHdl( LINK( this, MenuManager
, Select
));
275 if ( m_xContext
.is() )
276 m_xURLTransformer
.set( URLTransformer::create( m_xContext
) );
279 MenuManager::~MenuManager()
281 std::vector
< MenuItemHandler
* >::iterator p
;
282 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
284 MenuItemHandler
* pItemHandler
= *p
;
285 pItemHandler
->xMenuItemDispatch
.clear();
286 if ( pItemHandler
->pSubMenuManager
)
287 (static_cast< XInterface
* >((OWeakObject
*)pItemHandler
->pSubMenuManager
))->release();
296 MenuManager::MenuItemHandler
* MenuManager::GetMenuItemHandler( sal_uInt16 nItemId
)
298 ResetableGuard
aGuard( m_aLock
);
300 std::vector
< MenuItemHandler
* >::iterator p
;
301 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
303 MenuItemHandler
* pItemHandler
= *p
;
304 if ( pItemHandler
->nItemId
== nItemId
)
312 void SAL_CALL
MenuManager::statusChanged( const FeatureStateEvent
& Event
)
313 throw ( RuntimeException
)
315 OUString aFeatureURL
= Event
.FeatureURL
.Complete
;
316 MenuItemHandler
* pStatusChangedMenu
= NULL
;
319 ResetableGuard
aGuard( m_aLock
);
321 std::vector
< MenuItemHandler
* >::iterator p
;
322 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
324 MenuItemHandler
* pMenuItemHandler
= *p
;
325 if ( pMenuItemHandler
->aMenuItemURL
== aFeatureURL
)
327 pStatusChangedMenu
= pMenuItemHandler
;
333 if ( pStatusChangedMenu
)
335 SolarMutexGuard aSolarGuard
;
337 ResetableGuard
aGuard( m_aLock
);
339 sal_Bool bSetCheckmark
= sal_False
;
340 sal_Bool bCheckmark
= sal_False
;
341 sal_Bool bMenuItemEnabled
= m_pVCLMenu
->IsItemEnabled( pStatusChangedMenu
->nItemId
);
343 if ( Event
.IsEnabled
!= bMenuItemEnabled
)
344 m_pVCLMenu
->EnableItem( pStatusChangedMenu
->nItemId
, Event
.IsEnabled
);
346 if ( Event
.State
>>= bCheckmark
)
347 bSetCheckmark
= sal_True
;
350 m_pVCLMenu
->CheckItem( pStatusChangedMenu
->nItemId
, bCheckmark
);
356 aTargetURL
.Complete
= pStatusChangedMenu
->aMenuItemURL
;
358 m_xURLTransformer
->parseStrict( aTargetURL
);
360 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
361 Reference
< XDispatch
> xMenuItemDispatch
= xDispatchProvider
->queryDispatch(
362 aTargetURL
, OUString(), 0 );
364 if ( xMenuItemDispatch
.is() )
366 pStatusChangedMenu
->xMenuItemDispatch
= xMenuItemDispatch
;
367 pStatusChangedMenu
->aMenuItemURL
= aTargetURL
.Complete
;
368 xMenuItemDispatch
->addStatusListener( (static_cast< XStatusListener
* >(this)), aTargetURL
);
375 void MenuManager::RemoveListener()
377 ResetableGuard
aGuard( m_aLock
);
381 void MenuManager::ClearMenuDispatch(const EventObject
& Source
,bool _bRemoveOnly
)
383 // disposing called from parent dispatcher
384 // remove all listener to prepare shutdown
386 std::vector
< MenuItemHandler
* >::iterator p
;
387 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
389 MenuItemHandler
* pItemHandler
= *p
;
390 if ( pItemHandler
->xMenuItemDispatch
.is() )
393 aTargetURL
.Complete
= pItemHandler
->aMenuItemURL
;
394 m_xURLTransformer
->parseStrict( aTargetURL
);
396 pItemHandler
->xMenuItemDispatch
->removeStatusListener(
397 (static_cast< XStatusListener
* >(this)), aTargetURL
);
400 pItemHandler
->xMenuItemDispatch
.clear();
401 if ( pItemHandler
->pSubMenuManager
)
404 pItemHandler
->pSubMenuManager
->RemoveListener();
406 pItemHandler
->pSubMenuManager
->disposing( Source
);
412 void SAL_CALL
MenuManager::disposing( const EventObject
& Source
) throw ( RuntimeException
)
414 if ( Source
.Source
== m_xFrame
)
416 ResetableGuard
aGuard( m_aLock
);
417 ClearMenuDispatch(Source
,false);
421 // disposing called from menu item dispatcher, remove listener
422 MenuItemHandler
* pMenuItemDisposing
= NULL
;
425 ResetableGuard
aGuard( m_aLock
);
427 std::vector
< MenuItemHandler
* >::iterator p
;
428 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
430 MenuItemHandler
* pMenuItemHandler
= *p
;
431 if ( pMenuItemHandler
->xMenuItemDispatch
== Source
.Source
)
433 pMenuItemDisposing
= pMenuItemHandler
;
438 if ( pMenuItemDisposing
)
441 aTargetURL
.Complete
= pMenuItemDisposing
->aMenuItemURL
;
443 m_xURLTransformer
->parseStrict( aTargetURL
);
445 pMenuItemDisposing
->xMenuItemDispatch
->removeStatusListener((static_cast< XStatusListener
* >(this)), aTargetURL
);
446 pMenuItemDisposing
->xMenuItemDispatch
.clear();
453 void MenuManager::UpdateSpecialFileMenu( Menu
* pMenu
)
456 Sequence
< Sequence
< PropertyValue
> > aHistoryList
= SvtHistoryOptions().GetList( ePICKLIST
);
457 ::std::vector
< MenuItemHandler
* > aNewPickVector
;
458 Reference
< XStringWidth
> xStringLength( new StringLength
);
460 sal_uInt16 nPickItemId
= START_ITEMID_PICKLIST
;
461 int nPickListMenuItems
= ( aHistoryList
.getLength() > 99 ) ? 99 : aHistoryList
.getLength();
463 aNewPickVector
.reserve(nPickListMenuItems
);
464 for ( int i
= 0; i
< nPickListMenuItems
; i
++ )
466 Sequence
< PropertyValue
> aPickListEntry
= aHistoryList
[i
];
468 Reference
< XDispatch
> aXDispatchRef
;
469 MenuItemHandler
* pNewMenuItemHandler
= new MenuItemHandler(
474 for ( int j
= 0; j
< aPickListEntry
.getLength(); j
++ )
476 Any a
= aPickListEntry
[j
].Value
;
478 if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_URL
)
479 a
>>= pNewMenuItemHandler
->aMenuItemURL
;
480 else if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_FILTER
)
481 a
>>= pNewMenuItemHandler
->aFilter
;
482 else if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_TITLE
)
483 a
>>= pNewMenuItemHandler
->aTitle
;
484 else if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_PASSWORD
)
485 a
>>= pNewMenuItemHandler
->aPassword
;
488 aNewPickVector
.push_back( pNewMenuItemHandler
);
491 if ( !aNewPickVector
.empty() )
494 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
496 Reference
< XDispatch
> xMenuItemDispatch
;
498 static const OUString
s_sDefault("_default");
499 // query for dispatcher
500 std::vector
< MenuItemHandler
* >::iterator p
;
501 for ( p
= aNewPickVector
.begin(); p
!= aNewPickVector
.end(); ++p
)
503 MenuItemHandler
* pMenuItemHandler
= *p
;
505 aTargetURL
.Complete
= pMenuItemHandler
->aMenuItemURL
;
506 m_xURLTransformer
->parseStrict( aTargetURL
);
508 if ( !xMenuItemDispatch
.is() )
510 // attention: this code assume that "_blank" can only be consumed by desktop service
511 xMenuItemDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, s_sDefault
, 0 );
514 if ( xMenuItemDispatch
.is() )
516 pMenuItemHandler
->xMenuItemDispatch
= xMenuItemDispatch
;
517 pMenuItemHandler
->aMenuItemURL
= aTargetURL
.Complete
;
522 ResetableGuard
aGuard( m_aLock
);
524 int nRemoveItemCount
= 0;
525 int nItemCount
= pMenu
->GetItemCount();
527 if ( nItemCount
> 0 )
529 // remove all old picklist entries from menu
530 sal_uInt16 nPos
= pMenu
->GetItemPos( START_ITEMID_PICKLIST
);
531 for ( sal_uInt16 n
= nPos
; n
< pMenu
->GetItemCount(); )
533 pMenu
->RemoveItem( n
);
537 if ( pMenu
->GetItemType( pMenu
->GetItemCount()-1 ) == MENUITEM_SEPARATOR
)
538 pMenu
->RemoveItem( pMenu
->GetItemCount()-1 );
540 // remove all old picklist entries from menu handler
541 if ( nRemoveItemCount
> 0 )
543 for( sal_uInt32 nIndex
= m_aMenuItemHandlerVector
.size() - nRemoveItemCount
;
544 nIndex
< m_aMenuItemHandlerVector
.size(); )
546 delete m_aMenuItemHandlerVector
.at( nIndex
);
547 m_aMenuItemHandlerVector
.erase( m_aMenuItemHandlerVector
.begin() + nIndex
);
552 // append new picklist menu entries
553 aNewPickVector
.reserve(aNewPickVector
.size());
554 pMenu
->InsertSeparator();
555 const sal_uInt32 nCount
= aNewPickVector
.size();
556 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
558 char menuShortCut
[5] = "~n: ";
560 OUString aMenuShortCut
;
564 aMenuShortCut
= OUString( "1~0: " );
567 menuShortCut
[1] = (char)( '1' + i
);
568 aMenuShortCut
= OUString::createFromAscii( menuShortCut
);
573 aMenuShortCut
= OUString::valueOf((sal_Int32
)( i
+ 1 ));
574 aMenuShortCut
+= ": ";
578 OUString
aURLString( aNewPickVector
.at( i
)->aMenuItemURL
);
579 OUString aTipHelpText
;
581 INetURLObject
aURL( aURLString
);
583 if ( aURL
.GetProtocol() == INET_PROT_FILE
)
585 // Do handle file URL differently => convert it to a system
586 // path and abbreviate it with a special function:
587 String
aFileSystemPath( aURL
.getFSysPath( INetURLObject::FSYS_DETECT
) );
589 OUString
aSystemPath( aFileSystemPath
);
590 OUString aCompactedSystemPath
;
592 aTipHelpText
= aSystemPath
;
593 oslFileError nError
= osl_abbreviateSystemPath( aSystemPath
.pData
, &aCompactedSystemPath
.pData
, 46, NULL
);
595 aMenuTitle
= String( aCompactedSystemPath
);
597 aMenuTitle
= aSystemPath
;
601 // Use INetURLObject to abbreviate all other URLs
603 aShortURL
= aURL
.getAbbreviated( xStringLength
, 46, INetURLObject::DECODE_UNAMBIGUOUS
);
604 aMenuTitle
+= aShortURL
;
605 aTipHelpText
= aURLString
;
608 OUString
aTitle( aMenuShortCut
+ aMenuTitle
);
610 MenuItemHandler
* pMenuItemHandler
= aNewPickVector
.at( i
);
611 pMenu
->InsertItem( pMenuItemHandler
->nItemId
, aTitle
);
612 pMenu
->SetTipHelpText( pMenuItemHandler
->nItemId
, aTipHelpText
);
613 m_aMenuItemHandlerVector
.push_back( pMenuItemHandler
);
619 void MenuManager::UpdateSpecialWindowMenu( Menu
* pMenu
,const Reference
< XComponentContext
>& xContext
,framework::IMutex
& _rMutex
)
621 // update window list
622 ::std::vector
< OUString
> aNewWindowListVector
;
624 Reference
< XDesktop2
> xDesktop
= Desktop::create( xContext
);
626 sal_uInt16 nActiveItemId
= 0;
627 sal_uInt16 nItemId
= START_ITEMID_WINDOWLIST
;
629 Reference
< XFrame
> xCurrentFrame
= xDesktop
->getCurrentFrame();
630 Reference
< XIndexAccess
> xList( xDesktop
->getFrames(), UNO_QUERY
);
631 sal_Int32 nFrameCount
= xList
->getCount();
632 aNewWindowListVector
.reserve(nFrameCount
);
633 for (sal_Int32 i
=0; i
<nFrameCount
; ++i
)
635 Reference
< XFrame
> xFrame
;
636 xList
->getByIndex(i
) >>= xFrame
;
640 if ( xFrame
== xCurrentFrame
)
641 nActiveItemId
= nItemId
;
643 Window
* pWin
= VCLUnoHelper::GetWindow( xFrame
->getContainerWindow() );
644 if ( pWin
&& pWin
->IsVisible() )
646 aNewWindowListVector
.push_back( pWin
->GetText() );
653 ResetableGuard
aGuard( _rMutex
);
655 int nItemCount
= pMenu
->GetItemCount();
657 if ( nItemCount
> 0 )
659 // remove all old window list entries from menu
660 sal_uInt16 nPos
= pMenu
->GetItemPos( START_ITEMID_WINDOWLIST
);
661 for ( sal_uInt16 n
= nPos
; n
< pMenu
->GetItemCount(); )
662 pMenu
->RemoveItem( n
);
664 if ( pMenu
->GetItemType( pMenu
->GetItemCount()-1 ) == MENUITEM_SEPARATOR
)
665 pMenu
->RemoveItem( pMenu
->GetItemCount()-1 );
668 if ( !aNewWindowListVector
.empty() )
670 // append new window list entries to menu
671 pMenu
->InsertSeparator();
672 nItemId
= START_ITEMID_WINDOWLIST
;
673 const sal_uInt32 nCount
= aNewWindowListVector
.size();
674 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
676 pMenu
->InsertItem( nItemId
, aNewWindowListVector
.at( i
), MIB_RADIOCHECK
);
677 if ( nItemId
== nActiveItemId
)
678 pMenu
->CheckItem( nItemId
);
686 void MenuManager::CreatePicklistArguments( Sequence
< PropertyValue
>& aArgsList
, const MenuItemHandler
* pMenuItemHandler
)
688 int NUM_OF_PICKLIST_ARGS
= 3;
691 aArgsList
.realloc( NUM_OF_PICKLIST_ARGS
);
693 aArgsList
[0].Name
= OUString( "FileName" );
694 a
<<= pMenuItemHandler
->aMenuItemURL
;
695 aArgsList
[0].Value
= a
;
697 aArgsList
[1].Name
= OUString( "Referer" );
698 a
<<= OUString( SFX_REFERER_USER
);
699 aArgsList
[1].Value
= a
;
701 OUString
aFilter( pMenuItemHandler
->aFilter
);
703 sal_Int32 nPos
= aFilter
.indexOf( '|' );
706 OUString aFilterOptions
;
708 if ( nPos
< ( aFilter
.getLength() - 1 ) )
709 aFilterOptions
= aFilter
.copy( nPos
+1 );
711 aArgsList
[2].Name
= OUString( "FilterOptions" );
712 a
<<= aFilterOptions
;
713 aArgsList
[2].Value
= a
;
715 aFilter
= aFilter
.copy( 0, nPos
-1 );
716 aArgsList
.realloc( ++NUM_OF_PICKLIST_ARGS
);
719 aArgsList
[NUM_OF_PICKLIST_ARGS
-1].Name
= OUString( "FilterName" );
721 aArgsList
[NUM_OF_PICKLIST_ARGS
-1].Value
= a
;
725 //_________________________________________________________________________________________________________________
727 //_________________________________________________________________________________________________________________
729 IMPL_LINK( MenuManager
, Activate
, Menu
*, pMenu
)
731 if ( pMenu
== m_pVCLMenu
)
733 // set/unset hiding disabled menu entries
734 sal_Bool bDontHide
= SvtMenuOptions().IsEntryHidingEnabled();
735 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
736 sal_Bool bShowMenuImages
= rSettings
.GetUseImagesInMenus();
738 sal_uInt16 nFlag
= pMenu
->GetMenuFlags();
740 nFlag
&= ~MENU_FLAG_HIDEDISABLEDENTRIES
;
742 nFlag
|= MENU_FLAG_HIDEDISABLEDENTRIES
;
743 pMenu
->SetMenuFlags( nFlag
);
748 m_bActive
= sal_True
;
750 OUString
aCommand( m_aMenuItemCommand
);
751 if (m_aMenuItemCommand
.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(UNO_COMMAND
)))
753 // Remove protocol part from command so we can use an easier comparision method
754 aCommand
= aCommand
.copy(RTL_CONSTASCII_LENGTH(UNO_COMMAND
));
757 if ( m_aMenuItemCommand
== aSpecialFileMenu
|| m_aMenuItemCommand
== aSlotSpecialFileMenu
|| aCommand
== aSpecialFileCommand
)
758 UpdateSpecialFileMenu( pMenu
);
759 else if ( m_aMenuItemCommand
== aSpecialWindowMenu
|| m_aMenuItemCommand
== aSlotSpecialWindowMenu
|| aCommand
== aSpecialWindowCommand
)
760 UpdateSpecialWindowMenu( pMenu
, m_xContext
, m_aLock
);
762 // Check if some modes have changed so we have to update our menu images
763 if ( bShowMenuImages
!= m_bShowMenuImages
)
765 // The mode changed so we have to replace all images
766 m_bShowMenuImages
= bShowMenuImages
;
767 FillMenuImages( m_xFrame
, pMenu
, bShowMenuImages
);
770 if ( m_bInitialized
)
776 ResetableGuard
aGuard( m_aLock
);
778 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
779 if ( xDispatchProvider
.is() )
781 std::vector
< MenuItemHandler
* >::iterator p
;
782 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
784 MenuItemHandler
* pMenuItemHandler
= *p
;
785 if ( pMenuItemHandler
&&
786 pMenuItemHandler
->pSubMenuManager
== 0 &&
787 !pMenuItemHandler
->xMenuItemDispatch
.is() )
789 // There is no dispatch mechanism for the special window list menu items,
790 // because they are handled directly through XFrame->activate!!!
791 if ( pMenuItemHandler
->nItemId
< START_ITEMID_WINDOWLIST
||
792 pMenuItemHandler
->nItemId
> END_ITEMID_WINDOWLIST
)
794 OUString aItemCommand
= pMenu
->GetItemCommand( pMenuItemHandler
->nItemId
);
795 if ( aItemCommand
.isEmpty() )
797 const static OUString
aSlotString( "slot:" );
798 aItemCommand
= aSlotString
;
799 aItemCommand
+= OUString::valueOf( (sal_Int32
)pMenuItemHandler
->nItemId
);
800 pMenu
->SetItemCommand( pMenuItemHandler
->nItemId
, aItemCommand
);
803 aTargetURL
.Complete
= aItemCommand
;
805 m_xURLTransformer
->parseStrict( aTargetURL
);
807 Reference
< XDispatch
> xMenuItemDispatch
;
808 if ( m_bIsBookmarkMenu
)
809 xMenuItemDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, pMenuItemHandler
->aTargetFrame
, 0 );
811 xMenuItemDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
813 if ( xMenuItemDispatch
.is() )
815 pMenuItemHandler
->xMenuItemDispatch
= xMenuItemDispatch
;
816 pMenuItemHandler
->aMenuItemURL
= aTargetURL
.Complete
;
817 xMenuItemDispatch
->addStatusListener( (static_cast< XStatusListener
* >(this)), aTargetURL
);
820 pMenu
->EnableItem( pMenuItemHandler
->nItemId
, sal_False
);
832 IMPL_LINK( MenuManager
, Deactivate
, Menu
*, pMenu
)
834 if ( pMenu
== m_pVCLMenu
)
835 m_bActive
= sal_False
;
841 IMPL_LINK( MenuManager
, Select
, Menu
*, pMenu
)
844 Sequence
<PropertyValue
> aArgs
;
845 Reference
< XDispatch
> xDispatch
;
848 ResetableGuard
aGuard( m_aLock
);
850 sal_uInt16 nCurItemId
= pMenu
->GetCurItemId();
851 if ( pMenu
== m_pVCLMenu
&&
852 pMenu
->GetItemType( nCurItemId
) != MENUITEM_SEPARATOR
)
854 if ( nCurItemId
>= START_ITEMID_WINDOWLIST
&&
855 nCurItemId
<= END_ITEMID_WINDOWLIST
)
857 // window list menu item selected
859 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_xContext
);
861 sal_uInt16 nTaskId
= START_ITEMID_WINDOWLIST
;
862 Reference
< XIndexAccess
> xList( xDesktop
->getFrames(), UNO_QUERY
);
863 sal_Int32 nCount
= xList
->getCount();
864 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
866 Reference
< XFrame
> xFrame
;
867 xList
->getByIndex(i
) >>= xFrame
;
869 if ( xFrame
.is() && nTaskId
== nCurItemId
)
871 Window
* pWin
= VCLUnoHelper::GetWindow( xFrame
->getContainerWindow() );
873 pWin
->ToTop( TOTOP_RESTOREWHENMIN
);
882 MenuItemHandler
* pMenuItemHandler
= GetMenuItemHandler( nCurItemId
);
883 if ( pMenuItemHandler
&& pMenuItemHandler
->xMenuItemDispatch
.is() )
885 aTargetURL
.Complete
= pMenuItemHandler
->aMenuItemURL
;
886 m_xURLTransformer
->parseStrict( aTargetURL
);
888 if ( nCurItemId
>= START_ITEMID_PICKLIST
&&
889 nCurItemId
< START_ITEMID_WINDOWLIST
)
891 // picklist menu item selected
892 CreatePicklistArguments( aArgs
, pMenuItemHandler
);
894 else if ( m_bIsBookmarkMenu
)
896 // bookmark menu item selected
898 aArgs
[0].Name
= OUString( "Referer" );
899 aArgs
[0].Value
<<= OUString( SFX_REFERER_USER
);
902 xDispatch
= pMenuItemHandler
->xMenuItemDispatch
;
908 if ( xDispatch
.is() )
909 xDispatch
->dispatch( aTargetURL
, aArgs
);
915 IMPL_LINK_NOARG(MenuManager
, Highlight
)
920 const Reference
< XComponentContext
>& MenuManager::getContext()
925 void MenuManager::AddMenu(PopupMenu
* _pPopupMenu
,const OUString
& _sItemCommand
,sal_uInt16 _nItemId
,sal_Bool _bDelete
,sal_Bool _bDeleteChildren
)
927 MenuManager
* pSubMenuManager
= new MenuManager( m_xContext
, m_xFrame
, _pPopupMenu
, _bDelete
, _bDeleteChildren
);
929 // store menu item command as we later have to know which menu is active (see Activate handler)
930 pSubMenuManager
->m_aMenuItemCommand
= _sItemCommand
;
932 Reference
< XDispatch
> aXDispatchRef
;
933 MenuItemHandler
* pMenuItemHandler
= new MenuItemHandler(
937 m_aMenuItemHandlerVector
.push_back( pMenuItemHandler
);
940 sal_uInt16
MenuManager::FillItemCommand(OUString
& _rItemCommand
, Menu
* _pMenu
,sal_uInt16 _nIndex
) const
942 sal_uInt16 nItemId
= _pMenu
->GetItemId( _nIndex
);
944 _rItemCommand
= _pMenu
->GetItemCommand( nItemId
);
945 if ( _rItemCommand
.isEmpty() )
947 const static OUString
aSlotString( "slot:" );
948 _rItemCommand
= aSlotString
;
949 _rItemCommand
+= OUString::valueOf( (sal_Int32
)nItemId
);
950 _pMenu
->SetItemCommand( nItemId
, _rItemCommand
);
954 void MenuManager::FillMenuImages(Reference
< XFrame
>& _xFrame
, Menu
* _pMenu
,sal_Bool bShowMenuImages
)
956 AddonsOptions aAddonOptions
;
958 for ( sal_uInt16 nPos
= 0; nPos
< _pMenu
->GetItemCount(); nPos
++ )
960 sal_uInt16 nId
= _pMenu
->GetItemId( nPos
);
961 if ( _pMenu
->GetItemType( nPos
) != MENUITEM_SEPARATOR
)
963 bool bTmpShowMenuImages( bShowMenuImages
);
964 // overwrite the show icons on menu option?
965 if (!bTmpShowMenuImages
)
967 MenuItemBits nBits
= _pMenu
->GetItemBits( nId
);
968 bTmpShowMenuImages
= ( ( nBits
& MIB_ICON
) == MIB_ICON
);
971 if ( bTmpShowMenuImages
)
973 sal_Bool bImageSet
= sal_False
;
976 ::framework::MenuConfiguration::Attributes
* pMenuAttributes
=
977 (::framework::MenuConfiguration::Attributes
*)_pMenu
->GetUserValue( nId
);
979 if ( pMenuAttributes
)
980 aImageId
= pMenuAttributes
->aImageId
; // Retrieve image id from menu attributes
982 if ( !aImageId
.isEmpty() )
984 Image aImage
= GetImageFromURL( _xFrame
, aImageId
, false );
987 bImageSet
= sal_True
;
988 _pMenu
->SetItemImage( nId
, aImage
);
994 OUString aMenuItemCommand
= _pMenu
->GetItemCommand( nId
);
995 Image aImage
= GetImageFromURL( _xFrame
, aMenuItemCommand
, false );
997 aImage
= aAddonOptions
.GetImageFromURL( aMenuItemCommand
, false );
999 _pMenu
->SetItemImage( nId
, aImage
);
1003 _pMenu
->SetItemImage( nId
, Image() );
1009 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */