Avoid potential negative array index access to cached text.
[LibreOffice.git] / framework / source / uielement / toolbarwrapper.cxx
blobae988744c14212c4da9550609612df9de1964f16
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 <uielement/toolbarwrapper.hxx>
21 #include <uielement/toolbarmanager.hxx>
23 #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
24 #include <com/sun/star/ui/UIElementType.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <toolkit/helper/vclunohelper.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/toolbox.hxx>
31 #include <vcl/weldutils.hxx>
33 using namespace com::sun::star;
34 using namespace com::sun::star::uno;
35 using namespace com::sun::star::beans;
36 using namespace com::sun::star::frame;
37 using namespace com::sun::star::lang;
38 using namespace com::sun::star::container;
39 using namespace com::sun::star::awt;
40 using namespace ::com::sun::star::ui;
42 namespace framework
45 ToolBarWrapper::ToolBarWrapper( const Reference< XComponentContext >& rxContext ) :
46 ImplInheritanceHelper( UIElementType::TOOLBAR ),
47 m_xContext( rxContext )
51 ToolBarWrapper::~ToolBarWrapper()
53 m_xWeldedToolbar.reset(nullptr);
54 m_xTopLevel.reset(nullptr);
55 m_xBuilder.reset(nullptr);
58 // XComponent
59 void SAL_CALL ToolBarWrapper::dispose()
61 Reference< XComponent > xThis(this);
64 SolarMutexGuard g;
65 if ( m_bDisposed )
66 return;
69 css::lang::EventObject aEvent( xThis );
70 m_aListenerContainer.disposeAndClear( aEvent );
72 SolarMutexGuard g;
74 auto xMultiplexer( ContextChangeEventMultiplexer::get( m_xContext ) );
75 xMultiplexer->removeAllContextChangeEventListeners( this );
77 Reference< XComponent > xComponent( m_xSubElement, UNO_QUERY );
78 if ( xComponent.is() )
79 xComponent->removeEventListener( Reference< XUIConfigurationListener >( this ));
80 m_xSubElement.clear();
82 if ( m_xToolBarManager.is() )
83 m_xToolBarManager->dispose();
84 m_xToolBarManager.clear();
85 m_xConfigSource.clear();
86 m_xConfigData.clear();
88 m_bDisposed = true;
91 // XInitialization
92 void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments )
94 SolarMutexGuard g;
96 if ( m_bDisposed )
97 throw DisposedException();
99 if ( m_bInitialized )
100 return;
102 UIConfigElementWrapperBase::initialize( aArguments );
104 bool bPopupMode( false );
105 Reference< XWindow > xParentWindow;
106 for ( Any const & arg : aArguments )
108 PropertyValue aPropValue;
109 if ( arg >>= aPropValue )
111 if ( aPropValue.Name == "PopupMode" )
112 aPropValue.Value >>= bPopupMode;
113 else if ( aPropValue.Name == "ParentWindow" )
114 xParentWindow.set( aPropValue.Value, UNO_QUERY );
118 Reference< XFrame > xFrame( m_xWeakFrame );
119 if ( !(xFrame.is() && m_xConfigSource.is()) )
120 return;
122 OUString aContextPart;
123 if ( m_aResourceURL.startsWith( "private:resource/toolbar/singlemode", &aContextPart ) && aContextPart.isEmpty() )
125 auto xMultiplexer( ContextChangeEventMultiplexer::get( m_xContext ) );
128 xMultiplexer->addContextChangeEventListener( this, xFrame->getController() );
130 catch( const Exception& )
133 // Avoid flickering on context change
134 bPopupMode = true;
137 // Create VCL based toolbar which will be filled with settings data
138 VclPtr<ToolBox> pToolBar;
139 rtl::Reference<ToolBarManager> pToolBarManager;
140 if ( aContextPart.isEmpty() )
142 SolarMutexGuard aSolarMutexGuard;
143 if ( !xParentWindow.is() )
144 xParentWindow.set( xFrame->getContainerWindow() );
145 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xParentWindow );
146 if ( pWindow )
148 sal_uLong nStyles = WB_BORDER | WB_SCROLL | WB_MOVEABLE | WB_3DLOOK | WB_DOCKABLE | WB_SIZEABLE | WB_CLOSEABLE;
150 pToolBar = VclPtr<ToolBox>::Create( pWindow, nStyles );
151 pToolBar->SetLineSpacing(true);
152 pToolBarManager = new ToolBarManager( m_xContext, xFrame, m_aResourceURL, pToolBar );
153 m_xToolBarManager = pToolBarManager;
154 pToolBar->WillUsePopupMode( bPopupMode );
156 else if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xParentWindow.get()))
158 m_xBuilder = Application::CreateBuilder(pTunnel->getWidget(), "svt/ui/managedtoolbar.ui");
159 m_xTopLevel = m_xBuilder->weld_container("toolbarcontainer");
160 m_xWeldedToolbar = m_xBuilder->weld_toolbar("managedtoolbar");
161 if ( m_xWeldedToolbar )
163 pToolBarManager = new ToolBarManager( m_xContext, xFrame, m_aResourceURL, m_xWeldedToolbar.get(), m_xBuilder.get() );
164 m_xToolBarManager = pToolBarManager;
171 m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
172 if ( m_xConfigData.is() && (pToolBar || m_xWeldedToolbar) && pToolBarManager )
174 // Fill toolbar with container contents
175 impl_fillNewData();
176 if (pToolBar)
178 pToolBar->EnableCustomize();
179 ::Size aActSize( pToolBar->GetSizePixel() );
180 ::Size aSize( pToolBar->CalcWindowSizePixel() );
181 aSize.setWidth( aActSize.Width() );
182 pToolBar->SetOutputSizePixel( aSize );
186 catch ( const NoSuchElementException& )
188 // No settings in our configuration manager. This means we are
189 // a transient toolbar which has no persistent settings.
190 m_bPersistent = false;
191 if ( pToolBar && pToolBarManager )
193 pToolBar->EnableCustomize();
194 ::Size aActSize( pToolBar->GetSizePixel() );
195 ::Size aSize( pToolBar->CalcWindowSizePixel() );
196 aSize.setWidth( aActSize.Width() );
197 pToolBar->SetOutputSizePixel( aSize );
202 // XEventListener
203 void SAL_CALL ToolBarWrapper::disposing( const css::lang::EventObject& aEvent )
205 if ( aEvent.Source == m_xSubElement )
206 m_xSubElement.clear();
209 // XUpdatable
210 void SAL_CALL ToolBarWrapper::update()
212 SolarMutexGuard g;
214 if ( m_bDisposed )
215 throw DisposedException();
217 if ( m_xToolBarManager )
218 m_xToolBarManager->CheckAndUpdateImages();
221 // XUIElementSettings
222 void SAL_CALL ToolBarWrapper::updateSettings()
224 SolarMutexGuard g;
226 if ( m_bDisposed )
227 throw DisposedException();
229 if ( m_xConfigSource.is() && m_bPersistent )
233 m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
234 if ( m_xConfigData.is() )
235 impl_fillNewData();
237 catch ( const NoSuchElementException& )
241 auto pContainer( m_aListenerContainer.getContainer( cppu::UnoType< XEventListener >::get() ) );
242 if ( pContainer )
243 pContainer->forEach< XUIElementSettings >([]( const Reference<XUIElementSettings>& xListener ){ xListener->updateSettings(); });
245 else if ( !m_bPersistent )
247 // Transient toolbar: do nothing
251 void ToolBarWrapper::impl_fillNewData()
253 if ( m_xToolBarManager )
255 Reference< XUIElementSettings > xUIElementSettings( m_xSubElement, UNO_QUERY );
256 Reference< XIndexAccess > xContextData = xUIElementSettings.is() ? xUIElementSettings->getSettings( false ) : nullptr;
257 OUString aContextToolbar = xContextData.is() ? m_xSubElement->getResourceURL() : OUString();
258 m_xToolBarManager->FillToolbar( m_xConfigData, xContextData, aContextToolbar );
262 //XContextChangeEventListener
263 void SAL_CALL ToolBarWrapper::notifyContextChangeEvent( const ContextChangeEventObject& aEvent )
265 SolarMutexGuard g;
267 if ( m_bDisposed )
268 throw DisposedException();
270 if ( aEvent.ContextName.isEmpty() || aEvent.ContextName == "default" )
271 return;
273 const OUString aContextToolbar( m_aResourceURL + "-" + aEvent.ContextName.toAsciiLowerCase() );
274 if ( m_xSubElement.is() && m_xSubElement->getResourceURL() == aContextToolbar )
275 return;
277 Reference< XComponent > xComponent( m_xSubElement, UNO_QUERY );
278 if ( xComponent.is() )
279 xComponent->removeEventListener( Reference< XUIConfigurationListener >( this ));
280 m_xSubElement.clear();
282 Reference< XLayoutManager > xLayoutManager;
283 Reference< XPropertySet > xPropSet( m_xWeakFrame.get(), UNO_QUERY );
284 if ( xPropSet.is() )
285 xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
286 if ( !xLayoutManager.is() )
287 return;
289 xLayoutManager->createElement( aContextToolbar );
290 m_xSubElement.set( xLayoutManager->getElement( aContextToolbar ) );
291 xComponent.set( m_xSubElement, UNO_QUERY );
292 if ( xComponent.is() )
293 xComponent->addEventListener( Reference< XUIConfigurationListener >( this ));
295 if ( m_xConfigData.is() )
297 xLayoutManager->lock();
298 impl_fillNewData();
299 xLayoutManager->unlock();
303 // XUIElement interface
304 Reference< XInterface > SAL_CALL ToolBarWrapper::getRealInterface( )
306 SolarMutexGuard g;
308 if ( m_xToolBarManager )
310 vcl::Window* pWindow = m_xToolBarManager->GetToolBar();
311 return Reference< XInterface >( VCLUnoHelper::GetInterface( pWindow ), UNO_QUERY );
314 return Reference< XInterface >();
317 //XUIFunctionExecute
318 void SAL_CALL ToolBarWrapper::functionExecute(
319 const OUString& aUIElementName,
320 const OUString& aCommand )
322 SolarMutexGuard g;
324 if ( m_xToolBarManager )
325 m_xToolBarManager->notifyRegisteredControllers( aUIElementName, aCommand );
328 void SAL_CALL ToolBarWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& aValue )
330 SolarMutexResettableGuard aLock;
331 bool bNoClose( m_bNoClose );
332 aLock.clear();
334 UIConfigElementWrapperBase::setFastPropertyValue_NoBroadcast( nHandle, aValue );
336 aLock.reset();
338 bool bNewNoClose( m_bNoClose );
339 if ( !(m_xToolBarManager.is() && !m_bDisposed && ( bNewNoClose != bNoClose )))
340 return;
342 if ( !m_xToolBarManager )
343 return;
345 ToolBox* pToolBox = m_xToolBarManager->GetToolBar();
346 if ( !pToolBox )
347 return;
349 if ( bNewNoClose )
351 pToolBox->SetStyle( pToolBox->GetStyle() & ~WB_CLOSEABLE );
352 pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
354 else
356 pToolBox->SetStyle( pToolBox->GetStyle() | WB_CLOSEABLE );
357 pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() | WB_CLOSEABLE );
361 } // namespace framework
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */