30#include <com/sun/star/embed/VerbAttributes.hpp>
31#include <com/sun/star/embed/VerbDescriptor.hpp>
32#include <com/sun/star/frame/Desktop.hpp>
33#include <com/sun/star/frame/ModuleManager.hpp>
34#include <com/sun/star/frame/XStorable.hpp>
35#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
36#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
37#include <com/sun/star/util/URL.hpp>
41class ResourceMenuController :
public cppu::ImplInheritanceHelper< svt::PopupMenuControllerBase, css::ui::XUIConfigurationListener >
44 ResourceMenuController(
const css::uno::Reference< css::uno::XComponentContext >& rxContext,
45 const css::uno::Sequence< css::uno::Any >& rxArgs,
bool bToolbarContainer );
48 virtual void SAL_CALL updatePopupMenu()
override;
51 virtual void SAL_CALL statusChanged(
const css::frame::FeatureStateEvent& rEvent )
override;
54 virtual void SAL_CALL disposing(
const css::lang::EventObject& rEvent )
override;
57 virtual void SAL_CALL
elementInserted(
const css::ui::ConfigurationEvent& rEvent )
override;
58 virtual void SAL_CALL
elementRemoved(
const css::ui::ConfigurationEvent& rEvent )
override;
59 virtual void SAL_CALL
elementReplaced(
const css::ui::ConfigurationEvent& rEvent )
override;
62 virtual void SAL_CALL
itemActivated(
const css::awt::MenuEvent& rEvent )
override;
63 virtual void SAL_CALL
itemSelected(
const css::awt::MenuEvent& rEvent )
override;
73 bool m_bToolbarContainer;
74 sal_uInt16 m_nNewMenuId;
76 css::uno::Reference< css::frame::XDispatchProvider > m_xDispatchProvider;
77 css::uno::Reference< css::container::XIndexAccess > m_xMenuContainer;
78 css::uno::Reference< css::ui::XUIConfigurationManager > m_xConfigManager, m_xModuleConfigManager;
79 void addVerbs(
const css::uno::Sequence< css::embed::VerbDescriptor >& rVerbs );
80 virtual void disposing(std::unique_lock<std::mutex>& rGuard)
override;
83 css::uno::Reference< css::uno::XComponentContext >
m_xContext;
86ResourceMenuController::ResourceMenuController(
const css::uno::Reference< css::uno::XComponentContext >& rxContext,
87 const css::uno::Sequence< css::uno::Any >& rxArgs,
bool bToolbarContainer ) :
88 ImplInheritanceHelper( rxContext ),
89 m_bContextMenu( false ),
90 m_bInToolbar( false ),
91 m_bToolbarContainer( bToolbarContainer ),
95 for (
const auto& arg: rxArgs )
97 css::beans::PropertyValue aPropValue;
98 if ( arg >>= aPropValue )
100 if ( aPropValue.Name ==
"Value" )
103 aPropValue.Value >>= aMenuName;
104 if ( aMenuName.isEmpty() )
107 if ( m_bToolbarContainer )
108 m_aMenuURL =
"private:resource/toolbar/" + aMenuName;
110 m_aMenuURL =
"private:resource/popupmenu/" + aMenuName;
112 else if ( aPropValue.Name ==
"ResourceURL" )
113 aPropValue.Value >>= m_aMenuURL;
114 else if ( aPropValue.Name ==
"Frame" )
116 else if ( aPropValue.Name ==
"ModuleIdentifier" )
117 aPropValue.Value >>= m_aModuleName;
118 else if ( aPropValue.Name ==
"DispatchProvider" )
119 aPropValue.Value >>= m_xDispatchProvider;
120 else if ( aPropValue.Name ==
"IsContextMenu" )
121 aPropValue.Value >>= m_bContextMenu;
122 else if ( aPropValue.Name ==
"InToolbar" )
123 aPropValue.Value >>= m_bInToolbar;
128 m_bInitialized =
true;
131void ResourceMenuController::updatePopupMenu()
133 if ( ( m_xMenuContainer.is() && !m_bContextMenu ) || m_aMenuURL.isEmpty() )
136 if ( m_aModuleName.isEmpty() )
140 css::uno::Reference< css::frame::XModuleManager > xModuleManager( css::frame::ModuleManager::create(
m_xContext ) );
141 m_aModuleName = xModuleManager->identify( m_xFrame );
143 catch(
const css::uno::Exception& )
147 if ( !m_xConfigManager.is() )
153 css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xSupplier( xModel, css::uno::UNO_QUERY_THROW );
154 m_xConfigManager.set( xSupplier->getUIConfigurationManager() );
155 css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
156 xConfig->addConfigurationListener(
this );
158 catch(
const css::uno::RuntimeException& )
162 if ( !m_xModuleConfigManager.is() )
166 css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
167 css::ui::theModuleUIConfigurationManagerSupplier::get(
m_xContext ) );
168 m_xModuleConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleName ) );
169 css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xModuleConfigManager, css::uno::UNO_QUERY_THROW );
170 xConfig->addConfigurationListener(
this );
172 catch (
const css::container::NoSuchElementException& )
174 SAL_WARN(
"fwk.uielement",
"Invalid module identifier: " << m_aModuleName );
176 catch(
const css::uno::RuntimeException& )
180 if ( !m_xMenuContainer.is() && m_xConfigManager.is() )
184 m_xMenuContainer.set( m_xConfigManager->getSettings( m_aMenuURL,
false ) );
186 catch (
const css::container::NoSuchElementException& )
190 catch (
const css::lang::IllegalArgumentException& )
192 SAL_WARN(
"fwk.uielement",
"The given URL is not valid: " << m_aMenuURL );
197 if ( !m_xMenuContainer.is() && m_xModuleConfigManager.is() )
201 m_xMenuContainer.set( m_xModuleConfigManager->getSettings( m_aMenuURL,
false ) );
203 catch (
const css::container::NoSuchElementException& )
205 SAL_WARN(
"fwk.uielement",
"Can not find settings for " << m_aMenuURL );
208 catch (
const css::lang::IllegalArgumentException& )
210 SAL_WARN(
"fwk.uielement",
"The given URL is not valid: " << m_aMenuURL );
215 if ( !m_xMenuContainer.is() )
219 if ( m_xMenuBarManager.is() )
221 m_xMenuBarManager->dispose();
222 m_xMenuBarManager.clear();
224 resetPopupMenu( m_xPopupMenu );
231 if ( !m_bContextMenu )
234 css::util::URL aObjectMenuURL;
235 aObjectMenuURL.Complete =
".uno:ObjectMenue";
236 m_xURLTransformer->parseStrict( aObjectMenuURL );
237 css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( m_xFrame, css::uno::UNO_QUERY );
238 css::uno::Reference< css::frame::XDispatch >
xDispatch( xDispatchProvider->queryDispatch( aObjectMenuURL, OUString(), 0 ) );
241 xDispatch->addStatusListener(
this, aObjectMenuURL );
242 xDispatch->removeStatusListener(
this, aObjectMenuURL );
246void ResourceMenuController::statusChanged(
const css::frame::FeatureStateEvent& rEvent )
248 css::uno::Sequence< css::embed::VerbDescriptor > aVerbs;
249 if ( rEvent.IsEnabled && ( rEvent.State >>= aVerbs ) )
253void ResourceMenuController::addVerbs(
const css::uno::Sequence< css::embed::VerbDescriptor >& rVerbs )
257 css::uno::Reference< css::frame::XStorable > xStorable;
259 xStorable.set(
xController->getModel(), css::uno::UNO_QUERY );
261 bool bReadOnly = xStorable.is() && xStorable->isReadonly();
262 Menu* pVCLMenu = m_xPopupMenu->GetMenu();
264 for (
const auto& rVerb : rVerbs )
266 if ( !( rVerb.VerbAttributes & css::embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU ) ||
267 ( bReadOnly && !( rVerb.VerbAttributes & css::embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES ) ) )
270 pVCLMenu->
InsertItem( m_nNewMenuId, rVerb.VerbName );
271 pVCLMenu->
SetItemCommand( m_nNewMenuId,
".uno:ObjectMenue?VerbID:short=" + OUString::number( rVerb.VerbID ) );
276void ResourceMenuController::itemActivated(
const css::awt::MenuEvent& )
279 if ( !m_xMenuBarManager.is() )
282 m_xContext, m_xFrame, m_xURLTransformer, m_xDispatchProvider, m_aModuleName, m_xPopupMenu->GetMenu(),
false, !m_bContextMenu && !m_bInToolbar ) );
283 m_xFrame->addFrameActionListener( m_xMenuBarManager );
287void ResourceMenuController::itemSelected(
const css::awt::MenuEvent& )
292void ResourceMenuController::elementInserted(
const css::ui::ConfigurationEvent& rEvent )
294 if ( rEvent.ResourceURL == m_aMenuURL )
295 m_xMenuContainer.clear();
298void ResourceMenuController::elementRemoved(
const css::ui::ConfigurationEvent& rEvent )
303void ResourceMenuController::elementReplaced(
const css::ui::ConfigurationEvent& rEvent )
308void ResourceMenuController::disposing(
const css::lang::EventObject& rEvent )
310 if ( rEvent.Source == m_xConfigManager )
311 m_xConfigManager.clear();
312 else if ( rEvent.Source == m_xModuleConfigManager )
313 m_xModuleConfigManager.clear();
316 if ( m_xMenuBarManager.is() )
319 m_xFrame->removeFrameActionListener( m_xMenuBarManager );
321 m_xMenuBarManager->dispose();
322 m_xMenuBarManager.clear();
324 svt::PopupMenuControllerBase::disposing( rEvent );
328void ResourceMenuController::disposing(std::unique_lock<std::mutex>& rGuard)
330 css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY );
332 xConfig->removeConfigurationListener(
this );
334 css::uno::Reference< css::ui::XUIConfiguration > xModuleConfig( m_xModuleConfigManager, css::uno::UNO_QUERY );
335 if ( xModuleConfig.is() )
336 xModuleConfig->removeConfigurationListener(
this );
338 m_xConfigManager.clear();
339 m_xModuleConfigManager.clear();
340 m_xMenuContainer.clear();
341 m_xDispatchProvider.clear();
342 if ( m_xMenuBarManager.is() )
345 m_xFrame->removeFrameActionListener( m_xMenuBarManager );
347 m_xMenuBarManager->dispose();
348 m_xMenuBarManager.clear();
351 svt::PopupMenuControllerBase::disposing(rGuard);
354OUString ResourceMenuController::getImplementationName()
356 if ( m_bToolbarContainer )
357 return "com.sun.star.comp.framework.ToolbarAsMenuController";
359 return "com.sun.star.comp.framework.ResourceMenuController";
362css::uno::Sequence< OUString > ResourceMenuController::getSupportedServiceNames()
364 return {
"com.sun.star.frame.PopupMenuController" };
367class SaveAsMenuController :
public ResourceMenuController
370 SaveAsMenuController(
const css::uno::Reference< css::uno::XComponentContext >& rContext,
371 const css::uno::Sequence< css::uno::Any >& rArgs );
377 virtual void impl_setPopupMenu()
override;
380SaveAsMenuController::SaveAsMenuController(
const css::uno::Reference< css::uno::XComponentContext >& rContext,
381 const css::uno::Sequence< css::uno::Any >& rArgs )
382 : ResourceMenuController( rContext, rArgs, false )
386void InsertItem(
const css::uno::Reference<css::awt::XPopupMenu>& rPopupMenu,
387 const OUString& rCommand)
389 sal_uInt16 nItemId = rPopupMenu->getItemCount() + 1;
390 rPopupMenu->insertItem(nItemId, OUString(), 0, -1);
391 rPopupMenu->setCommand(nItemId, rCommand);
394void SaveAsMenuController::impl_setPopupMenu()
398 InsertItem(m_xPopupMenu,
".uno:SaveAs");
399 InsertItem(m_xPopupMenu,
".uno:ExportTo");
400 InsertItem(m_xPopupMenu,
".uno:SaveACopy");
401 InsertItem(m_xPopupMenu,
".uno:SaveAsTemplate");
402 m_xPopupMenu->insertSeparator(-1);
403 InsertItem(m_xPopupMenu,
".uno:SaveAsRemote");
406OUString SaveAsMenuController::getImplementationName()
408 return "com.sun.star.comp.framework.SaveAsMenuController";
411class WindowListMenuController :
public ResourceMenuController
414 WindowListMenuController(
const css::uno::Reference< css::uno::XComponentContext >& rxContext,
415 const css::uno::Sequence< css::uno::Any >& rxArgs )
416 : ResourceMenuController(rxContext, rxArgs, false) {}
419 void SAL_CALL
itemActivated(
const css::awt::MenuEvent& rEvent )
override;
420 void SAL_CALL
itemSelected(
const css::awt::MenuEvent& rEvent )
override;
426 void impl_setPopupMenu()
override;
429constexpr sal_uInt16 START_ITEMID_WINDOWLIST = 4600;
430constexpr sal_uInt16 END_ITEMID_WINDOWLIST = 4699;
432void WindowListMenuController::itemActivated(
const css::awt::MenuEvent& rEvent )
434 ResourceMenuController::itemActivated( rEvent );
437 ::std::vector< OUString > aNewWindowListVector;
439 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(
m_xContext );
441 sal_uInt16 nActiveItemId = 0;
442 sal_uInt16 nItemId = START_ITEMID_WINDOWLIST;
444 css::uno::Reference< css::frame::XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
445 css::uno::Reference< css::container::XIndexAccess > xList = xDesktop->getFrames();
446 sal_Int32 nFrameCount = xList->getCount();
447 aNewWindowListVector.reserve(nFrameCount);
448 for (sal_Int32 i=0;
i<nFrameCount; ++
i )
450 css::uno::Reference< css::frame::XFrame >
xFrame;
451 xList->getByIndex(i) >>=
xFrame;
455 if ( xFrame == xCurrentFrame )
456 nActiveItemId = nItemId;
459 OUString sWindowTitle;
460 if ( pWin && pWin->IsVisible() )
461 sWindowTitle = pWin->GetText();
465 if ( sWindowTitle.isEmpty() )
468 aNewWindowListVector.push_back( sWindowTitle );
476 Menu* pVCLMenu = m_xPopupMenu->GetMenu();
479 if ( nItemCount > 0 )
482 sal_uInt16
nPos = pVCLMenu->
GetItemPos( START_ITEMID_WINDOWLIST );
490 if ( !aNewWindowListVector.empty() )
494 nItemId = START_ITEMID_WINDOWLIST;
495 const sal_uInt32
nCount = aNewWindowListVector.size();
496 for ( sal_uInt32 i = 0;
i <
nCount;
i++ )
498 pVCLMenu->
InsertItem( nItemId, aNewWindowListVector.at( i ), MenuItemBits::RADIOCHECK );
499 if ( nItemId == nActiveItemId )
507void WindowListMenuController::itemSelected(
const css::awt::MenuEvent& rEvent )
509 if ( rEvent.MenuId < START_ITEMID_WINDOWLIST || rEvent.MenuId > END_ITEMID_WINDOWLIST )
513 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(
m_xContext );
515 sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
516 css::uno::Reference< css::container::XIndexAccess > xList = xDesktop->getFrames();
517 sal_Int32
nCount = xList->getCount();
518 for ( sal_Int32 i=0;
i<
nCount; ++
i )
520 css::uno::Reference< css::frame::XFrame >
xFrame;
521 xList->getByIndex(i) >>=
xFrame;
522 if (
xFrame.is() && nTaskId == rEvent.MenuId )
526 pWin->ToTop( ToTopFlags::RestoreWhenMin );
534void WindowListMenuController::impl_setPopupMenu()
538 if (m_xPopupMenu.is() && !m_xPopupMenu->getItemCount())
539 m_xPopupMenu->insertSeparator(0);
542OUString WindowListMenuController::getImplementationName()
544 return "com.sun.star.comp.framework.WindowListMenuController";
549extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
551 css::uno::XComponentContext* context,
552 css::uno::Sequence< css::uno::Any >
const & args )
554 return cppu::acquire(
new ResourceMenuController( context,
args,
false ) );
557extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
559 css::uno::XComponentContext* context,
560 css::uno::Sequence< css::uno::Any >
const & args )
562 return cppu::acquire(
new ResourceMenuController( context,
args,
true ) );
565extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
567 css::uno::XComponentContext* context,
568 css::uno::Sequence< css::uno::Any >
const & args )
570 return cppu::acquire(
new WindowListMenuController( context,
args ) );
573extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
575 css::uno::XComponentContext* context,
576 css::uno::Sequence< css::uno::Any >
const & args )
578 return cppu::acquire(
new SaveAsMenuController( context,
args ) );
css::uno::Reference< css::lang::XComponent > m_xFrame
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
Reference< XDispatch > xDispatch
css::uno::Reference< css::uno::XComponentContext > m_xContext
void SAL_CALL itemActivated(const css::awt::MenuEvent &rEvent) override
void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
void SAL_CALL itemSelected(const css::awt::MenuEvent &rEvent) override
#define SAL_WARN(area, stream)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel