24#include <unordered_map>
32#include <com/sun/star/beans/PropertyValue.hpp>
33#include <com/sun/star/awt/MenuItemStyle.hpp>
34#include <com/sun/star/frame/ModuleManager.hpp>
35#include <com/sun/star/frame/XDispatchProvider.hpp>
36#include <com/sun/star/util/XURLTransformer.hpp>
37#include <com/sun/star/beans/XPropertySet.hpp>
38#include <com/sun/star/frame/XLayoutManager.hpp>
39#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
40#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
41#include <com/sun/star/ui/UIElementType.hpp>
42#include <com/sun/star/ui/theWindowStateConfiguration.hpp>
45#include <officecfg/Office/Common.hxx>
49#include <rtl/ustrbuf.hxx>
94 sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName );
101 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
102 Reference< XLayoutManager > xLayoutManager;
106 xPropSet->getPropertyValue(
"LayoutManager") >>= xLayoutManager;
108 catch (
const UnknownPropertyException& )
112 return xLayoutManager;
129 return "com.sun.star.comp.framework.ToolBarsMenuController";
146 svt::PopupMenuControllerBase( xContext ),
148 m_bResetActive( false ),
158 Reference< css::awt::XPopupMenu >
const & rPopupMenu,
const OUString& rCommandURL,
const OUString& rLabel )
160 sal_uInt16 nItemId = m_xPopupMenu->getItemCount()+1;
163 if ( rLabel.isEmpty() )
171 rPopupMenu->insertItem( nItemId,
aLabel, 0, nItemId );
172 rPopupMenu->setCommand( nItemId, rCommandURL );
178 m_xPopupMenu->enableItem( nItemId,
false );
183 css::uno::Reference<css::graphic::XGraphic> xGraphic;
190 rPopupMenu->setItemImage(nItemId, xGraphic,
false);
198 Reference< XURLTransformer > xURLTransformer;
199 Reference< XFrame >
xFrame;
203 xURLTransformer = m_xURLTransformer;
209 Reference< XDispatchProvider > xDispatchProvider(
xFrame, UNO_QUERY );
210 if ( xDispatchProvider.is() )
211 return xDispatchProvider->queryDispatch(
aTargetURL, OUString(), 0 );
213 return Reference< XDispatch >();
216static void fillHashMap(
const Sequence< Sequence< css::beans::PropertyValue > >& rSeqToolBars,
219 for ( Sequence< css::beans::PropertyValue >
const &
props : rSeqToolBars )
221 OUString aResourceURL;
223 for ( css::beans::PropertyValue
const & prop :
props )
225 if ( prop.Name ==
"ResourceURL" )
226 prop.Value >>= aResourceURL;
227 else if ( prop.Name ==
"UIName" )
231 if ( !aResourceURL.isEmpty() &&
232 rHashMap.find( aResourceURL ) == rHashMap.end() )
233 rHashMap.emplace( aResourceURL,
aUIName );
240 std::vector< ToolBarInfo > aToolBarArray;
241 const Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements();
242 for ( Reference< XUIElement >
const & xUIElement : aUIElements )
244 Reference< XPropertySet > xPropSet( xUIElement, UNO_QUERY );
245 if ( xPropSet.is() && xUIElement.is() )
250 sal_Int16
nType( -1 );
251 xPropSet->getPropertyValue(
"Type") >>=
nType;
252 xPropSet->getPropertyValue(
"ResourceURL") >>= aResName;
254 if ((
nType == css::ui::UIElementType::TOOLBAR ) &&
255 !aResName.isEmpty() )
257 ToolBarInfo aToolBarInfo;
259 aToolBarInfo.aToolBarResName = aResName;
262 Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
265 aToolBarInfo.aToolBarUIName = pWindow->GetText();
267 aToolBarArray.push_back( aToolBarInfo );
276 Sequence< Sequence< css::beans::PropertyValue > >
aSeq( aToolBarArray.size() );
277 auto pSeq =
aSeq.getArray();
278 const sal_uInt32
nCount = aToolBarArray.size();
279 for ( sal_uInt32
i = 0;
i <
nCount;
i++ )
281 Sequence< css::beans::PropertyValue > aTbSeq{
294 if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
298 resetPopupMenu( rPopupMenu );
306 if ( !xLayoutManager.is() )
313 Sequence< Sequence< css::beans::PropertyValue > > aSeqDocToolBars =
314 m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
320 Sequence< Sequence< css::beans::PropertyValue > > aSeqToolBars =
325 std::vector< ToolBarEntry > aSortedTbs;
331 for (
auto const& toolbar : aToolbarHashMap)
333 OUString
aUIName = toolbar.second;
334 bool bHideFromMenu(
false );
335 bool bContextSensitive(
false );
343 Sequence< PropertyValue > aWindowState;
346 if (
a >>= aWindowState )
348 for ( PropertyValue
const & prop : std::as_const(aWindowState) )
353 prop.Value >>= bHideFromMenu;
355 prop.Value >>= bContextSensitive;
366 if ( bContextSensitive && !
bVisible )
371 if ( !
aUIName.isEmpty() && !bHideFromMenu )
373 ToolBarEntry aTbEntry;
375 aTbEntry.aCommand = toolbar.first;
376 aTbEntry.bVisible = xLayoutManager->isElementVisible( toolbar.first );
378 aSortedTbs.push_back( aTbEntry );
386 const sal_uInt32
nCount = aSortedTbs.size();
387 for ( sal_uInt32
i = 0;
i <
nCount;
i++ )
389 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
390 m_xPopupMenu->insertItem(
nIndex, aSortedTbs[
i].
aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount );
392 m_xPopupMenu->checkItem(
nIndex,
true );
394 OUStringBuffer aStrBuf( aStaticCmdPart );
396 sal_Int32
n = aSortedTbs[
i].aCommand.lastIndexOf(
'/' );
397 if ((
n > 0 ) && ((
n+1 ) < aSortedTbs[
i].
aCommand.getLength() ))
398 aStrBuf.append( aSortedTbs[
i].
aCommand.subView(
n+1) );
400 OUString aCmd( aStrBuf.makeStringAndClear() );
404 rPopupMenu->setCommand(
nIndex, aCmd );
410 bool bAddCommand(
true );
419 if ( m_xPopupMenu->getItemCount() > 0 )
421 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
422 m_xPopupMenu->insertSeparator( nItemCount+1 );
425 addCommand( m_xPopupMenu,
".uno:ConfigureDialog",
"" );
432 if ( m_xPopupMenu->getItemCount() > 0 )
434 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
435 m_xPopupMenu->insertSeparator( nItemCount+1 );
439 OUString aLabelStr(
FwkResId(STR_RESTORE_TOOLBARS));
441 aLabelStr =
FwkResId(STR_LOCK_TOOLBARS);
448 Reference< css::awt::XMenuListener > xHolder(
this);
457 if ( m_xPopupMenu.is() )
458 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(
this) );
459 m_xPopupMenu.clear();
465 OUString aFeatureURL( Event.FeatureURL.Complete );
469 Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu );
472 if ( !xPopupMenu.is() )
477 bool bSetCheckmark =
false;
478 bool bCheckmark =
false;
479 for (sal_Int16
i = 0,
nCount = xPopupMenu->getItemCount();
i <
nCount; ++
i)
481 sal_Int16
nId = xPopupMenu->getItemId(
i);
485 OUString aCmd = xPopupMenu->getCommand(
nId);
486 if ( aCmd == aFeatureURL )
489 xPopupMenu->enableItem(
nId, Event.IsEnabled);
492 if ( Event.State >>= bCheckmark )
493 bSetCheckmark =
true;
496 xPopupMenu->checkItem(
nId, bCheckmark);
501 if ( Event.State >>= aItemText )
502 xPopupMenu->setItemText(
nId, aItemText);
511 Reference< css::awt::XPopupMenu > xPopupMenu;
512 Reference< XComponentContext > xContext;
513 Reference< XURLTransformer > xURLTransformer;
514 Reference< XFrame >
xFrame;
515 Reference< XNameAccess > xPersistentWindowState;
519 xPopupMenu = m_xPopupMenu;
521 xURLTransformer = m_xURLTransformer;
526 if ( !xPopupMenu.is() )
531 OUString aCmd(xPopupMenu->getCommand(rEvent.MenuId));
535 Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY );
536 if ( xPersistentWindowState.is() && xNameReplace.is() )
540 Sequence< OUString > aElementNames = xPersistentWindowState->getElementNames();
541 sal_Int32
nCount = aElementNames.getLength();
542 bool bRefreshToolbars(
false );
548 OUString aElementName = aElementNames[
i];
549 Sequence< PropertyValue > aWindowState;
551 if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState )
554 bool bContextSensitive(
false );
555 sal_Int32 nVisibleIndex( -1 );
556 for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ )
564 aWindowState[j].Value >>= bContextSensitive;
567 if ( !
bVisible && bContextSensitive && nVisibleIndex >= 0 )
570 aWindowState.getArray()[nVisibleIndex].Value <<=
true;
571 xNameReplace->replaceByName( aElementName,
Any( aWindowState ));
572 bRefreshToolbars =
true;
576 catch (
const NoSuchElementException& )
581 if ( bRefreshToolbars )
584 if ( xLayoutManager.is() )
586 Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY );
591 xPropSet->setPropertyValue(
"RefreshContextToolbarVisibility",
Any(
true ));
616 Sequence<PropertyValue> aArgs;
620 Reference< XDispatchProvider > xDispatchProvider(
m_xFrame, UNO_QUERY );
621 if ( xDispatchProvider.is() )
623 Reference< XDispatch >
xDispatch = xDispatchProvider->queryDispatch(
629 pExecuteInfo->
aArgs = aArgs;
636 if ( xLayoutManager.is() )
639 sal_Int32
nIndex = aCmd.indexOf(
'=' );
640 if ((
nIndex > 0 ) && ((
nIndex+1 ) < aCmd.getLength() ))
644 const bool bShow(!xPopupMenu->isItemChecked(rEvent.MenuId));
664 std::vector< OUString > aCmdVector;
665 Reference< XDispatchProvider > xDispatchProvider(
m_xFrame, UNO_QUERY );
666 Reference< XURLTransformer > xURLTransformer( m_xURLTransformer );
674 const sal_uInt32
nCount = aCmdVector.size();
675 for ( sal_uInt32
i = 0;
i <
nCount;
i++ )
684 Reference< XDispatch >
xDispatch = xDispatchProvider->queryDispatch(
aTargetURL, OUString(), 0 );
694 FeatureStateEvent aFeatureStateEvent;
695 aFeatureStateEvent.FeatureURL.Complete = aCmdVector[
i];
707 throwIfDisposed(aLock);
709 if (
m_xFrame.is() && !m_xPopupMenu.is() )
714 m_xPopupMenu =
dynamic_cast<VCLXPopupMenu*
>(xPopupMenu.get());
715 assert(
bool(xPopupMenu) ==
bool(m_xPopupMenu) &&
"we only support VCLXPopupMenu");
716 m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >(
this) );
724 bool bInitialized( m_bInitialized );
728 svt::PopupMenuControllerBase::initializeImpl(rGuard,
aArguments);
730 if ( !m_bInitialized )
733 Reference< XModuleManager2 > xModuleManager = ModuleManager::create(
m_xContext );
734 Reference< XNameAccess > xPersistentWindowStateSupplier = css::ui::theWindowStateConfiguration::get(
m_xContext );
739 OUString aModuleIdentifier = xModuleManager->identify(
m_xFrame );
742 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier =
743 theModuleUIConfigurationManagerSupplier::get(
m_xContext );
744 m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
747 Reference< XModel >
xModel;
752 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier(
xModel, UNO_QUERY );
753 if ( xUIConfigurationManagerSupplier.is() )
754 m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
764 ExecuteInfo* pExecuteInfo =
static_cast<ExecuteInfo*
>(
p);
770 if ( pExecuteInfo->xDispatch.is() )
772 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
784extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
786 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const& )
PropertiesInfo aProperties
constexpr OUStringLiteral sServiceName
css::uno::Reference< css::lang::XComponent > m_xFrame
css::uno::Reference< css::frame::XDispatch > m_xDispatch
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
const CollatorWrapper * getCaseCollator() const
bool GetUseImagesInMenus() const
bool LookupDisabled(const OUString &aCommandURL) const
bool HasEntriesDisabled() const
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
Reference< XDispatch > xDispatch
OUString FwkResId(TranslateId aId)
css::uno::Reference< css::uno::XComponentContext > m_xContext
Sequence< PropertyValue > aArguments
#define LINK(Instance, Class, Member)
Sequence< sal_Int8 > aSeq
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral g_aPropResourceURL(u"ResourceURL")
constexpr OUStringLiteral g_aPropUIName(u"UIName")
static void fillHashMap(const Sequence< Sequence< css::beans::PropertyValue > > &rSeqToolBars, ToolbarHashMap &rHashMap)
IMPL_STATIC_LINK(ComplexToolbarController, ExecuteHdl_Impl, void *, p, void)
constexpr OUStringLiteral SERVICENAME_POPUPMENUCONTROLLER
void RefreshToolbars(css::uno::Reference< css::frame::XFrame > const &rFrame)
static bool CompareToolBarEntry(const ToolBarEntry &aOne, const ToolBarEntry &aTwo)
std::unordered_map< OUString, OUString > ToolbarHashMap
static css::uno::Reference< css::frame::XLayoutManager > getLayoutManagerFromFrame(css::uno::Reference< css::frame::XFrame > const &rFrame)
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
Reference< graphic::XGraphic > GetXGraphicForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetMenuLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel
constexpr OUStringLiteral WINDOWSTATE_PROPERTY_VISIBLE
constexpr OUStringLiteral WINDOWSTATE_PROPERTY_HIDEFROMENU
constexpr OUStringLiteral WINDOWSTATE_PROPERTY_UINAME
constexpr OUStringLiteral WINDOWSTATE_PROPERTY_CONTEXT