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 <framework/addonsoptions.hxx>
26 #include <classes/fwkresid.hxx>
28 #include "classes/resource.hrc"
30 #include <com/sun/star/frame/XDispatchProvider.hpp>
31 #include <com/sun/star/frame/XDispatch.hpp>
32 #include <com/sun/star/util/URLTransformer.hpp>
33 #include <com/sun/star/util/XURLTransformer.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/frame/XFramesSupplier.hpp>
36 #include <com/sun/star/frame/Desktop.hpp>
37 #include <com/sun/star/container/XEnumeration.hpp>
38 #include <com/sun/star/util/XStringWidth.hpp>
40 #include <comphelper/processfactory.hxx>
42 #include <comphelper/extract.hxx>
43 #include <svtools/menuoptions.hxx>
44 #include <unotools/historyoptions.hxx>
45 #include <unotools/pathoptions.hxx>
46 #include <unotools/localfilehelper.hxx>
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include <tools/urlobj.hxx>
51 #include <vcl/svapp.hxx>
52 #include <vcl/window.hxx>
53 #include <vcl/settings.hxx>
55 #include <osl/mutex.hxx>
56 #include <osl/file.hxx>
57 #include <cppuhelper/implbase1.hxx>
59 using namespace ::cppu
;
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::util
;
62 using namespace ::com::sun::star::beans
;
63 using namespace ::com::sun::star::frame
;
64 using namespace ::com::sun::star::lang
;
65 using namespace ::com::sun::star::container
;
67 class StringLength
: public ::cppu::WeakImplHelper1
< XStringWidth
>
71 virtual ~StringLength() {}
74 sal_Int32 SAL_CALL
queryStringWidth( const OUString
& aString
)
75 throw (RuntimeException
, std::exception
) SAL_OVERRIDE
77 return aString
.getLength();
84 // special menu ids/command ids for dynamic popup menus
85 #define SID_SFX_START 5000
86 #define SID_NEWDOCDIRECT (SID_SFX_START + 537)
87 #define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
88 #define SID_ADDONLIST (SID_SFX_START + 1677)
90 #define aSlotNewDocDirect "slot:5537"
91 #define aSlotAutoPilot "slot:6381"
93 #define aSpecialFileMenu "file"
94 #define aSpecialWindowMenu "window"
95 #define aSlotSpecialFileMenu "slot:5510"
96 #define aSlotSpecialWindowMenu "slot:5610"
97 #define aSlotSpecialToolsMenu "slot:6677"
99 // special uno commands for picklist and window list
100 #define aSpecialFileCommand "PickList"
101 #define aSpecialWindowCommand "WindowList"
103 const char UNO_COMMAND
[] = ".uno:";
105 MenuManager::MenuManager(
106 const Reference
< XComponentContext
>& rxContext
,
107 Reference
< XFrame
>& rFrame
, Menu
* pMenu
, bool bDelete
, bool bDeleteChildren
)
109 m_xContext(rxContext
)
112 m_bDeleteMenu
= bDelete
;
113 m_bDeleteChildren
= bDeleteChildren
;
116 m_bInitialized
= false;
117 m_bIsBookmarkMenu
= false;
119 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
120 m_bShowMenuImages
= rSettings
.GetUseImagesInMenus();
122 sal_uInt16 nItemCount
= pMenu
->GetItemCount();
123 m_aMenuItemHandlerVector
.reserve(nItemCount
);
124 OUString aItemCommand
;
125 for ( sal_uInt16 i
= 0; i
< nItemCount
; i
++ )
127 sal_uInt16 nItemId
= FillItemCommand(aItemCommand
,pMenu
, i
);
128 bool bShowMenuImages( m_bShowMenuImages
);
130 // overwrite the show icons on menu option?
131 if (!bShowMenuImages
)
133 MenuItemBits nBits
= pMenu
->GetItemBits( nItemId
);
134 bShowMenuImages
= ( ( nBits
& MenuItemBits::ICON
) == MenuItemBits::ICON
);
137 PopupMenu
* pPopupMenu
= pMenu
->GetPopupMenu( nItemId
);
140 AddMenu(pPopupMenu
,aItemCommand
,nItemId
,bDeleteChildren
,bDeleteChildren
);
141 if (! ( aItemCommand
.startsWith( ADDONSPOPUPMENU_URL_PREFIX_STR
) ) )
144 // Create addon popup menu if there exist elements and this is the tools popup menu
145 if ( ( nItemId
== SID_ADDONLIST
|| aItemCommand
== aSlotSpecialToolsMenu
)
146 && AddonMenuManager::HasAddonMenuElements() )
148 AddonMenu
* pSubMenu
= AddonMenuManager::CreateAddonMenu(rFrame
, rxContext
);
149 if ( pSubMenu
&& ( pSubMenu
->GetItemCount() > 0 ))
151 sal_uInt16 nCount
= 0;
152 if ( pPopupMenu
->GetItemType( nCount
-1 ) != MenuItemType::SEPARATOR
)
153 pPopupMenu
->InsertSeparator();
155 // Use resource to load popup menu title
156 OUString
aAddonsStrRes(FWK_RESSTR(STR_MENU_ADDONS
));
157 pPopupMenu
->InsertItem( ITEMID_ADDONLIST
, aAddonsStrRes
);
158 pPopupMenu
->SetPopupMenu( ITEMID_ADDONLIST
, pSubMenu
);
160 // Set item command for popup menu to enable it for GetImageFromURL
161 aItemCommand
= "slot:" + OUString::number( ITEMID_ADDONLIST
);
162 pPopupMenu
->SetItemCommand( ITEMID_ADDONLIST
, aItemCommand
);
164 AddMenu(pSubMenu
,OUString(),nItemId
,true,false);
165 // Set image for the addon popup menu item
166 if ( bShowMenuImages
&& !pPopupMenu
->GetItemImage( ITEMID_ADDONLIST
))
168 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
170 pPopupMenu
->SetItemImage( ITEMID_ADDONLIST
, aImage
);
180 if ( nItemId
== SID_NEWDOCDIRECT
|| aItemCommand
== aSlotNewDocDirect
)
182 MenuConfiguration
aMenuCfg( m_xContext
);
183 BmkMenu
* pSubMenu
= static_cast<BmkMenu
*>(aMenuCfg
.CreateBookmarkMenu( rFrame
, BOOKMARK_NEWMENU
));
184 pMenu
->SetPopupMenu( nItemId
, pSubMenu
);
186 AddMenu(pSubMenu
,OUString(),nItemId
,true,false);
187 if ( bShowMenuImages
&& !pMenu
->GetItemImage( nItemId
))
189 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
191 pMenu
->SetItemImage( nItemId
, aImage
);
194 else if ( nItemId
== SID_AUTOPILOTMENU
|| aItemCommand
== aSlotAutoPilot
)
196 MenuConfiguration
aMenuCfg( m_xContext
);
197 BmkMenu
* pSubMenu
= static_cast<BmkMenu
*>(aMenuCfg
.CreateBookmarkMenu( rFrame
, BOOKMARK_WIZARDMENU
));
198 pMenu
->SetPopupMenu( nItemId
, pSubMenu
);
200 AddMenu(pSubMenu
,OUString(),nItemId
,true,false);
202 if ( bShowMenuImages
&& !pMenu
->GetItemImage( nItemId
))
204 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
206 pMenu
->SetItemImage( nItemId
, aImage
);
209 else if ( pMenu
->GetItemType( i
) != MenuItemType::SEPARATOR
)
211 if ( bShowMenuImages
)
213 if ( AddonMenuManager::IsAddonMenuId( nItemId
))
215 // Add-Ons uses a images from different places
219 MenuAttributes
* pMenuAttributes
=
220 reinterpret_cast<MenuAttributes
*>(pMenu
->GetUserValue( nItemId
));
222 if ( pMenuAttributes
&& !pMenuAttributes
->aImageId
.isEmpty() )
224 // Retrieve image id from menu attributes
225 aImage
= GetImageFromURL( rFrame
, aImageId
, false );
230 aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
232 aImage
= AddonsOptions().GetImageFromURL( aItemCommand
, false );
236 pMenu
->SetItemImage( nItemId
, aImage
);
238 else if ( !pMenu
->GetItemImage( nItemId
))
240 Image aImage
= GetImageFromURL( rFrame
, aItemCommand
, false );
242 pMenu
->SetItemImage( nItemId
, aImage
);
246 Reference
< XDispatch
> aXDispatchRef
;
247 m_aMenuItemHandlerVector
.push_back( new MenuItemHandler( nItemId
, NULL
, aXDispatchRef
));
253 // retrieve label information for all menu items without item text
258 void MenuManager::SetHdl()
260 m_pVCLMenu
->SetHighlightHdl( LINK( this, MenuManager
, Highlight
));
261 m_pVCLMenu
->SetActivateHdl( LINK( this, MenuManager
, Activate
));
262 m_pVCLMenu
->SetDeactivateHdl( LINK( this, MenuManager
, Deactivate
));
263 m_pVCLMenu
->SetSelectHdl( LINK( this, MenuManager
, Select
));
265 if ( m_xContext
.is() )
266 m_xURLTransformer
.set( URLTransformer::create( m_xContext
) );
269 MenuManager::~MenuManager()
271 std::vector
< MenuItemHandler
* >::iterator p
;
272 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
274 MenuItemHandler
* pItemHandler
= *p
;
275 pItemHandler
->xMenuItemDispatch
.clear();
276 if ( pItemHandler
->pSubMenuManager
)
277 (static_cast< XInterface
* >((OWeakObject
*)pItemHandler
->pSubMenuManager
))->release();
285 MenuManager::MenuItemHandler
* MenuManager::GetMenuItemHandler( sal_uInt16 nItemId
)
289 std::vector
< MenuItemHandler
* >::iterator p
;
290 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
292 MenuItemHandler
* pItemHandler
= *p
;
293 if ( pItemHandler
->nItemId
== nItemId
)
300 void SAL_CALL
MenuManager::statusChanged( const FeatureStateEvent
& Event
)
301 throw ( RuntimeException
, std::exception
)
303 OUString aFeatureURL
= Event
.FeatureURL
.Complete
;
304 MenuItemHandler
* pStatusChangedMenu
= NULL
;
309 std::vector
< MenuItemHandler
* >::iterator p
;
310 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
312 MenuItemHandler
* pMenuItemHandler
= *p
;
313 if ( pMenuItemHandler
->aMenuItemURL
== aFeatureURL
)
315 pStatusChangedMenu
= pMenuItemHandler
;
321 if ( pStatusChangedMenu
)
323 SolarMutexGuard aSolarGuard
;
325 bool bSetCheckmark
= false;
326 bool bCheckmark
= false;
327 bool bMenuItemEnabled
= m_pVCLMenu
->IsItemEnabled( pStatusChangedMenu
->nItemId
);
329 if ( bool(Event
.IsEnabled
) != bMenuItemEnabled
)
330 m_pVCLMenu
->EnableItem( pStatusChangedMenu
->nItemId
, Event
.IsEnabled
);
332 if ( Event
.State
>>= bCheckmark
)
333 bSetCheckmark
= true;
336 m_pVCLMenu
->CheckItem( pStatusChangedMenu
->nItemId
, bCheckmark
);
342 aTargetURL
.Complete
= pStatusChangedMenu
->aMenuItemURL
;
344 m_xURLTransformer
->parseStrict( aTargetURL
);
346 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
347 Reference
< XDispatch
> xMenuItemDispatch
= xDispatchProvider
->queryDispatch(
348 aTargetURL
, OUString(), 0 );
350 if ( xMenuItemDispatch
.is() )
352 pStatusChangedMenu
->xMenuItemDispatch
= xMenuItemDispatch
;
353 pStatusChangedMenu
->aMenuItemURL
= aTargetURL
.Complete
;
354 xMenuItemDispatch
->addStatusListener( (static_cast< XStatusListener
* >(this)), aTargetURL
);
360 void MenuManager::RemoveListener()
366 void MenuManager::ClearMenuDispatch(const EventObject
& Source
,bool _bRemoveOnly
)
368 // disposing called from parent dispatcher
369 // remove all listener to prepare shutdown
371 std::vector
< MenuItemHandler
* >::iterator p
;
372 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
374 MenuItemHandler
* pItemHandler
= *p
;
375 if ( pItemHandler
->xMenuItemDispatch
.is() )
378 aTargetURL
.Complete
= pItemHandler
->aMenuItemURL
;
379 m_xURLTransformer
->parseStrict( aTargetURL
);
381 pItemHandler
->xMenuItemDispatch
->removeStatusListener(
382 (static_cast< XStatusListener
* >(this)), aTargetURL
);
385 pItemHandler
->xMenuItemDispatch
.clear();
386 if ( pItemHandler
->pSubMenuManager
)
389 pItemHandler
->pSubMenuManager
->RemoveListener();
391 pItemHandler
->pSubMenuManager
->disposing( Source
);
396 void SAL_CALL
MenuManager::disposing( const EventObject
& Source
) throw ( RuntimeException
, std::exception
)
398 if ( Source
.Source
== m_xFrame
)
401 ClearMenuDispatch(Source
,false);
405 // disposing called from menu item dispatcher, remove listener
406 MenuItemHandler
* pMenuItemDisposing
= NULL
;
411 std::vector
< MenuItemHandler
* >::iterator p
;
412 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
414 MenuItemHandler
* pMenuItemHandler
= *p
;
415 if ( pMenuItemHandler
->xMenuItemDispatch
== Source
.Source
)
417 pMenuItemDisposing
= pMenuItemHandler
;
422 if ( pMenuItemDisposing
)
425 aTargetURL
.Complete
= pMenuItemDisposing
->aMenuItemURL
;
427 m_xURLTransformer
->parseStrict( aTargetURL
);
429 pMenuItemDisposing
->xMenuItemDispatch
->removeStatusListener((static_cast< XStatusListener
* >(this)), aTargetURL
);
430 pMenuItemDisposing
->xMenuItemDispatch
.clear();
436 void MenuManager::UpdateSpecialFileMenu( Menu
* pMenu
)
439 Sequence
< Sequence
< PropertyValue
> > aHistoryList
= SvtHistoryOptions().GetList( ePICKLIST
);
440 ::std::vector
< MenuItemHandler
* > aNewPickVector
;
441 Reference
< XStringWidth
> xStringLength( new StringLength
);
443 sal_uInt16 nPickItemId
= START_ITEMID_PICKLIST
;
444 int nPickListMenuItems
= ( aHistoryList
.getLength() > 99 ) ? 99 : aHistoryList
.getLength();
446 aNewPickVector
.reserve(nPickListMenuItems
);
447 for ( int i
= 0; i
< nPickListMenuItems
; i
++ )
449 Sequence
< PropertyValue
> aPickListEntry
= aHistoryList
[i
];
451 Reference
< XDispatch
> aXDispatchRef
;
452 MenuItemHandler
* pNewMenuItemHandler
= new MenuItemHandler(
457 for ( int j
= 0; j
< aPickListEntry
.getLength(); j
++ )
459 Any a
= aPickListEntry
[j
].Value
;
461 if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_URL
)
462 a
>>= pNewMenuItemHandler
->aMenuItemURL
;
463 else if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_FILTER
)
464 a
>>= pNewMenuItemHandler
->aFilter
;
465 else if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_TITLE
)
466 a
>>= pNewMenuItemHandler
->aTitle
;
467 else if ( aPickListEntry
[j
].Name
== HISTORY_PROPERTYNAME_PASSWORD
)
468 a
>>= pNewMenuItemHandler
->aPassword
;
471 aNewPickVector
.push_back( pNewMenuItemHandler
);
474 if ( !aNewPickVector
.empty() )
477 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
479 Reference
< XDispatch
> xMenuItemDispatch
;
481 static const char s_sDefault
[] = "_default";
482 // query for dispatcher
483 std::vector
< MenuItemHandler
* >::iterator p
;
484 for ( p
= aNewPickVector
.begin(); p
!= aNewPickVector
.end(); ++p
)
486 MenuItemHandler
* pMenuItemHandler
= *p
;
488 aTargetURL
.Complete
= pMenuItemHandler
->aMenuItemURL
;
489 m_xURLTransformer
->parseStrict( aTargetURL
);
491 if ( !xMenuItemDispatch
.is() )
493 // attention: this code assume that "_blank" can only be consumed by desktop service
494 xMenuItemDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, s_sDefault
, 0 );
497 if ( xMenuItemDispatch
.is() )
499 pMenuItemHandler
->xMenuItemDispatch
= xMenuItemDispatch
;
500 pMenuItemHandler
->aMenuItemURL
= aTargetURL
.Complete
;
507 int nItemCount
= pMenu
->GetItemCount();
509 if ( nItemCount
> 0 )
511 int nRemoveItemCount
= 0;
513 // remove all old picklist entries from menu
514 sal_uInt16 nPos
= pMenu
->GetItemPos( START_ITEMID_PICKLIST
);
515 for ( sal_uInt16 n
= nPos
; n
< pMenu
->GetItemCount(); )
517 pMenu
->RemoveItem( n
);
521 if ( pMenu
->GetItemType( pMenu
->GetItemCount()-1 ) == MenuItemType::SEPARATOR
)
522 pMenu
->RemoveItem( pMenu
->GetItemCount()-1 );
524 // remove all old picklist entries from menu handler
525 if ( nRemoveItemCount
> 0 )
527 for( sal_uInt32 nIndex
= m_aMenuItemHandlerVector
.size() - nRemoveItemCount
;
528 nIndex
< m_aMenuItemHandlerVector
.size(); )
530 delete m_aMenuItemHandlerVector
.at( nIndex
);
531 m_aMenuItemHandlerVector
.erase( m_aMenuItemHandlerVector
.begin() + nIndex
);
536 // append new picklist menu entries
537 aNewPickVector
.reserve(aNewPickVector
.size());
538 pMenu
->InsertSeparator();
539 const sal_uInt32 nCount
= aNewPickVector
.size();
540 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
542 char menuShortCut
[5] = "~n: ";
544 OUString aMenuShortCut
;
548 aMenuShortCut
= "1~0: ";
551 menuShortCut
[1] = (char)( '1' + i
);
552 aMenuShortCut
= OUString::createFromAscii( menuShortCut
);
557 aMenuShortCut
= OUString::number(( i
+ 1 ));
558 aMenuShortCut
+= ": ";
562 OUString
aURLString( aNewPickVector
.at( i
)->aMenuItemURL
);
563 OUString aTipHelpText
;
565 INetURLObject
aURL( aURLString
);
567 if ( aURL
.GetProtocol() == INetProtocol::File
)
569 // Do handle file URL differently => convert it to a system
570 // path and abbreviate it with a special function:
571 OUString
aFileSystemPath( aURL
.getFSysPath( INetURLObject::FSYS_DETECT
) );
573 OUString
aSystemPath( aFileSystemPath
);
574 OUString aCompactedSystemPath
;
576 aTipHelpText
= aSystemPath
;
577 oslFileError nError
= osl_abbreviateSystemPath( aSystemPath
.pData
, &aCompactedSystemPath
.pData
, 46, NULL
);
579 aMenuTitle
= aCompactedSystemPath
;
581 aMenuTitle
= aSystemPath
;
585 // Use INetURLObject to abbreviate all other URLs
587 aShortURL
= aURL
.getAbbreviated( xStringLength
, 46, INetURLObject::DECODE_UNAMBIGUOUS
);
588 aMenuTitle
+= aShortURL
;
589 aTipHelpText
= aURLString
;
592 OUString
aTitle( aMenuShortCut
+ aMenuTitle
);
594 MenuItemHandler
* pMenuItemHandler
= aNewPickVector
.at( i
);
595 pMenu
->InsertItem( pMenuItemHandler
->nItemId
, aTitle
);
596 pMenu
->SetTipHelpText( pMenuItemHandler
->nItemId
, aTipHelpText
);
597 m_aMenuItemHandlerVector
.push_back( pMenuItemHandler
);
603 void MenuManager::UpdateSpecialWindowMenu( Menu
* pMenu
,const Reference
< XComponentContext
>& xContext
)
605 // update window list
606 ::std::vector
< OUString
> aNewWindowListVector
;
608 Reference
< XDesktop2
> xDesktop
= Desktop::create( xContext
);
610 sal_uInt16 nActiveItemId
= 0;
611 sal_uInt16 nItemId
= START_ITEMID_WINDOWLIST
;
613 Reference
< XFrame
> xCurrentFrame
= xDesktop
->getCurrentFrame();
614 Reference
< XIndexAccess
> xList( xDesktop
->getFrames(), UNO_QUERY
);
615 sal_Int32 nFrameCount
= xList
->getCount();
616 aNewWindowListVector
.reserve(nFrameCount
);
617 for (sal_Int32 i
=0; i
<nFrameCount
; ++i
)
619 Reference
< XFrame
> xFrame
;
620 xList
->getByIndex(i
) >>= xFrame
;
624 if ( xFrame
== xCurrentFrame
)
625 nActiveItemId
= nItemId
;
627 vcl::Window
* pWin
= VCLUnoHelper::GetWindow( xFrame
->getContainerWindow() );
628 if ( pWin
&& pWin
->IsVisible() )
630 aNewWindowListVector
.push_back( pWin
->GetText() );
639 int nItemCount
= pMenu
->GetItemCount();
641 if ( nItemCount
> 0 )
643 // remove all old window list entries from menu
644 sal_uInt16 nPos
= pMenu
->GetItemPos( START_ITEMID_WINDOWLIST
);
645 for ( sal_uInt16 n
= nPos
; n
< pMenu
->GetItemCount(); )
646 pMenu
->RemoveItem( n
);
648 if ( pMenu
->GetItemType( pMenu
->GetItemCount()-1 ) == MenuItemType::SEPARATOR
)
649 pMenu
->RemoveItem( pMenu
->GetItemCount()-1 );
652 if ( !aNewWindowListVector
.empty() )
654 // append new window list entries to menu
655 pMenu
->InsertSeparator();
656 nItemId
= START_ITEMID_WINDOWLIST
;
657 const sal_uInt32 nCount
= aNewWindowListVector
.size();
658 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
660 pMenu
->InsertItem( nItemId
, aNewWindowListVector
.at( i
), MenuItemBits::RADIOCHECK
);
661 if ( nItemId
== nActiveItemId
)
662 pMenu
->CheckItem( nItemId
);
669 void MenuManager::CreatePicklistArguments( Sequence
< PropertyValue
>& aArgsList
, const MenuItemHandler
* pMenuItemHandler
)
671 int NUM_OF_PICKLIST_ARGS
= 3;
674 aArgsList
.realloc( NUM_OF_PICKLIST_ARGS
);
676 aArgsList
[0].Name
= "FileName";
677 a
<<= pMenuItemHandler
->aMenuItemURL
;
678 aArgsList
[0].Value
= a
;
680 aArgsList
[1].Name
= "Referer";
681 a
<<= OUString( "private:user" );
682 aArgsList
[1].Value
= a
;
684 OUString
aFilter( pMenuItemHandler
->aFilter
);
686 sal_Int32 nPos
= aFilter
.indexOf( '|' );
689 OUString aFilterOptions
;
691 if ( nPos
< ( aFilter
.getLength() - 1 ) )
692 aFilterOptions
= aFilter
.copy( nPos
+1 );
694 aArgsList
[2].Name
= "FilterOptions";
695 a
<<= aFilterOptions
;
696 aArgsList
[2].Value
= a
;
698 aFilter
= aFilter
.copy( 0, nPos
-1 );
699 aArgsList
.realloc( ++NUM_OF_PICKLIST_ARGS
);
702 aArgsList
[NUM_OF_PICKLIST_ARGS
-1].Name
= "FilterName";
704 aArgsList
[NUM_OF_PICKLIST_ARGS
-1].Value
= a
;
709 IMPL_LINK_TYPED( MenuManager
, Activate
, Menu
*, pMenu
, bool )
711 if ( pMenu
== m_pVCLMenu
)
713 // set/unset hiding disabled menu entries
714 bool bDontHide
= SvtMenuOptions().IsEntryHidingEnabled();
715 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
716 bool bShowMenuImages
= rSettings
.GetUseImagesInMenus();
718 MenuFlags nFlag
= pMenu
->GetMenuFlags();
720 nFlag
&= ~MenuFlags::HideDisabledEntries
;
722 nFlag
|= MenuFlags::HideDisabledEntries
;
723 pMenu
->SetMenuFlags( nFlag
);
730 OUString
aCommand( m_aMenuItemCommand
);
731 if (m_aMenuItemCommand
.matchIgnoreAsciiCase(UNO_COMMAND
))
733 // Remove protocol part from command so we can use an easier comparison method
734 aCommand
= aCommand
.copy(RTL_CONSTASCII_LENGTH(UNO_COMMAND
));
737 if ( m_aMenuItemCommand
== aSpecialFileMenu
|| m_aMenuItemCommand
== aSlotSpecialFileMenu
|| aCommand
== aSpecialFileCommand
)
738 UpdateSpecialFileMenu( pMenu
);
739 else if ( m_aMenuItemCommand
== aSpecialWindowMenu
|| m_aMenuItemCommand
== aSlotSpecialWindowMenu
|| aCommand
== aSpecialWindowCommand
)
740 UpdateSpecialWindowMenu( pMenu
, m_xContext
);
742 // Check if some modes have changed so we have to update our menu images
743 if ( bShowMenuImages
!= m_bShowMenuImages
)
745 // The mode changed so we have to replace all images
746 m_bShowMenuImages
= bShowMenuImages
;
747 FillMenuImages( m_xFrame
, pMenu
, bShowMenuImages
);
750 if ( m_bInitialized
)
758 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
759 if ( xDispatchProvider
.is() )
761 std::vector
< MenuItemHandler
* >::iterator p
;
762 for ( p
= m_aMenuItemHandlerVector
.begin(); p
!= m_aMenuItemHandlerVector
.end(); ++p
)
764 MenuItemHandler
* pMenuItemHandler
= *p
;
765 if ( pMenuItemHandler
&&
766 pMenuItemHandler
->pSubMenuManager
== 0 &&
767 !pMenuItemHandler
->xMenuItemDispatch
.is() )
769 // There is no dispatch mechanism for the special window list menu items,
770 // because they are handled directly through XFrame->activate!!!
771 if ( pMenuItemHandler
->nItemId
< START_ITEMID_WINDOWLIST
||
772 pMenuItemHandler
->nItemId
> END_ITEMID_WINDOWLIST
)
774 OUString aItemCommand
= pMenu
->GetItemCommand( pMenuItemHandler
->nItemId
);
775 if ( aItemCommand
.isEmpty() )
777 aItemCommand
= "slot:" + OUString::number( pMenuItemHandler
->nItemId
);
778 pMenu
->SetItemCommand( pMenuItemHandler
->nItemId
, aItemCommand
);
781 aTargetURL
.Complete
= aItemCommand
;
783 m_xURLTransformer
->parseStrict( aTargetURL
);
785 Reference
< XDispatch
> xMenuItemDispatch
;
786 if ( m_bIsBookmarkMenu
)
787 xMenuItemDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, pMenuItemHandler
->aTargetFrame
, 0 );
789 xMenuItemDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
791 if ( xMenuItemDispatch
.is() )
793 pMenuItemHandler
->xMenuItemDispatch
= xMenuItemDispatch
;
794 pMenuItemHandler
->aMenuItemURL
= aTargetURL
.Complete
;
795 xMenuItemDispatch
->addStatusListener( (static_cast< XStatusListener
* >(this)), aTargetURL
);
798 pMenu
->EnableItem( pMenuItemHandler
->nItemId
, false );
809 IMPL_LINK_TYPED( MenuManager
, Deactivate
, Menu
*, pMenu
, bool )
811 if ( pMenu
== m_pVCLMenu
)
817 IMPL_LINK( MenuManager
, Select
, Menu
*, pMenu
)
820 Sequence
<PropertyValue
> aArgs
;
821 Reference
< XDispatch
> xDispatch
;
826 sal_uInt16 nCurItemId
= pMenu
->GetCurItemId();
827 if ( pMenu
== m_pVCLMenu
&&
828 pMenu
->GetItemType( nCurItemId
) != MenuItemType::SEPARATOR
)
830 if ( nCurItemId
>= START_ITEMID_WINDOWLIST
&&
831 nCurItemId
<= END_ITEMID_WINDOWLIST
)
833 // window list menu item selected
835 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_xContext
);
837 sal_uInt16 nTaskId
= START_ITEMID_WINDOWLIST
;
838 Reference
< XIndexAccess
> xList( xDesktop
->getFrames(), UNO_QUERY
);
839 sal_Int32 nCount
= xList
->getCount();
840 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
842 Reference
< XFrame
> xFrame
;
843 xList
->getByIndex(i
) >>= xFrame
;
845 if ( xFrame
.is() && nTaskId
== nCurItemId
)
847 vcl::Window
* pWin
= VCLUnoHelper::GetWindow( xFrame
->getContainerWindow() );
849 pWin
->ToTop( TOTOP_RESTOREWHENMIN
);
858 MenuItemHandler
* pMenuItemHandler
= GetMenuItemHandler( nCurItemId
);
859 if ( pMenuItemHandler
&& pMenuItemHandler
->xMenuItemDispatch
.is() )
861 aTargetURL
.Complete
= pMenuItemHandler
->aMenuItemURL
;
862 m_xURLTransformer
->parseStrict( aTargetURL
);
864 if ( nCurItemId
>= START_ITEMID_PICKLIST
&&
865 nCurItemId
< START_ITEMID_WINDOWLIST
)
867 // picklist menu item selected
868 CreatePicklistArguments( aArgs
, pMenuItemHandler
);
870 else if ( m_bIsBookmarkMenu
)
872 // bookmark menu item selected
874 aArgs
[0].Name
= "Referer";
875 aArgs
[0].Value
<<= OUString( "private:user" );
878 xDispatch
= pMenuItemHandler
->xMenuItemDispatch
;
884 if ( xDispatch
.is() )
885 xDispatch
->dispatch( aTargetURL
, aArgs
);
890 IMPL_LINK_NOARG_TYPED(MenuManager
, Highlight
, Menu
*, bool)
895 void MenuManager::AddMenu(PopupMenu
* _pPopupMenu
,const OUString
& _sItemCommand
,sal_uInt16 _nItemId
,bool _bDelete
,bool _bDeleteChildren
)
897 MenuManager
* pSubMenuManager
= new MenuManager( m_xContext
, m_xFrame
, _pPopupMenu
, _bDelete
, _bDeleteChildren
);
899 // store menu item command as we later have to know which menu is active (see Activate handler)
900 pSubMenuManager
->m_aMenuItemCommand
= _sItemCommand
;
902 Reference
< XDispatch
> aXDispatchRef
;
903 MenuItemHandler
* pMenuItemHandler
= new MenuItemHandler(
907 m_aMenuItemHandlerVector
.push_back( pMenuItemHandler
);
910 sal_uInt16
MenuManager::FillItemCommand(OUString
& _rItemCommand
, Menu
* _pMenu
,sal_uInt16 _nIndex
) const
912 sal_uInt16 nItemId
= _pMenu
->GetItemId( _nIndex
);
914 _rItemCommand
= _pMenu
->GetItemCommand( nItemId
);
915 if ( _rItemCommand
.isEmpty() )
917 _rItemCommand
= "slot:" + OUString::number( nItemId
);
918 _pMenu
->SetItemCommand( nItemId
, _rItemCommand
);
922 void MenuManager::FillMenuImages(Reference
< XFrame
>& _xFrame
, Menu
* _pMenu
,bool bShowMenuImages
)
924 AddonsOptions aAddonOptions
;
926 for ( sal_uInt16 nPos
= 0; nPos
< _pMenu
->GetItemCount(); nPos
++ )
928 sal_uInt16 nId
= _pMenu
->GetItemId( nPos
);
929 if ( _pMenu
->GetItemType( nPos
) != MenuItemType::SEPARATOR
)
931 bool bTmpShowMenuImages( bShowMenuImages
);
932 // overwrite the show icons on menu option?
933 if (!bTmpShowMenuImages
)
935 MenuItemBits nBits
= _pMenu
->GetItemBits( nId
);
936 bTmpShowMenuImages
= ( ( nBits
& MenuItemBits::ICON
) == MenuItemBits::ICON
);
939 if ( bTmpShowMenuImages
)
941 bool bImageSet
= false;
944 ::framework::MenuAttributes
* pMenuAttributes
=
945 reinterpret_cast< ::framework::MenuAttributes
*>(_pMenu
->GetUserValue( nId
));
947 if ( pMenuAttributes
)
948 aImageId
= pMenuAttributes
->aImageId
; // Retrieve image id from menu attributes
950 if ( !aImageId
.isEmpty() )
952 Image aImage
= GetImageFromURL( _xFrame
, aImageId
, false );
956 _pMenu
->SetItemImage( nId
, aImage
);
962 OUString aMenuItemCommand
= _pMenu
->GetItemCommand( nId
);
963 Image aImage
= GetImageFromURL( _xFrame
, aMenuItemCommand
, false );
965 aImage
= aAddonOptions
.GetImageFromURL( aMenuItemCommand
, false );
967 _pMenu
->SetItemImage( nId
, aImage
);
971 _pMenu
->SetItemImage( nId
, Image() );
977 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */