LibreOffice Module framework (master) 1
toolbarwrapper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
22
23#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
24#include <com/sun/star/ui/UIElementType.hpp>
25#include <com/sun/star/lang/DisposedException.hpp>
26
28
29#include <vcl/svapp.hxx>
30#include <vcl/toolbox.hxx>
31#include <vcl/weldutils.hxx>
32
33using namespace com::sun::star;
34using namespace com::sun::star::uno;
35using namespace com::sun::star::beans;
36using namespace com::sun::star::frame;
37using namespace com::sun::star::lang;
38using namespace com::sun::star::container;
39using namespace com::sun::star::awt;
40using namespace ::com::sun::star::ui;
41
42namespace framework
43{
44
46 ImplInheritanceHelper( UIElementType::TOOLBAR ),
47 m_xContext( rxContext )
48{
49}
50
52{
53 m_xWeldedToolbar.reset(nullptr);
54 m_xTopLevel.reset(nullptr);
55 m_xBuilder.reset(nullptr);
56}
57
58// XComponent
60{
61 Reference< XComponent > xThis(this);
62
63 {
65 if ( m_bDisposed )
66 return;
67 }
68
69 css::lang::EventObject aEvent( xThis );
70 m_aListenerContainer.disposeAndClear( aEvent );
71
73
74 auto xMultiplexer( ContextChangeEventMultiplexer::get( m_xContext ) );
75 xMultiplexer->removeAllContextChangeEventListeners( this );
76
77 Reference< XComponent > xComponent( m_xSubElement, UNO_QUERY );
78 if ( xComponent.is() )
79 xComponent->removeEventListener( Reference< XUIConfigurationListener >( this ));
80 m_xSubElement.clear();
81
82 if ( m_xToolBarManager.is() )
83 m_xToolBarManager->dispose();
84 m_xToolBarManager.clear();
85 m_xConfigSource.clear();
86 m_xConfigData.clear();
87
88 m_bDisposed = true;
89}
90
91// XInitialization
92void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments )
93{
95
96 if ( m_bDisposed )
97 throw DisposedException();
98
99 if ( m_bInitialized )
100 return;
101
103
104 bool bPopupMode( false );
105 Reference< XWindow > xParentWindow;
106 for ( Any const & arg : aArguments )
107 {
108 PropertyValue aPropValue;
109 if ( arg >>= aPropValue )
110 {
111 if ( aPropValue.Name == "PopupMode" )
112 aPropValue.Value >>= bPopupMode;
113 else if ( aPropValue.Name == "ParentWindow" )
114 xParentWindow.set( aPropValue.Value, UNO_QUERY );
115 }
116 }
117
118 Reference< XFrame > xFrame( m_xWeakFrame );
119 if ( !(xFrame.is() && m_xConfigSource.is()) )
120 return;
121
122 OUString aContextPart;
123 if ( m_aResourceURL.startsWith( "private:resource/toolbar/singlemode", &aContextPart ) && aContextPart.isEmpty() )
124 {
125 auto xMultiplexer( ContextChangeEventMultiplexer::get( m_xContext ) );
126 try
127 {
128 xMultiplexer->addContextChangeEventListener( this, xFrame->getController() );
129 }
130 catch( const Exception& )
131 {
132 }
133 // Avoid flickering on context change
134 bPopupMode = true;
135 }
136
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() )
141 {
142 SolarMutexGuard aSolarMutexGuard;
143 if ( !xParentWindow.is() )
144 xParentWindow.set( xFrame->getContainerWindow() );
145 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xParentWindow );
146 if ( pWindow )
147 {
149
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 );
155 }
156 else if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xParentWindow.get()))
157 {
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 )
162 {
163 pToolBarManager = new ToolBarManager( m_xContext, xFrame, m_aResourceURL, m_xWeldedToolbar.get(), m_xBuilder.get() );
164 m_xToolBarManager = pToolBarManager;
165 }
166 }
167 }
168
169 try
170 {
171 m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
172 if ( m_xConfigData.is() && (pToolBar || m_xWeldedToolbar) && pToolBarManager )
173 {
174 // Fill toolbar with container contents
176 if (pToolBar)
177 {
178 pToolBar->EnableCustomize();
179 ::Size aActSize( pToolBar->GetSizePixel() );
180 ::Size aSize( pToolBar->CalcWindowSizePixel() );
181 aSize.setWidth( aActSize.Width() );
182 pToolBar->SetOutputSizePixel( aSize );
183 }
184 }
185 }
186 catch ( const NoSuchElementException& )
187 {
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 )
192 {
193 pToolBar->EnableCustomize();
194 ::Size aActSize( pToolBar->GetSizePixel() );
195 ::Size aSize( pToolBar->CalcWindowSizePixel() );
196 aSize.setWidth( aActSize.Width() );
197 pToolBar->SetOutputSizePixel( aSize );
198 }
199 }
200}
201
202// XEventListener
203void SAL_CALL ToolBarWrapper::disposing( const css::lang::EventObject& aEvent )
204{
205 if ( aEvent.Source == m_xSubElement )
206 m_xSubElement.clear();
207}
208
209// XUpdatable
211{
213
214 if ( m_bDisposed )
215 throw DisposedException();
216
217 ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
218 if ( pToolBarManager )
219 pToolBarManager->CheckAndUpdateImages();
220}
221
222// XUIElementSettings
224{
226
227 if ( m_bDisposed )
228 throw DisposedException();
229
230 if ( m_xConfigSource.is() && m_bPersistent )
231 {
232 try
233 {
234 m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
235 if ( m_xConfigData.is() )
237 }
238 catch ( const NoSuchElementException& )
239 {
240 }
241
242 auto pContainer( m_aListenerContainer.getContainer( cppu::UnoType< XEventListener >::get() ) );
243 if ( pContainer )
244 pContainer->forEach< XUIElementSettings >([]( const Reference<XUIElementSettings>& xListener ){ xListener->updateSettings(); });
245 }
246 else if ( !m_bPersistent )
247 {
248 // Transient toolbar: do nothing
249 }
250}
251
253{
254 ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
255 if ( pToolBarManager )
256 {
257 Reference< XUIElementSettings > xUIElementSettings( m_xSubElement, UNO_QUERY );
258 Reference< XIndexAccess > xContextData = xUIElementSettings.is() ? xUIElementSettings->getSettings( false ) : nullptr;
259 OUString aContextToolbar = xContextData.is() ? m_xSubElement->getResourceURL() : OUString();
260 pToolBarManager->FillToolbar( m_xConfigData, xContextData, aContextToolbar );
261 }
262}
263
264//XContextChangeEventListener
265void SAL_CALL ToolBarWrapper::notifyContextChangeEvent( const ContextChangeEventObject& aEvent )
266{
268
269 if ( m_bDisposed )
270 throw DisposedException();
271
272 if ( aEvent.ContextName.isEmpty() || aEvent.ContextName == "default" )
273 return;
274
275 const OUString aContextToolbar( m_aResourceURL + "-" + aEvent.ContextName.toAsciiLowerCase() );
276 if ( m_xSubElement.is() && m_xSubElement->getResourceURL() == aContextToolbar )
277 return;
278
279 Reference< XComponent > xComponent( m_xSubElement, UNO_QUERY );
280 if ( xComponent.is() )
281 xComponent->removeEventListener( Reference< XUIConfigurationListener >( this ));
282 m_xSubElement.clear();
283
284 Reference< XLayoutManager > xLayoutManager;
285 Reference< XPropertySet > xPropSet( m_xWeakFrame.get(), UNO_QUERY );
286 if ( xPropSet.is() )
287 xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
288 if ( !xLayoutManager.is() )
289 return;
290
291 xLayoutManager->createElement( aContextToolbar );
292 m_xSubElement.set( xLayoutManager->getElement( aContextToolbar ) );
293 xComponent.set( m_xSubElement, UNO_QUERY );
294 if ( xComponent.is() )
295 xComponent->addEventListener( Reference< XUIConfigurationListener >( this ));
296
297 if ( m_xConfigData.is() )
298 {
299 xLayoutManager->lock();
301 xLayoutManager->unlock();
302 }
303}
304
305// XUIElement interface
307{
309
310 if ( m_xToolBarManager.is() )
311 {
312 ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
313 if ( pToolBarManager )
314 {
315 vcl::Window* pWindow = pToolBarManager->GetToolBar();
316 return Reference< XInterface >( VCLUnoHelper::GetInterface( pWindow ), UNO_QUERY );
317 }
318 }
319
321}
322
323//XUIFunctionExecute
325 const OUString& aUIElementName,
326 const OUString& aCommand )
327{
329
330 if ( m_xToolBarManager.is() )
331 {
332 ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
333 if ( pToolBarManager )
334 pToolBarManager->notifyRegisteredControllers( aUIElementName, aCommand );
335 }
336}
337
338void SAL_CALL ToolBarWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& aValue )
339{
341 bool bNoClose( m_bNoClose );
342 aLock.clear();
343
345
346 aLock.reset();
347
348 bool bNewNoClose( m_bNoClose );
349 if ( !(m_xToolBarManager.is() && !m_bDisposed && ( bNewNoClose != bNoClose )))
350 return;
351
352 ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
353 if ( !pToolBarManager )
354 return;
355
356 ToolBox* pToolBox = pToolBarManager->GetToolBar();
357 if ( !pToolBox )
358 return;
359
360 if ( bNewNoClose )
361 {
362 pToolBox->SetStyle( pToolBox->GetStyle() & ~WB_CLOSEABLE );
363 pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
364 }
365 else
366 {
367 pToolBox->SetStyle( pToolBox->GetStyle() | WB_CLOSEABLE );
368 pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() | WB_CLOSEABLE );
369 }
370}
371
372} // namespace framework
373
374/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
void SetFloatStyle(WinBits nWinStyle)
WinBits GetFloatStyle() const
void setWidth(tools::Long nWidth)
constexpr tools::Long Width() const
void SetStyle(WinBits nNewStyle)
WinBits GetStyle() const
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
static VclPtr< reference_type > Create(Arg &&... arg)
void notifyRegisteredControllers(const OUString &aUIElementName, const OUString &aCommand)
void FillToolbar(const css::uno::Reference< css::container::XIndexAccess > &rToolBarData, const css::uno::Reference< css::container::XIndexAccess > &rContextData, const OUString &rContextToolbarName)
ToolBox * GetToolBar() const
css::uno::Reference< css::lang::XComponent > m_xToolBarManager
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &aValue) override
std::unique_ptr< weld::Builder > m_xBuilder
ToolBarWrapper(const css::uno::Reference< css::uno::XComponentContext > &xContext)
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getRealInterface() override
virtual void SAL_CALL updateSettings() override
std::unique_ptr< weld::Toolbar > m_xWeldedToolbar
virtual void SAL_CALL functionExecute(const OUString &aUIElementName, const OUString &aCommand) override
virtual void SAL_CALL dispose() override
virtual void SAL_CALL disposing(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
virtual ~ToolBarWrapper() override
std::unique_ptr< weld::Container > m_xTopLevel
virtual void SAL_CALL update() override
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Reference< css::ui::XUIElement > m_xSubElement
virtual void impl_fillNewData() override
virtual void SAL_CALL notifyContextChangeEvent(const css::ui::ContextChangeEventObject &aEvent) override
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &aValue) override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
bool m_bDisposed
Sequence< PropertyValue > aArguments
@ Exception
sal_Int32 nHandle
sal_uIntPtr sal_uLong
Reference< XFrame > xFrame
OUString aCommand
WinBits const WB_CLOSEABLE
WinBits const WB_MOVEABLE
WinBits const WB_DOCKABLE
WinBits const WB_SIZEABLE
WinBits const WB_3DLOOK
WinBits const WB_BORDER
WinBits const WB_SCROLL