tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / framework / source / uielement / popuptoolbarcontroller.cxx
blob2b3b70da963bf24539b5b8c5738533d37e8c7267
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <bitmaps.hlst>
22 #include <cppuhelper/implbase.hxx>
23 #include <cppuhelper/supportsservice.hxx>
24 #include <comphelper/propertyvalue.hxx>
25 #include <helper/persistentwindowstate.hxx>
26 #include <menuconfiguration.hxx>
27 #include <svtools/imagemgr.hxx>
28 #include <svtools/toolboxcontroller.hxx>
29 #include <toolkit/awt/vclxmenu.hxx>
30 #include <toolkit/helper/vclunohelper.hxx>
31 #include <comphelper/diagnose_ex.hxx>
32 #include <tools/urlobj.hxx>
33 #include <utility>
34 #include <vcl/commandinfoprovider.hxx>
35 #include <vcl/menu.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/toolbox.hxx>
38 #include <vcl/unohelp.hxx>
40 #include <com/sun/star/awt/PopupMenuDirection.hpp>
41 #include <com/sun/star/awt/XPopupMenu.hpp>
42 #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
43 #include <com/sun/star/frame/XPopupMenuController.hpp>
44 #include <com/sun/star/frame/XStorable.hpp>
45 #include <com/sun/star/frame/XSubToolbarController.hpp>
46 #include <com/sun/star/frame/XUIControllerFactory.hpp>
47 #include <com/sun/star/frame/XController.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/ucb/CommandFailedException.hpp>
50 #include <com/sun/star/ucb/ContentCreationException.hpp>
51 #include <com/sun/star/util/XModifiable.hpp>
53 using namespace framework;
55 namespace
58 typedef cppu::ImplInheritanceHelper< svt::ToolboxController,
59 css::lang::XServiceInfo >
60 ToolBarBase;
62 class PopupMenuToolbarController : public ToolBarBase
64 public:
65 // XComponent
66 virtual void SAL_CALL dispose() override;
67 // XInitialization
68 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
69 // XToolbarController
70 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createPopupWindow() override;
71 // XStatusListener
72 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
74 protected:
75 PopupMenuToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
76 OUString aPopupCommand = OUString() );
77 virtual void functionExecuted( const OUString &rCommand );
78 virtual ToolBoxItemBits getDropDownStyle() const;
79 void createPopupMenuController();
81 bool m_bHasController;
82 bool m_bResourceURL;
83 OUString m_aPopupCommand;
84 rtl::Reference< VCLXPopupMenu > m_xPopupMenu;
86 private:
87 css::uno::Reference< css::frame::XUIControllerFactory > m_xPopupMenuFactory;
88 css::uno::Reference< css::frame::XPopupMenuController > m_xPopupMenuController;
91 PopupMenuToolbarController::PopupMenuToolbarController(
92 const css::uno::Reference< css::uno::XComponentContext >& xContext,
93 OUString aPopupCommand )
94 : ToolBarBase( xContext, css::uno::Reference< css::frame::XFrame >(), /*aCommandURL*/OUString() )
95 , m_bHasController( false )
96 , m_bResourceURL( false )
97 , m_aPopupCommand(std::move( aPopupCommand ))
101 void SAL_CALL PopupMenuToolbarController::dispose()
103 svt::ToolboxController::dispose();
105 osl::MutexGuard aGuard( m_aMutex );
106 if( m_xPopupMenuController.is() )
108 css::uno::Reference< css::lang::XComponent > xComponent(
109 m_xPopupMenuController, css::uno::UNO_QUERY );
110 if( xComponent.is() )
114 xComponent->dispose();
116 catch (...)
119 m_xPopupMenuController.clear();
122 m_xContext.clear();
123 m_xPopupMenuFactory.clear();
124 m_xPopupMenu.clear();
127 void SAL_CALL PopupMenuToolbarController::initialize(
128 const css::uno::Sequence< css::uno::Any >& aArguments )
130 ToolboxController::initialize( aArguments );
132 osl::MutexGuard aGuard( m_aMutex );
133 if ( !m_aPopupCommand.getLength() )
134 m_aPopupCommand = m_aCommandURL;
138 m_xPopupMenuFactory.set(
139 css::frame::thePopupMenuControllerFactory::get( m_xContext ) );
140 m_bHasController = m_xPopupMenuFactory->hasController(
141 m_aPopupCommand, getModuleName() );
143 catch (const css::uno::Exception&)
145 TOOLS_INFO_EXCEPTION( "fwk.uielement", "" );
148 if ( !m_bHasController && m_aPopupCommand.startsWith( "private:resource/" ) )
150 m_bResourceURL = true;
151 m_bHasController = true;
154 SolarMutexGuard aSolarLock;
155 ToolBox* pToolBox = nullptr;
156 ToolBoxItemId nItemId;
157 if ( getToolboxId( nItemId, &pToolBox ) )
159 ToolBoxItemBits nCurStyle( pToolBox->GetItemBits( nItemId ) );
160 ToolBoxItemBits nSetStyle( getDropDownStyle() );
161 pToolBox->SetItemBits( nItemId,
162 m_bHasController ?
163 nCurStyle | nSetStyle :
164 nCurStyle & ~nSetStyle );
169 void SAL_CALL PopupMenuToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
171 if ( m_bResourceURL )
172 return;
174 ToolBox* pToolBox = nullptr;
175 ToolBoxItemId nItemId;
176 if ( getToolboxId( nItemId, &pToolBox ) )
178 SolarMutexGuard aSolarLock;
179 pToolBox->EnableItem( nItemId, rEvent.IsEnabled );
180 bool bValue;
181 if ( rEvent.State >>= bValue )
182 pToolBox->CheckItem( nItemId, bValue );
186 css::uno::Reference< css::awt::XWindow > SAL_CALL
187 PopupMenuToolbarController::createPopupWindow()
189 css::uno::Reference< css::awt::XWindow > xRet;
191 osl::MutexGuard aGuard( m_aMutex );
192 if ( !m_bHasController )
193 return xRet;
195 createPopupMenuController();
197 SolarMutexGuard aSolarLock;
198 VclPtr< ToolBox > pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
199 if ( !pToolBox )
200 return xRet;
202 pToolBox->SetItemDown( m_nToolBoxId, true );
203 WindowAlign eAlign( pToolBox->GetAlign() );
205 // If the parent ToolBox is in popup mode (e.g. sub toolbar, overflow popup),
206 // its ToolBarManager can be disposed along with our controller, destroying
207 // m_xPopupMenu, while the latter still in execute. This should be fixed at a
208 // different level, for now just hold it here so it won't crash.
209 css::uno::Reference< css::awt::XPopupMenu > xPopupMenu ( m_xPopupMenu );
210 sal_uInt16 nId = xPopupMenu->execute(
211 css::uno::Reference< css::awt::XWindowPeer >( getParent(), css::uno::UNO_QUERY ),
212 vcl::unohelper::ConvertToAWTRect( pToolBox->GetItemRect( m_nToolBoxId ) ),
213 ( eAlign == WindowAlign::Top || eAlign == WindowAlign::Bottom ) ?
214 css::awt::PopupMenuDirection::EXECUTE_DOWN :
215 css::awt::PopupMenuDirection::EXECUTE_RIGHT );
216 pToolBox->SetItemDown( m_nToolBoxId, false );
218 if ( nId )
219 functionExecuted( xPopupMenu->getCommand( nId ) );
221 return xRet;
224 void PopupMenuToolbarController::functionExecuted( const OUString &/*rCommand*/)
228 ToolBoxItemBits PopupMenuToolbarController::getDropDownStyle() const
230 return ToolBoxItemBits::DROPDOWN;
233 void PopupMenuToolbarController::createPopupMenuController()
235 if( !m_bHasController )
236 return;
238 if ( m_xPopupMenuController.is() )
240 m_xPopupMenuController->updatePopupMenu();
242 else
244 css::uno::Sequence<css::uno::Any> aArgs {
245 css::uno::Any(comphelper::makePropertyValue(u"Frame"_ustr, m_xFrame)),
246 css::uno::Any(comphelper::makePropertyValue(u"ModuleIdentifier"_ustr, m_sModuleName)),
247 css::uno::Any(comphelper::makePropertyValue(u"InToolbar"_ustr, true))
252 m_xPopupMenu = new VCLXPopupMenu();
254 if (m_bResourceURL)
256 sal_Int32 nAppendIndex = aArgs.getLength();
257 aArgs.realloc(nAppendIndex + 1);
258 aArgs.getArray()[nAppendIndex] <<= comphelper::makePropertyValue(u"ResourceURL"_ustr, m_aPopupCommand);
260 m_xPopupMenuController.set( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
261 u"com.sun.star.comp.framework.ResourceMenuController"_ustr, aArgs, m_xContext), css::uno::UNO_QUERY_THROW );
263 else
265 m_xPopupMenuController.set( m_xPopupMenuFactory->createInstanceWithArgumentsAndContext(
266 m_aPopupCommand, aArgs, m_xContext), css::uno::UNO_QUERY_THROW );
269 m_xPopupMenuController->setPopupMenu( m_xPopupMenu );
271 catch ( const css::uno::Exception & )
273 TOOLS_INFO_EXCEPTION( "fwk.uielement", "" );
274 m_xPopupMenu.clear();
279 class GenericPopupToolbarController : public PopupMenuToolbarController
281 public:
282 GenericPopupToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
283 const css::uno::Sequence< css::uno::Any >& rxArgs );
285 // XInitialization
286 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rxArgs ) override;
288 // XStatusListener
289 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
291 // XServiceInfo
292 virtual OUString SAL_CALL getImplementationName() override;
294 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) override;
296 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
298 private:
299 bool m_bSplitButton, m_bReplaceWithLast;
300 void functionExecuted(const OUString &rCommand) override;
301 ToolBoxItemBits getDropDownStyle() const override;
304 GenericPopupToolbarController::GenericPopupToolbarController(
305 const css::uno::Reference< css::uno::XComponentContext >& xContext,
306 const css::uno::Sequence< css::uno::Any >& rxArgs )
307 : PopupMenuToolbarController( xContext )
308 , m_bReplaceWithLast( false )
310 css::beans::PropertyValue aPropValue;
311 for ( const auto& arg: rxArgs )
313 if ( ( arg >>= aPropValue ) && aPropValue.Name == "Value" )
315 sal_Int32 nIdx{ 0 };
316 OUString aValue;
317 aPropValue.Value >>= aValue;
318 m_aPopupCommand = aValue.getToken(0, ';', nIdx);
319 m_bReplaceWithLast = aValue.getToken(0, ';', nIdx).toBoolean();
320 break;
323 m_bSplitButton = m_bReplaceWithLast || !m_aPopupCommand.isEmpty();
326 OUString GenericPopupToolbarController::getImplementationName()
328 return u"com.sun.star.comp.framework.GenericPopupToolbarController"_ustr;
331 sal_Bool GenericPopupToolbarController::supportsService(OUString const & rServiceName)
333 return cppu::supportsService( this, rServiceName );
336 css::uno::Sequence<OUString> GenericPopupToolbarController::getSupportedServiceNames()
338 return {u"com.sun.star.frame.ToolbarController"_ustr};
341 void GenericPopupToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& rxArgs )
343 PopupMenuToolbarController::initialize( rxArgs );
344 if ( m_bReplaceWithLast )
345 // Create early, so we can use the menu is statusChanged method.
346 createPopupMenuController();
349 void GenericPopupToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
351 SolarMutexGuard aGuard;
353 if ( m_bReplaceWithLast && !rEvent.IsEnabled && m_xPopupMenu.is() )
355 ToolBox* pToolBox = nullptr;
356 ToolBoxItemId nId;
357 if ( getToolboxId( nId, &pToolBox ) && pToolBox->IsItemEnabled( nId ) )
359 Menu* pVclMenu = m_xPopupMenu->GetMenu();
360 pVclMenu->Activate();
361 pVclMenu->Deactivate();
364 for (sal_uInt16 i = 0, nCount = m_xPopupMenu->getItemCount(); i < nCount; ++i )
366 sal_uInt16 nItemId = m_xPopupMenu->getItemId(i);
367 if (nItemId && m_xPopupMenu->isItemEnabled(nItemId) && !m_xPopupMenu->getPopupMenu(nItemId).is())
369 functionExecuted(m_xPopupMenu->getCommand(nItemId));
370 return;
375 PopupMenuToolbarController::statusChanged( rEvent );
378 void GenericPopupToolbarController::functionExecuted( const OUString& rCommand )
380 if ( !m_bReplaceWithLast )
381 return;
383 removeStatusListener( m_aCommandURL );
385 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rCommand, m_sModuleName);
386 OUString aRealCommand( vcl::CommandInfoProvider::GetRealCommandForCommand(aProperties) );
387 m_aCommandURL = aRealCommand.isEmpty() ? rCommand : aRealCommand;
388 addStatusListener( m_aCommandURL );
390 ToolBox* pToolBox = nullptr;
391 ToolBoxItemId nId;
392 if ( getToolboxId( nId, &pToolBox ) )
394 pToolBox->SetItemCommand( nId, rCommand );
395 pToolBox->SetHelpText( nId, OUString() ); // Will retrieve the new one from help.
396 pToolBox->SetItemText(nId, vcl::CommandInfoProvider::GetLabelForCommand(aProperties));
397 pToolBox->SetQuickHelpText(nId, vcl::CommandInfoProvider::GetTooltipForCommand(rCommand, aProperties, m_xFrame));
399 Image aImage = vcl::CommandInfoProvider::GetImageForCommand(rCommand, m_xFrame, pToolBox->GetImageSize());
400 if ( !!aImage )
401 pToolBox->SetItemImage( nId, aImage );
405 ToolBoxItemBits GenericPopupToolbarController::getDropDownStyle() const
407 return m_bSplitButton ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY;
410 class SaveToolbarController : public cppu::ImplInheritanceHelper< PopupMenuToolbarController,
411 css::frame::XSubToolbarController,
412 css::util::XModifyListener >
414 public:
415 explicit SaveToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
417 // XInitialization
418 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
420 // XSubToolbarController
421 // Make ToolBarManager ask our controller for updated image, in case of icon theme change.
422 virtual sal_Bool SAL_CALL opensSubToolbar() override;
423 virtual OUString SAL_CALL getSubToolbarName() override;
424 virtual void SAL_CALL functionSelected( const OUString& aCommand ) override;
425 virtual void SAL_CALL updateImage() override;
427 // XStatusListener
428 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
430 // XModifyListener
431 virtual void SAL_CALL modified( const css::lang::EventObject& rEvent ) override;
433 // XEventListener
434 virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) override;
436 // XComponent
437 virtual void SAL_CALL dispose() override;
439 // XServiceInfo
440 virtual OUString SAL_CALL getImplementationName() override;
441 virtual sal_Bool SAL_CALL supportsService( OUString const & rServiceName ) override;
442 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
444 private:
445 bool m_bReadOnly;
446 bool m_bModified;
447 css::uno::Reference< css::frame::XStorable > m_xStorable;
448 css::uno::Reference< css::util::XModifiable > m_xModifiable;
451 SaveToolbarController::SaveToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
452 : ImplInheritanceHelper( rxContext, ".uno:SaveAsMenu" )
453 , m_bReadOnly( false )
454 , m_bModified( false )
458 void SaveToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
460 PopupMenuToolbarController::initialize( aArguments );
462 // Also listen to the status of the slot used for read-only case
463 m_aListenerMap.emplace(u".uno:SaveAs"_ustr, css::uno::Reference<css::frame::XDispatch>());
465 ToolBox* pToolBox = nullptr;
466 ToolBoxItemId nId;
467 if ( !getToolboxId( nId, &pToolBox ) )
468 return;
470 css::uno::Reference< css::frame::XController > xController = m_xFrame->getController();
471 if ( xController.is() )
472 m_xModifiable.set( xController->getModel(), css::uno::UNO_QUERY );
474 if ( m_xModifiable.is() && pToolBox->GetItemCommand( nId ) == m_aCommandURL )
475 // Will also enable the save as only mode.
476 m_xStorable.set( m_xModifiable, css::uno::UNO_QUERY );
477 else if ( !m_xModifiable.is() )
478 // Can be in table/query design.
479 m_xModifiable.set( xController, css::uno::UNO_QUERY );
480 else
481 // Simple save button, without the dropdown.
482 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) & ~ ToolBoxItemBits::DROPDOWN );
484 if ( m_xModifiable.is() )
486 m_xModifiable->addModifyListener( this );
487 modified( css::lang::EventObject() );
491 sal_Bool SaveToolbarController::opensSubToolbar()
493 return true;
496 OUString SaveToolbarController::getSubToolbarName()
498 return OUString();
501 void SaveToolbarController::functionSelected( const OUString& /*aCommand*/ )
505 void SaveToolbarController::updateImage()
507 SolarMutexGuard aGuard;
508 ToolBox* pToolBox = nullptr;
509 ToolBoxItemId nId;
510 if ( !getToolboxId( nId, &pToolBox ) )
511 return;
513 vcl::ImageType eImageType = pToolBox->GetImageSize();
515 Image aImage;
517 if ( m_bReadOnly )
519 aImage = vcl::CommandInfoProvider::GetImageForCommand(u".uno:SaveAs"_ustr, m_xFrame, eImageType);
521 else if ( m_bModified )
523 if (eImageType == vcl::ImageType::Size26)
524 aImage = Image(StockImage::Yes, BMP_SAVEMODIFIED_LARGE);
525 else if (eImageType == vcl::ImageType::Size32)
526 aImage = Image(StockImage::Yes, BMP_SAVEMODIFIED_EXTRALARGE);
527 else
528 aImage = Image(StockImage::Yes, BMP_SAVEMODIFIED_SMALL);
531 if ( !aImage )
532 aImage = vcl::CommandInfoProvider::GetImageForCommand(m_aCommandURL, m_xFrame, eImageType);
534 if ( !!aImage )
535 pToolBox->SetItemImage( nId, aImage );
538 void SaveToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
540 ToolBox* pToolBox = nullptr;
541 ToolBoxItemId nId;
542 if ( !getToolboxId( nId, &pToolBox ) )
543 return;
545 bool bLastReadOnly = m_bReadOnly;
546 m_bReadOnly = m_xStorable.is() && m_xStorable->isReadonly();
547 OUString sCommand = m_bReadOnly ? u".uno:SaveAs"_ustr : m_aCommandURL;
548 if ( bLastReadOnly != m_bReadOnly )
550 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(sCommand,
551 vcl::CommandInfoProvider::GetModuleIdentifier(m_xFrame));
552 pToolBox->SetQuickHelpText( nId,
553 vcl::CommandInfoProvider::GetTooltipForCommand(sCommand, aProperties, m_xFrame) );
554 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) & ~( m_bReadOnly ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY ) );
555 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ( m_bReadOnly ? ToolBoxItemBits::DROPDOWNONLY : ToolBoxItemBits::DROPDOWN ) );
556 updateImage();
559 if (rEvent.FeatureURL.Complete == sCommand)
560 pToolBox->EnableItem(nId, rEvent.IsEnabled);
563 void SaveToolbarController::modified( const css::lang::EventObject& /*rEvent*/ )
565 bool bLastModified = m_bModified;
566 m_bModified = m_xModifiable->isModified();
567 if ( bLastModified != m_bModified )
568 updateImage();
571 void SaveToolbarController::disposing( const css::lang::EventObject& rEvent )
573 if ( rEvent.Source == m_xModifiable )
575 m_xModifiable.clear();
576 m_xStorable.clear();
578 else
579 PopupMenuToolbarController::disposing( rEvent );
582 void SaveToolbarController::dispose()
584 PopupMenuToolbarController::dispose();
585 if ( m_xModifiable.is() )
587 m_xModifiable->removeModifyListener( this );
588 m_xModifiable.clear();
590 m_xStorable.clear();
593 OUString SaveToolbarController::getImplementationName()
595 return u"com.sun.star.comp.framework.SaveToolbarController"_ustr;
598 sal_Bool SaveToolbarController::supportsService( OUString const & rServiceName )
600 return cppu::supportsService( this, rServiceName );
603 css::uno::Sequence< OUString > SaveToolbarController::getSupportedServiceNames()
605 return {u"com.sun.star.frame.ToolbarController"_ustr};
608 class NewToolbarController : public cppu::ImplInheritanceHelper<PopupMenuToolbarController, css::frame::XSubToolbarController>
610 public:
611 explicit NewToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
613 // XServiceInfo
614 OUString SAL_CALL getImplementationName() override;
616 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) override;
618 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
620 void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
622 // XSubToolbarController
623 // Make ToolBarManager ask our controller for updated image, in case of icon theme change.
624 sal_Bool SAL_CALL opensSubToolbar() override { return true; }
625 OUString SAL_CALL getSubToolbarName() override { return OUString(); }
626 void SAL_CALL functionSelected( const OUString& ) override {}
627 void SAL_CALL updateImage() override;
629 private:
630 void functionExecuted( const OUString &rCommand ) override;
631 void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
632 void SAL_CALL execute( sal_Int16 KeyModifier ) override;
633 sal_uInt16 getMenuIdForCommand( std::u16string_view rCommand );
635 sal_uInt16 m_nMenuId;
638 NewToolbarController::NewToolbarController(
639 const css::uno::Reference< css::uno::XComponentContext >& xContext )
640 : ImplInheritanceHelper( xContext )
641 , m_nMenuId( 0 )
645 OUString NewToolbarController::getImplementationName()
647 return u"org.apache.openoffice.comp.framework.NewToolbarController"_ustr;
650 sal_Bool NewToolbarController::supportsService(OUString const & rServiceName)
652 return cppu::supportsService( this, rServiceName );
655 css::uno::Sequence<OUString> NewToolbarController::getSupportedServiceNames()
657 return {u"com.sun.star.frame.ToolbarController"_ustr};
660 void SAL_CALL NewToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
662 PopupMenuToolbarController::initialize( aArguments );
664 osl::MutexGuard aGuard( m_aMutex );
665 createPopupMenuController();
668 void SAL_CALL NewToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
670 if ( rEvent.IsEnabled )
672 OUString aState;
673 rEvent.State >>= aState;
676 // set the image even if the state is not a string
677 // the toolbar item command will be used as a fallback
678 functionExecuted( aState );
680 catch (const css::ucb::CommandFailedException&)
683 catch (const css::ucb::ContentCreationException&)
688 enable( rEvent.IsEnabled );
691 void SAL_CALL NewToolbarController::execute( sal_Int16 /*KeyModifier*/ )
693 osl::MutexGuard aGuard( m_aMutex );
695 OUString aURL, aTarget;
696 if ( m_xPopupMenu.is() && m_nMenuId )
698 SolarMutexGuard aSolarMutexGuard;
699 aURL = m_xPopupMenu->getCommand(m_nMenuId);
701 // TODO investigate how to wrap Get/SetUserValue in css::awt::XMenu
702 MenuAttributes* pMenuAttributes(static_cast<MenuAttributes*>(m_xPopupMenu->getUserValue(m_nMenuId)));
703 if ( pMenuAttributes )
704 aTarget = pMenuAttributes->aTargetFrame;
705 else
706 aTarget = "_default";
708 else
709 aURL = m_aCommandURL;
711 // tdf#144407 save the current window state so a new window of the same type will
712 // open with the same settings
713 PersistentWindowState::SaveWindowStateToConfig(m_xContext, m_xFrame);
715 css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
716 u"Referer"_ustr, u"private:user"_ustr) };
718 dispatchCommand( aURL, aArgs, aTarget );
721 void NewToolbarController::functionExecuted( const OUString &rCommand )
723 m_nMenuId = getMenuIdForCommand( rCommand );
724 updateImage();
727 sal_uInt16 NewToolbarController::getMenuIdForCommand( std::u16string_view rCommand )
729 if ( m_xPopupMenu.is() && !rCommand.empty() )
731 sal_uInt16 nCount = m_xPopupMenu->getItemCount();
732 for ( sal_uInt16 n = 0; n < nCount; ++n )
734 sal_uInt16 nId = m_xPopupMenu->getItemId(n);
735 OUString aCmd(m_xPopupMenu->getCommand(nId));
737 // match even if the menu command is more detailed
738 // (maybe an additional query) #i28667#
739 if ( aCmd.match( rCommand ) )
740 return nId;
744 return 0;
747 void SAL_CALL NewToolbarController::updateImage()
749 SolarMutexGuard aSolarLock;
750 VclPtr< ToolBox> pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
751 if ( !pToolBox )
752 return;
754 OUString aURL, aImageId;
755 if ( m_xPopupMenu.is() && m_nMenuId )
757 aURL = m_xPopupMenu->getCommand(m_nMenuId);
758 MenuAttributes* pMenuAttributes(static_cast<MenuAttributes*>(m_xPopupMenu->getUserValue(m_nMenuId)));
759 if ( pMenuAttributes )
760 aImageId = pMenuAttributes->aImageId;
762 else
763 aURL = m_aCommandURL;
765 INetURLObject aURLObj( aImageId.isEmpty() ? aURL : aImageId );
766 vcl::ImageType eImageType( pToolBox->GetImageSize() );
767 Image aImage = SvFileInformationManager::GetImageNoDefault( aURLObj, eImageType );
768 if ( !aImage )
769 aImage = vcl::CommandInfoProvider::GetImageForCommand( aURL, m_xFrame, eImageType );
771 if ( !aImage )
772 return;
774 pToolBox->SetItemImage( m_nToolBoxId, aImage );
779 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
780 com_sun_star_comp_framework_GenericPopupToolbarController_get_implementation(
781 css::uno::XComponentContext *context,
782 css::uno::Sequence<css::uno::Any> const &args)
784 return cppu::acquire(new GenericPopupToolbarController(context, args));
787 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
788 com_sun_star_comp_framework_SaveToolbarController_get_implementation(
789 css::uno::XComponentContext *context,
790 css::uno::Sequence<css::uno::Any> const &)
792 return cppu::acquire(new SaveToolbarController(context));
795 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
796 org_apache_openoffice_comp_framework_NewToolbarController_get_implementation(
797 css::uno::XComponentContext *context,
798 css::uno::Sequence<css::uno::Any> const &)
800 return cppu::acquire(new NewToolbarController(context));
803 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */