Move setting of LD_LIBRARY_PATH closer to invocation of cppunittester
[LibreOffice.git] / framework / source / uielement / subtoolbarcontroller.cxx
blobffa4dd0924fac95489e2a008e97a9f0118dc61f1
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 <comphelper/propertysequence.hxx>
21 #include <cppuhelper/implbase.hxx>
22 #include <cppuhelper/supportsservice.hxx>
23 #include <cppuhelper/weakref.hxx>
24 #include <svtools/popupwindowcontroller.hxx>
25 #include <svtools/toolbarmenu.hxx>
26 #include <toolkit/helper/vclunohelper.hxx>
27 #include <tools/gen.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/toolbox.hxx>
30 #include <vcl/commandinfoprovider.hxx>
31 #include <vcl/weldutils.hxx>
33 #include <com/sun/star/awt/XDockableWindow.hpp>
34 #include <com/sun/star/frame/XLayoutManager.hpp>
35 #include <com/sun/star/frame/XSubToolbarController.hpp>
36 #include <com/sun/star/frame/status/Visibility.hpp>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
39 #include <com/sun/star/container/NoSuchElementException.hpp>
41 typedef cppu::ImplInheritanceHelper< svt::PopupWindowController,
42 css::frame::XSubToolbarController,
43 css::awt::XDockableWindowListener> ToolBarBase;
45 namespace {
47 class SubToolBarController : public ToolBarBase
49 OUString m_aSubTbName;
50 OUString m_aLastCommand;
51 css::uno::Reference< css::ui::XUIElement > m_xUIElement;
52 void disposeUIElement();
53 public:
54 explicit SubToolBarController( const rtl::Reference< css::uno::XComponentContext >& rxContext,
55 const css::uno::Sequence< css::uno::Any >& rxArgs );
56 virtual ~SubToolBarController() override;
58 void PopoverDestroyed();
60 // XInitialization
61 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rxArgs ) override;
63 // XStatusListener
64 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override;
66 // XToolbarController
67 virtual void SAL_CALL execute( sal_Int16 nKeyModifier ) override;
69 // PopupWindowController
70 virtual VclPtr<vcl::Window> createVclPopupWindow(vcl::Window* pParent) override;
71 virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
73 // XSubToolbarController
74 virtual sal_Bool SAL_CALL opensSubToolbar() override;
75 virtual OUString SAL_CALL getSubToolbarName() override;
76 virtual void SAL_CALL functionSelected( const OUString& rCommand ) override;
77 virtual void SAL_CALL updateImage() override;
79 // XDockableWindowListener
80 virtual void SAL_CALL startDocking( const css::awt::DockingEvent& e ) override;
81 virtual css::awt::DockingData SAL_CALL docking( const css::awt::DockingEvent& e ) override;
82 virtual void SAL_CALL endDocking( const css::awt::EndDockingEvent& e ) override;
83 virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const css::lang::EventObject& e ) override;
84 virtual void SAL_CALL toggleFloatingMode( const css::lang::EventObject& e ) override;
85 virtual void SAL_CALL closed( const css::lang::EventObject& e ) override;
86 virtual void SAL_CALL endPopupMode( const css::awt::EndPopupModeEvent& e ) override;
88 // XEventListener
89 virtual void SAL_CALL disposing( const css::lang::EventObject& e ) override;
91 // XComponent
92 virtual void SAL_CALL dispose() override;
94 // XServiceInfo
95 virtual OUString SAL_CALL getImplementationName() override;
96 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
97 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
102 SubToolBarController::SubToolBarController(
103 const rtl::Reference< css::uno::XComponentContext >& rxContext,
104 const css::uno::Sequence< css::uno::Any >& rxArgs
105 ) : ToolBarBase(
106 rxContext,
107 rtl::Reference< css::frame::XFrame >(),
111 for ( css::uno::Any const & arg : rxArgs )
113 css::beans::PropertyValue aPropValue;
114 arg >>= aPropValue;
115 if ( aPropValue.Name == "Value" )
117 sal_Int32 nIdx{ 0 };
118 OUString aValue;
119 aPropValue.Value >>= aValue;
120 m_aSubTbName = aValue.getToken(0, ';', nIdx);
121 m_aCommandURL = m_aSubTbName;
122 m_aLastCommand = aValue.getToken(0, ';', nIdx);
123 break;
126 if ( !m_aLastCommand.isEmpty() )
127 addStatusListener( m_aLastCommand );
130 SubToolBarController::~SubToolBarController()
132 disposeUIElement();
133 m_xUIElement = nullptr;
136 void SubToolBarController::disposeUIElement()
138 if ( m_xUIElement.is() )
140 css::uno::Reference< css::lang::XComponent > xComponent( m_xUIElement, css::uno::UNO_QUERY );
141 xComponent->dispose();
145 void SubToolBarController::statusChanged( const css::frame::FeatureStateEvent& Event )
147 SolarMutexGuard aSolarMutexGuard;
149 if ( m_bDisposed )
150 return;
152 ToolBox* pToolBox = nullptr;
153 ToolBoxItemId nId;
154 if ( !getToolboxId( nId, &pToolBox ) )
155 return;
157 ToolBoxItemBits nItemBits = pToolBox->GetItemBits( nId );
158 nItemBits &= ~ToolBoxItemBits::CHECKABLE;
159 TriState eTri = TRISTATE_FALSE;
161 if ( Event.FeatureURL.Complete == m_aCommandURL )
163 pToolBox->EnableItem( nId, Event.IsEnabled );
165 OUString aStrValue;
166 css::frame::status::Visibility aItemVisibility;
167 if ( Event.State >>= aStrValue )
169 // Enum command, such as the current custom shape,
170 // toggle checked state.
171 if ( m_aLastCommand == Concat2View( m_aCommandURL + "." + aStrValue ) )
173 eTri = TRISTATE_TRUE;
174 nItemBits |= ToolBoxItemBits::CHECKABLE;
177 else if ( Event.State >>= aItemVisibility )
179 pToolBox->ShowItem( nId, aItemVisibility.bVisible );
182 else
184 bool bValue;
185 if ( Event.State >>= bValue )
187 // Boolean, treat it as checked/unchecked
188 if ( bValue )
189 eTri = TRISTATE_TRUE;
190 nItemBits |= ToolBoxItemBits::CHECKABLE;
194 pToolBox->SetItemState( nId, eTri );
195 pToolBox->SetItemBits( nId, nItemBits );
198 void SubToolBarController::execute( sal_Int16 nKeyModifier )
200 if ( !m_aLastCommand.isEmpty() )
202 auto aArgs( comphelper::InitPropertySequence( {
203 { "KeyModifier", css::uno::Any( nKeyModifier ) }
204 } ) );
205 dispatchCommand( m_aLastCommand, aArgs );
209 namespace {
210 class SubToolbarControl final : public WeldToolbarPopup
212 public:
213 explicit SubToolbarControl(SubToolBarController& rController, weld::Widget* pParent);
214 virtual ~SubToolbarControl() override;
216 virtual void GrabFocus() override;
218 weld::Container* GetContainer() { return m_xTargetContainer.get(); }
220 private:
221 SubToolBarController& m_rController;
222 std::unique_ptr<weld::Container> m_xTargetContainer;
226 SubToolbarControl::SubToolbarControl(SubToolBarController& rController,
227 weld::Widget* pParent)
228 : WeldToolbarPopup(rController.getFrameInterface(), pParent, u"svt/ui/subtoolbar.ui"_ustr, u"subtoolbar"_ustr)
229 , m_rController(rController)
230 , m_xTargetContainer(m_xBuilder->weld_container(u"container"_ustr))
234 void SubToolbarControl::GrabFocus()
236 // TODO
239 SubToolbarControl::~SubToolbarControl()
241 m_rController.PopoverDestroyed();
244 std::unique_ptr<WeldToolbarPopup> SubToolBarController::weldPopupWindow()
246 SolarMutexGuard aGuard;
248 auto pPopup = std::make_unique<SubToolbarControl>(*this, m_pToolbar);
250 css::uno::Reference< css::frame::XFrame > xFrame ( getFrameInterface() );
252 // create element with factory
253 static css::uno::WeakReference< css::ui::XUIElementFactoryManager > xWeakUIElementFactory;
254 css::uno::Reference< css::ui::XUIElementFactoryManager > xUIElementFactory = xWeakUIElementFactory;
255 if ( !xUIElementFactory.is() )
257 xUIElementFactory = css::ui::theUIElementFactoryManager::get( m_xContext );
258 xWeakUIElementFactory = xUIElementFactory;
261 css::uno::Reference< css::awt::XWindow > xParent = new weld::TransportAsXWindow(pPopup->GetContainer());
263 auto aPropSeq( comphelper::InitPropertySequence( {
264 { "Frame", css::uno::Any( xFrame ) },
265 { "ParentWindow", css::uno::Any( xParent ) },
266 { "Persistent", css::uno::Any( false ) },
267 { "PopupMode", css::uno::Any( true ) }
268 } ) );
272 m_xUIElement = xUIElementFactory->createUIElement( "private:resource/toolbar/" + m_aSubTbName, aPropSeq );
274 catch ( css::container::NoSuchElementException& )
276 catch ( css::lang::IllegalArgumentException& )
279 return pPopup;
282 VclPtr<vcl::Window> SubToolBarController::createVclPopupWindow(vcl::Window* /*pParent*/)
284 SolarMutexGuard aGuard;
286 ToolBox* pToolBox = nullptr;
287 ToolBoxItemId nId;
288 if ( getToolboxId( nId, &pToolBox ) )
290 css::uno::Reference< css::frame::XFrame > xFrame ( getFrameInterface() );
292 // create element with factory
293 static css::uno::WeakReference< css::ui::XUIElementFactoryManager > xWeakUIElementFactory;
294 css::uno::Reference< css::ui::XUIElement > xUIElement;
295 css::uno::Reference< css::ui::XUIElementFactoryManager > xUIElementFactory = xWeakUIElementFactory;
296 if ( !xUIElementFactory.is() )
298 xUIElementFactory = css::ui::theUIElementFactoryManager::get( m_xContext );
299 xWeakUIElementFactory = xUIElementFactory;
302 auto aPropSeq( comphelper::InitPropertySequence( {
303 { "Frame", css::uno::Any( xFrame ) },
304 { "ParentWindow", css::uno::Any( m_xParentWindow ) },
305 { "Persistent", css::uno::Any( false ) },
306 { "PopupMode", css::uno::Any( true ) }
307 } ) );
311 xUIElement = xUIElementFactory->createUIElement( "private:resource/toolbar/" + m_aSubTbName, aPropSeq );
313 catch ( css::container::NoSuchElementException& )
315 catch ( css::lang::IllegalArgumentException& )
318 if ( xUIElement.is() )
320 css::uno::Reference< css::awt::XWindow > xSubToolBar( xUIElement->getRealInterface(), css::uno::UNO_QUERY );
321 if ( xSubToolBar.is() )
323 css::uno::Reference< css::awt::XDockableWindow > xDockWindow( xSubToolBar, css::uno::UNO_QUERY );
324 xDockWindow->addDockableWindowListener( css::uno::Reference< css::awt::XDockableWindowListener >(this) );
325 xDockWindow->enableDocking( true );
327 // keep reference to UIElement to avoid its destruction
328 disposeUIElement();
329 m_xUIElement = std::move(xUIElement);
331 VclPtr<vcl::Window> pTbxWindow = VCLUnoHelper::GetWindow( xSubToolBar );
332 if ( pTbxWindow && pTbxWindow->GetType() == WindowType::TOOLBOX )
334 ToolBox* pToolBar = static_cast< ToolBox* >( pTbxWindow.get() );
335 // calc and set size for popup mode
336 Size aSize = pToolBar->CalcPopupWindowSizePixel();
337 pToolBar->SetSizePixel( aSize );
338 // open subtoolbox in popup mode
339 vcl::Window::GetDockingManager()->StartPopupMode( pToolBox, pToolBar );
344 return nullptr;
347 sal_Bool SubToolBarController::opensSubToolbar()
349 return !m_aLastCommand.isEmpty();
352 OUString SubToolBarController::getSubToolbarName()
354 return m_aSubTbName;
357 void SubToolBarController::functionSelected( const OUString& rCommand )
359 if ( !m_aLastCommand.isEmpty() && m_aLastCommand != rCommand )
361 removeStatusListener( m_aLastCommand );
362 m_aLastCommand = rCommand;
363 addStatusListener( m_aLastCommand );
364 updateImage();
368 void SubToolBarController::updateImage()
370 SolarMutexGuard aGuard;
371 if ( !m_aLastCommand.isEmpty() )
373 ToolBox* pToolBox = nullptr;
374 ToolBoxItemId nId;
375 if ( getToolboxId( nId, &pToolBox ) )
377 vcl::ImageType eImageType = pToolBox->GetImageSize();
378 Image aImage = vcl::CommandInfoProvider::GetImageForCommand(m_aLastCommand, getFrameInterface(), eImageType);
379 if ( !!aImage )
380 pToolBox->SetItemImage( nId, aImage );
385 void SubToolBarController::startDocking( const css::awt::DockingEvent& )
389 css::awt::DockingData SubToolBarController::docking( const css::awt::DockingEvent& )
391 return css::awt::DockingData();
394 void SubToolBarController::endDocking( const css::awt::EndDockingEvent& )
398 sal_Bool SubToolBarController::prepareToggleFloatingMode( const css::lang::EventObject& )
400 return false;
403 void SubToolBarController::toggleFloatingMode( const css::lang::EventObject& )
407 void SubToolBarController::closed( const css::lang::EventObject& )
411 void SubToolBarController::endPopupMode( const css::awt::EndPopupModeEvent& e )
413 SolarMutexGuard aGuard;
415 OUString aSubToolBarResName;
416 if ( m_xUIElement.is() )
418 css::uno::Reference< css::beans::XPropertySet > xPropSet( m_xUIElement, css::uno::UNO_QUERY );
419 if ( xPropSet.is() )
423 xPropSet->getPropertyValue(u"ResourceURL"_ustr) >>= aSubToolBarResName;
425 catch ( css::beans::UnknownPropertyException& )
427 catch ( css::lang::WrappedTargetException& )
430 disposeUIElement();
432 m_xUIElement = nullptr;
434 // if the toolbar was teared-off recreate it and place it at the given position
435 if( !e.bTearoff )
436 return;
438 css::uno::Reference< css::ui::XUIElement > xUIElement;
439 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager = getLayoutManager();
441 if ( !xLayoutManager.is() )
442 return;
444 xLayoutManager->createElement( aSubToolBarResName );
445 xUIElement = xLayoutManager->getElement( aSubToolBarResName );
446 if ( !xUIElement.is() )
447 return;
449 css::uno::Reference< css::awt::XWindow > xSubToolBar( xUIElement->getRealInterface(), css::uno::UNO_QUERY );
450 css::uno::Reference< css::beans::XPropertySet > xProp( xUIElement, css::uno::UNO_QUERY );
451 if ( !(xSubToolBar.is() && xProp.is()) )
452 return;
456 VclPtr<vcl::Window> pTbxWindow = VCLUnoHelper::GetWindow( xSubToolBar );
457 if ( pTbxWindow && pTbxWindow->GetType() == WindowType::TOOLBOX )
459 OUString aPersistentString( u"Persistent"_ustr );
460 css::uno::Any a = xProp->getPropertyValue( aPersistentString );
461 xProp->setPropertyValue( aPersistentString, css::uno::Any( false ) );
463 xLayoutManager->hideElement( aSubToolBarResName );
464 xLayoutManager->floatWindow( aSubToolBarResName );
466 xLayoutManager->setElementPos( aSubToolBarResName, e.FloatingPosition );
467 xLayoutManager->showElement( aSubToolBarResName );
469 xProp->setPropertyValue(u"Persistent"_ustr, a );
472 catch ( css::uno::RuntimeException& )
474 throw;
476 catch ( css::uno::Exception& )
480 void SubToolBarController::disposing( const css::lang::EventObject& e )
482 svt::ToolboxController::disposing( e );
485 void SubToolBarController::initialize( const css::uno::Sequence< css::uno::Any >& rxArgs )
487 svt::PopupWindowController::initialize( rxArgs );
489 ToolBox* pToolBox = nullptr;
490 ToolBoxItemId nId;
491 if ( getToolboxId( nId, &pToolBox ) )
493 if ( m_aLastCommand.isEmpty() )
494 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
495 else
496 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWN );
499 if (m_pToolbar)
501 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
502 m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
505 updateImage();
508 void SubToolBarController::PopoverDestroyed()
510 disposeUIElement();
511 m_xUIElement = nullptr;
514 void SubToolBarController::dispose()
516 if ( m_bDisposed )
517 return;
519 svt::PopupWindowController::dispose();
520 disposeUIElement();
521 m_xUIElement = nullptr;
524 OUString SubToolBarController::getImplementationName()
526 return u"com.sun.star.comp.framework.SubToolBarController"_ustr;
529 sal_Bool SubToolBarController::supportsService( const OUString& rServiceName )
531 return cppu::supportsService( this, rServiceName );
534 css::uno::Sequence< OUString > SubToolBarController::getSupportedServiceNames()
536 return {u"com.sun.star.frame.ToolbarController"_ustr};
539 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
540 com_sun_star_comp_framework_SubToolBarController_get_implementation(
541 css::uno::XComponentContext* rxContext,
542 css::uno::Sequence<css::uno::Any> const & rxArgs )
544 return cppu::acquire( new SubToolBarController( rxContext, rxArgs ) );
547 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */