File: | home/maarten/src/libreoffice/core/framework/source/layoutmanager/toolbarlayoutmanager.cxx |
Warning: | line 3069, column 25 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||||||||||
20 | #include "toolbarlayoutmanager.hxx" | ||||||||||||
21 | #include <uiconfiguration/windowstateproperties.hxx> | ||||||||||||
22 | #include <uielement/addonstoolbarwrapper.hxx> | ||||||||||||
23 | #include "helpers.hxx" | ||||||||||||
24 | #include <services/layoutmanager.hxx> | ||||||||||||
25 | #include <strings.hrc> | ||||||||||||
26 | #include <classes/fwkresid.hxx> | ||||||||||||
27 | |||||||||||||
28 | #include <com/sun/star/awt/PosSize.hpp> | ||||||||||||
29 | #include <com/sun/star/beans/XPropertySet.hpp> | ||||||||||||
30 | #include <com/sun/star/ui/UIElementType.hpp> | ||||||||||||
31 | #include <com/sun/star/container/XNameReplace.hpp> | ||||||||||||
32 | #include <com/sun/star/container/XNameContainer.hpp> | ||||||||||||
33 | #include <com/sun/star/ui/XUIElementSettings.hpp> | ||||||||||||
34 | #include <com/sun/star/ui/XUIFunctionListener.hpp> | ||||||||||||
35 | |||||||||||||
36 | #include <cppuhelper/queryinterface.hxx> | ||||||||||||
37 | #include <unotools/cmdoptions.hxx> | ||||||||||||
38 | #include <toolkit/helper/vclunohelper.hxx> | ||||||||||||
39 | #include <toolkit/helper/convert.hxx> | ||||||||||||
40 | #include <vcl/i18nhelp.hxx> | ||||||||||||
41 | #include <vcl/dockingarea.hxx> | ||||||||||||
42 | #include <vcl/settings.hxx> | ||||||||||||
43 | #include <vcl/svapp.hxx> | ||||||||||||
44 | #include <sal/log.hxx> | ||||||||||||
45 | #include <tools/gen.hxx> | ||||||||||||
46 | |||||||||||||
47 | |||||||||||||
48 | using namespace ::com::sun::star; | ||||||||||||
49 | |||||||||||||
50 | namespace framework | ||||||||||||
51 | { | ||||||||||||
52 | |||||||||||||
53 | ToolbarLayoutManager::ToolbarLayoutManager( | ||||||||||||
54 | const uno::Reference< uno::XComponentContext >& rxContext, | ||||||||||||
55 | const uno::Reference< ui::XUIElementFactory >& xUIElementFactory, | ||||||||||||
56 | LayoutManager* pParentLayouter ): | ||||||||||||
57 | m_xContext( rxContext), | ||||||||||||
58 | m_xUIElementFactoryManager( xUIElementFactory ), | ||||||||||||
59 | m_pParentLayouter( pParentLayouter ), | ||||||||||||
60 | m_eDockOperation( DOCKOP_ON_COLROW ), | ||||||||||||
61 | m_ePreviewDetection( PREVIEWFRAME_UNKNOWN ), | ||||||||||||
62 | m_bComponentAttached( false ), | ||||||||||||
63 | m_bLayoutDirty( false ), | ||||||||||||
64 | m_bGlobalSettings( false ), | ||||||||||||
65 | m_bDockingInProgress( false ), | ||||||||||||
66 | m_bLayoutInProgress( false ), | ||||||||||||
67 | m_bToolbarCreation( false ) | ||||||||||||
68 | { | ||||||||||||
69 | // initialize rectangles to zero values | ||||||||||||
70 | setZeroRectangle( m_aDockingAreaOffsets ); | ||||||||||||
71 | setZeroRectangle( m_aDockingArea ); | ||||||||||||
72 | } | ||||||||||||
73 | |||||||||||||
74 | ToolbarLayoutManager::~ToolbarLayoutManager() | ||||||||||||
75 | { | ||||||||||||
76 | m_pGlobalSettings.reset(); | ||||||||||||
77 | m_pAddonOptions.reset(); | ||||||||||||
78 | } | ||||||||||||
79 | |||||||||||||
80 | // XInterface | ||||||||||||
81 | |||||||||||||
82 | void SAL_CALL ToolbarLayoutManager::acquire() throw() | ||||||||||||
83 | { | ||||||||||||
84 | OWeakObject::acquire(); | ||||||||||||
85 | } | ||||||||||||
86 | |||||||||||||
87 | void SAL_CALL ToolbarLayoutManager::release() throw() | ||||||||||||
88 | { | ||||||||||||
89 | OWeakObject::release(); | ||||||||||||
90 | } | ||||||||||||
91 | |||||||||||||
92 | uno::Any SAL_CALL ToolbarLayoutManager::queryInterface( const uno::Type & rType ) | ||||||||||||
93 | { | ||||||||||||
94 | uno::Any a = ::cppu::queryInterface( rType, | ||||||||||||
95 | static_cast< awt::XDockableWindowListener* >(this), | ||||||||||||
96 | static_cast< ui::XUIConfigurationListener* >(this), | ||||||||||||
97 | static_cast< awt::XWindowListener* >(this)); | ||||||||||||
98 | |||||||||||||
99 | if ( a.hasValue() ) | ||||||||||||
100 | return a; | ||||||||||||
101 | |||||||||||||
102 | return OWeakObject::queryInterface( rType ); | ||||||||||||
103 | } | ||||||||||||
104 | |||||||||||||
105 | void SAL_CALL ToolbarLayoutManager::disposing( const lang::EventObject& aEvent ) | ||||||||||||
106 | { | ||||||||||||
107 | if ( aEvent.Source == m_xFrame ) | ||||||||||||
108 | { | ||||||||||||
109 | // Reset all internal references | ||||||||||||
110 | reset(); | ||||||||||||
111 | implts_destroyDockingAreaWindows(); | ||||||||||||
112 | } | ||||||||||||
113 | } | ||||||||||||
114 | |||||||||||||
115 | awt::Rectangle ToolbarLayoutManager::getDockingArea() | ||||||||||||
116 | { | ||||||||||||
117 | SolarMutexResettableGuard aWriteLock; | ||||||||||||
118 | tools::Rectangle aNewDockingArea( m_aDockingArea ); | ||||||||||||
119 | aWriteLock.clear(); | ||||||||||||
120 | |||||||||||||
121 | if ( isLayoutDirty() ) | ||||||||||||
122 | aNewDockingArea = implts_calcDockingArea(); | ||||||||||||
123 | |||||||||||||
124 | aWriteLock.reset(); | ||||||||||||
125 | m_aDockingArea = aNewDockingArea; | ||||||||||||
126 | aWriteLock.clear(); | ||||||||||||
127 | |||||||||||||
128 | return putRectangleValueToAWT(aNewDockingArea); | ||||||||||||
129 | } | ||||||||||||
130 | |||||||||||||
131 | void ToolbarLayoutManager::setDockingArea( const awt::Rectangle& rDockingArea ) | ||||||||||||
132 | { | ||||||||||||
133 | SolarMutexGuard g; | ||||||||||||
134 | m_aDockingArea = putAWTToRectangle( rDockingArea ); | ||||||||||||
135 | m_bLayoutDirty = true; | ||||||||||||
136 | } | ||||||||||||
137 | |||||||||||||
138 | void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& rBorderSpace ) | ||||||||||||
139 | { | ||||||||||||
140 | SolarMutexClearableGuard aReadLock; | ||||||||||||
141 | tools::Rectangle aDockOffsets = m_aDockingAreaOffsets; | ||||||||||||
142 | uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); | ||||||||||||
143 | uno::Reference< awt::XWindow > xTopDockAreaWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] ); | ||||||||||||
144 | uno::Reference< awt::XWindow > xBottomDockAreaWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)] ); | ||||||||||||
145 | uno::Reference< awt::XWindow > xLeftDockAreaWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] ); | ||||||||||||
146 | uno::Reference< awt::XWindow > xRightDockAreaWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)] ); | ||||||||||||
147 | aReadLock.clear(); | ||||||||||||
148 | |||||||||||||
149 | uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY ); | ||||||||||||
150 | |||||||||||||
151 | // Convert relative size to output size. | ||||||||||||
152 | awt::Rectangle aRectangle = xContainerWindow->getPosSize(); | ||||||||||||
153 | awt::DeviceInfo aInfo = xDevice->getInfo(); | ||||||||||||
154 | awt::Size aContainerClientSize( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , | ||||||||||||
155 | aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); | ||||||||||||
156 | long aStatusBarHeight = aDockOffsets.GetHeight(); | ||||||||||||
157 | |||||||||||||
158 | sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height ); | ||||||||||||
159 | if ( rBorderSpace.Y >= 0 ) | ||||||||||||
160 | { | ||||||||||||
161 | // Top docking area window | ||||||||||||
162 | xTopDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, awt::PosSize::POSSIZE ); | ||||||||||||
163 | xTopDockAreaWindow->setVisible( true ); | ||||||||||||
164 | nLeftRightDockingAreaHeight -= rBorderSpace.Y; | ||||||||||||
165 | } | ||||||||||||
166 | |||||||||||||
167 | if ( rBorderSpace.Height >= 0 ) | ||||||||||||
168 | { | ||||||||||||
169 | // Bottom docking area window | ||||||||||||
170 | sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarHeight + 1 ), sal_Int32( 0 )); | ||||||||||||
171 | sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height; | ||||||||||||
172 | |||||||||||||
173 | xBottomDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, awt::PosSize::POSSIZE ); | ||||||||||||
174 | xBottomDockAreaWindow->setVisible( true ); | ||||||||||||
175 | nLeftRightDockingAreaHeight -= nHeight - 1; | ||||||||||||
176 | } | ||||||||||||
177 | |||||||||||||
178 | nLeftRightDockingAreaHeight -= aStatusBarHeight; | ||||||||||||
179 | if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 ) | ||||||||||||
180 | { | ||||||||||||
181 | // Left docking area window | ||||||||||||
182 | // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! | ||||||||||||
183 | sal_Int32 nHeight = std::max<sal_Int32>( 0, nLeftRightDockingAreaHeight ); | ||||||||||||
184 | |||||||||||||
185 | xLeftDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, awt::PosSize::POSSIZE ); | ||||||||||||
186 | xLeftDockAreaWindow->setVisible( true ); | ||||||||||||
187 | } | ||||||||||||
188 | if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 ) | ||||||||||||
189 | { | ||||||||||||
190 | // Right docking area window | ||||||||||||
191 | // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! | ||||||||||||
192 | sal_Int32 nLeftPos = std::max<sal_Int32>( 0, aContainerClientSize.Width - rBorderSpace.Width ); | ||||||||||||
193 | sal_Int32 nHeight = std::max<sal_Int32>( 0, nLeftRightDockingAreaHeight ); | ||||||||||||
194 | sal_Int32 nWidth = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width; | ||||||||||||
195 | |||||||||||||
196 | xRightDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, awt::PosSize::POSSIZE ); | ||||||||||||
197 | xRightDockAreaWindow->setVisible( true ); | ||||||||||||
198 | } | ||||||||||||
199 | } | ||||||||||||
200 | |||||||||||||
201 | |||||||||||||
202 | void ToolbarLayoutManager::doLayout(const ::Size& aContainerSize) | ||||||||||||
203 | { | ||||||||||||
204 | SolarMutexResettableGuard aWriteLock; | ||||||||||||
205 | bool bLayoutInProgress( m_bLayoutInProgress ); | ||||||||||||
206 | m_bLayoutInProgress = true; | ||||||||||||
207 | awt::Rectangle aDockingArea = putRectangleValueToAWT( m_aDockingArea ); | ||||||||||||
208 | aWriteLock.clear(); | ||||||||||||
209 | |||||||||||||
210 | if ( bLayoutInProgress ) | ||||||||||||
211 | return; | ||||||||||||
212 | |||||||||||||
213 | // Retrieve row/column dependent data from all docked user-interface elements | ||||||||||||
214 | for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ ) | ||||||||||||
215 | { | ||||||||||||
216 | bool bReverse( isReverseOrderDockingArea( i )); | ||||||||||||
217 | std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; | ||||||||||||
218 | |||||||||||||
219 | implts_getDockingAreaElementInfos( static_cast<ui::DockingArea>(i), aRowColumnsWindowData ); | ||||||||||||
220 | |||||||||||||
221 | sal_Int32 nOffset( 0 ); | ||||||||||||
222 | const sal_uInt32 nCount = aRowColumnsWindowData.size(); | ||||||||||||
223 | for ( sal_uInt32 j = 0; j < nCount; ++j ) | ||||||||||||
224 | { | ||||||||||||
225 | sal_uInt32 nIndex = bReverse ? nCount-j-1 : j; | ||||||||||||
226 | implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[nIndex], aContainerSize ); | ||||||||||||
227 | nOffset += aRowColumnsWindowData[j].nStaticSize; | ||||||||||||
228 | } | ||||||||||||
229 | } | ||||||||||||
230 | |||||||||||||
231 | implts_setDockingAreaWindowSizes( aDockingArea ); | ||||||||||||
232 | |||||||||||||
233 | aWriteLock.reset(); | ||||||||||||
234 | m_bLayoutDirty = false; | ||||||||||||
235 | m_bLayoutInProgress = false; | ||||||||||||
236 | aWriteLock.clear(); | ||||||||||||
237 | } | ||||||||||||
238 | |||||||||||||
239 | bool ToolbarLayoutManager::implts_isParentWindowVisible() const | ||||||||||||
240 | { | ||||||||||||
241 | SolarMutexGuard g; | ||||||||||||
242 | bool bVisible( false ); | ||||||||||||
243 | if ( m_xContainerWindow.is() ) | ||||||||||||
244 | bVisible = m_xContainerWindow->isVisible(); | ||||||||||||
245 | |||||||||||||
246 | return bVisible; | ||||||||||||
247 | } | ||||||||||||
248 | |||||||||||||
249 | tools::Rectangle ToolbarLayoutManager::implts_calcDockingArea() | ||||||||||||
250 | { | ||||||||||||
251 | SolarMutexClearableGuard aReadLock; | ||||||||||||
252 | UIElementVector aWindowVector( m_aUIElements ); | ||||||||||||
253 | aReadLock.clear(); | ||||||||||||
254 | |||||||||||||
255 | tools::Rectangle aBorderSpace; | ||||||||||||
256 | sal_Int32 nCurrRowColumn( 0 ); | ||||||||||||
257 | sal_Int32 nCurrPos( 0 ); | ||||||||||||
258 | ui::DockingArea nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP ); | ||||||||||||
259 | std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT]; | ||||||||||||
260 | |||||||||||||
261 | // initialize rectangle with zero values! | ||||||||||||
262 | aBorderSpace.setWidth(0); | ||||||||||||
263 | aBorderSpace.setHeight(0); | ||||||||||||
264 | |||||||||||||
265 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)].clear(); | ||||||||||||
266 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)].push_back( 0 ); | ||||||||||||
267 | |||||||||||||
268 | for (auto const& window : aWindowVector) | ||||||||||||
269 | { | ||||||||||||
270 | if ( window.m_xUIElement.is() ) | ||||||||||||
271 | { | ||||||||||||
272 | uno::Reference< awt::XWindow > xWindow( window.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
273 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
274 | if ( xWindow.is() && xDockWindow.is() ) | ||||||||||||
275 | { | ||||||||||||
276 | SolarMutexGuard aGuard; | ||||||||||||
277 | |||||||||||||
278 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
279 | if ( pWindow && !xDockWindow->isFloating() && window.m_bVisible && !window.m_bMasterHide ) | ||||||||||||
280 | { | ||||||||||||
281 | awt::Rectangle aPosSize = xWindow->getPosSize(); | ||||||||||||
282 | if ( window.m_aDockedData.m_nDockedArea != nCurrDockingArea ) | ||||||||||||
283 | { | ||||||||||||
284 | nCurrDockingArea = window.m_aDockedData.m_nDockedArea; | ||||||||||||
285 | nCurrRowColumn = 0; | ||||||||||||
286 | nCurrPos = 0; | ||||||||||||
287 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)].clear(); | ||||||||||||
288 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)].push_back( 0 ); | ||||||||||||
289 | } | ||||||||||||
290 | |||||||||||||
291 | if ( window.m_aDockedData.m_nDockedArea == nCurrDockingArea ) | ||||||||||||
292 | { | ||||||||||||
293 | if ( isHorizontalDockingArea( window.m_aDockedData.m_nDockedArea )) | ||||||||||||
294 | { | ||||||||||||
295 | if ( window.m_aDockedData.m_aPos.Y > nCurrPos ) | ||||||||||||
296 | { | ||||||||||||
297 | ++nCurrRowColumn; | ||||||||||||
298 | nCurrPos = window.m_aDockedData.m_aPos.Y; | ||||||||||||
299 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)].push_back( 0 ); | ||||||||||||
300 | } | ||||||||||||
301 | |||||||||||||
302 | if ( aPosSize.Height > aRowColumnSizes[static_cast<int>(nCurrDockingArea)][nCurrRowColumn] ) | ||||||||||||
303 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)][nCurrRowColumn] = aPosSize.Height; | ||||||||||||
304 | } | ||||||||||||
305 | else | ||||||||||||
306 | { | ||||||||||||
307 | if ( window.m_aDockedData.m_aPos.X > nCurrPos ) | ||||||||||||
308 | { | ||||||||||||
309 | ++nCurrRowColumn; | ||||||||||||
310 | nCurrPos = window.m_aDockedData.m_aPos.X; | ||||||||||||
311 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)].push_back( 0 ); | ||||||||||||
312 | } | ||||||||||||
313 | |||||||||||||
314 | if ( aPosSize.Width > aRowColumnSizes[static_cast<int>(nCurrDockingArea)][nCurrRowColumn] ) | ||||||||||||
315 | aRowColumnSizes[static_cast<int>(nCurrDockingArea)][nCurrRowColumn] = aPosSize.Width; | ||||||||||||
316 | } | ||||||||||||
317 | } | ||||||||||||
318 | } | ||||||||||||
319 | } | ||||||||||||
320 | } | ||||||||||||
321 | } | ||||||||||||
322 | |||||||||||||
323 | // Sum up max heights from every row/column | ||||||||||||
324 | if ( !aWindowVector.empty() ) | ||||||||||||
325 | { | ||||||||||||
326 | for ( sal_Int32 i = 0; i <= sal_Int32(ui::DockingArea_DOCKINGAREA_RIGHT); i++ ) | ||||||||||||
327 | { | ||||||||||||
328 | sal_Int32 nSize( 0 ); | ||||||||||||
329 | const sal_uInt32 nCount = aRowColumnSizes[i].size(); | ||||||||||||
330 | for ( sal_uInt32 j = 0; j < nCount; j++ ) | ||||||||||||
331 | nSize += aRowColumnSizes[i][j]; | ||||||||||||
332 | |||||||||||||
333 | if ( i == sal_Int32(ui::DockingArea_DOCKINGAREA_TOP) ) | ||||||||||||
334 | aBorderSpace.SetTop( nSize ); | ||||||||||||
335 | else if ( i == sal_Int32(ui::DockingArea_DOCKINGAREA_BOTTOM) ) | ||||||||||||
336 | aBorderSpace.SetBottom( nSize ); | ||||||||||||
337 | else if ( i == sal_Int32(ui::DockingArea_DOCKINGAREA_LEFT) ) | ||||||||||||
338 | aBorderSpace.SetLeft( nSize ); | ||||||||||||
339 | else | ||||||||||||
340 | aBorderSpace.SetRight( nSize ); | ||||||||||||
341 | } | ||||||||||||
342 | } | ||||||||||||
343 | |||||||||||||
344 | return aBorderSpace; | ||||||||||||
345 | } | ||||||||||||
346 | |||||||||||||
347 | void ToolbarLayoutManager::reset() | ||||||||||||
348 | { | ||||||||||||
349 | { | ||||||||||||
350 | SolarMutexGuard aWriteLock; | ||||||||||||
351 | m_xModuleCfgMgr.clear(); | ||||||||||||
352 | m_xDocCfgMgr.clear(); | ||||||||||||
353 | m_ePreviewDetection = PREVIEWFRAME_UNKNOWN; | ||||||||||||
354 | m_bComponentAttached = false; | ||||||||||||
355 | } | ||||||||||||
356 | |||||||||||||
357 | destroyToolbars(); | ||||||||||||
358 | resetDockingArea(); | ||||||||||||
359 | } | ||||||||||||
360 | |||||||||||||
361 | void ToolbarLayoutManager::attach( | ||||||||||||
362 | const uno::Reference< frame::XFrame >& xFrame, | ||||||||||||
363 | const uno::Reference< ui::XUIConfigurationManager >& xModuleCfgMgr, | ||||||||||||
364 | const uno::Reference< ui::XUIConfigurationManager >& xDocCfgMgr, | ||||||||||||
365 | const uno::Reference< container::XNameAccess >& xPersistentWindowState ) | ||||||||||||
366 | { | ||||||||||||
367 | // reset toolbar manager if we lose our current frame | ||||||||||||
368 | if ( m_xFrame.is() && m_xFrame != xFrame ) | ||||||||||||
369 | reset(); | ||||||||||||
370 | |||||||||||||
371 | SolarMutexGuard g; | ||||||||||||
372 | m_xFrame = xFrame; | ||||||||||||
373 | m_xModuleCfgMgr = xModuleCfgMgr; | ||||||||||||
374 | m_xDocCfgMgr = xDocCfgMgr; | ||||||||||||
375 | m_xPersistentWindowState = xPersistentWindowState; | ||||||||||||
376 | m_bComponentAttached = true; | ||||||||||||
377 | } | ||||||||||||
378 | |||||||||||||
379 | bool ToolbarLayoutManager::isPreviewFrame() | ||||||||||||
380 | { | ||||||||||||
381 | SolarMutexGuard g; | ||||||||||||
382 | if (m_ePreviewDetection == PREVIEWFRAME_UNKNOWN) | ||||||||||||
383 | { | ||||||||||||
384 | uno::Reference< frame::XFrame > xFrame( m_xFrame ); | ||||||||||||
385 | |||||||||||||
386 | uno::Reference< frame::XModel > xModel( impl_getModelFromFrame( xFrame )); | ||||||||||||
387 | |||||||||||||
388 | m_ePreviewDetection = (implts_isPreviewModel( xModel ) ? PREVIEWFRAME_YES : PREVIEWFRAME_NO); | ||||||||||||
389 | } | ||||||||||||
390 | return m_ePreviewDetection == PREVIEWFRAME_YES; | ||||||||||||
391 | } | ||||||||||||
392 | |||||||||||||
393 | void ToolbarLayoutManager::createStaticToolbars() | ||||||||||||
394 | { | ||||||||||||
395 | resetDockingArea(); | ||||||||||||
396 | implts_createCustomToolBars(); | ||||||||||||
397 | implts_createAddonsToolBars(); | ||||||||||||
398 | implts_createNonContextSensitiveToolBars(); | ||||||||||||
399 | implts_sortUIElements(); | ||||||||||||
400 | } | ||||||||||||
401 | |||||||||||||
402 | bool ToolbarLayoutManager::requestToolbar( const OUString& rResourceURL ) | ||||||||||||
403 | { | ||||||||||||
404 | if (isPreviewFrame()) | ||||||||||||
405 | return false; // no toolbars for preview frame! | ||||||||||||
406 | |||||||||||||
407 | bool bNotify( false ); | ||||||||||||
408 | bool bMustCallCreate( false ); | ||||||||||||
409 | uno::Reference< ui::XUIElement > xUIElement; | ||||||||||||
410 | |||||||||||||
411 | UIElement aRequestedToolbar = impl_findToolbar( rResourceURL ); | ||||||||||||
412 | if ( aRequestedToolbar.m_aName != rResourceURL ) | ||||||||||||
413 | { | ||||||||||||
414 | bMustCallCreate = true; | ||||||||||||
415 | aRequestedToolbar.m_aName = rResourceURL; | ||||||||||||
416 | aRequestedToolbar.m_aType = UIRESOURCETYPE_TOOLBAR"toolbar"; | ||||||||||||
417 | aRequestedToolbar.m_xUIElement = xUIElement; | ||||||||||||
418 | implts_readWindowStateData( rResourceURL, aRequestedToolbar ); | ||||||||||||
419 | } | ||||||||||||
420 | |||||||||||||
421 | xUIElement = aRequestedToolbar.m_xUIElement; | ||||||||||||
422 | if ( !xUIElement.is() ) | ||||||||||||
423 | bMustCallCreate = true; | ||||||||||||
424 | |||||||||||||
425 | bool bCreateOrShowToolbar( aRequestedToolbar.m_bVisible && !aRequestedToolbar.m_bMasterHide ); | ||||||||||||
426 | |||||||||||||
427 | if ( bCreateOrShowToolbar ) | ||||||||||||
428 | bNotify = bMustCallCreate ? createToolbar( rResourceURL ) : showToolbar( rResourceURL ); | ||||||||||||
429 | |||||||||||||
430 | return bNotify; | ||||||||||||
431 | } | ||||||||||||
432 | |||||||||||||
433 | bool ToolbarLayoutManager::createToolbar( const OUString& rResourceURL ) | ||||||||||||
434 | { | ||||||||||||
435 | bool bNotify( false ); | ||||||||||||
436 | |||||||||||||
437 | uno::Reference<frame::XFrame> xFrame; | ||||||||||||
438 | uno::Reference<awt::XWindow2> xContainerWindow; | ||||||||||||
439 | { | ||||||||||||
440 | SolarMutexGuard aReadLock; | ||||||||||||
441 | xFrame.set(m_xFrame); | ||||||||||||
442 | xContainerWindow.set(m_xContainerWindow); | ||||||||||||
443 | } | ||||||||||||
444 | |||||||||||||
445 | if ( !xFrame.is() || !xContainerWindow.is() ) | ||||||||||||
446 | return false; | ||||||||||||
447 | |||||||||||||
448 | UIElement aToolbarElement = implts_findToolbar( rResourceURL ); | ||||||||||||
449 | if ( !aToolbarElement.m_xUIElement.is() ) | ||||||||||||
450 | { | ||||||||||||
451 | uno::Reference< ui::XUIElement > xUIElement; | ||||||||||||
452 | |||||||||||||
453 | uno::Sequence< beans::PropertyValue > aPropSeq( 2 ); | ||||||||||||
454 | aPropSeq[0].Name = "Frame"; | ||||||||||||
455 | aPropSeq[0].Value <<= xFrame; | ||||||||||||
456 | aPropSeq[1].Name = "Persistent"; | ||||||||||||
457 | aPropSeq[1].Value <<= true; | ||||||||||||
458 | uno::Reference<ui::XUIElementFactory> xUIElementFactory; | ||||||||||||
459 | { | ||||||||||||
460 | SolarMutexGuard aReadLock; | ||||||||||||
461 | xUIElementFactory.set(m_xUIElementFactoryManager); | ||||||||||||
462 | } | ||||||||||||
463 | |||||||||||||
464 | implts_setToolbarCreation(); | ||||||||||||
465 | try | ||||||||||||
466 | { | ||||||||||||
467 | if ( xUIElementFactory.is() ) | ||||||||||||
468 | xUIElement = xUIElementFactory->createUIElement( rResourceURL, aPropSeq ); | ||||||||||||
469 | } | ||||||||||||
470 | catch (const container::NoSuchElementException&) | ||||||||||||
471 | { | ||||||||||||
472 | } | ||||||||||||
473 | catch (const lang::IllegalArgumentException&) | ||||||||||||
474 | { | ||||||||||||
475 | } | ||||||||||||
476 | implts_setToolbarCreation( false ); | ||||||||||||
477 | |||||||||||||
478 | if ( xUIElement.is() ) | ||||||||||||
479 | { | ||||||||||||
480 | uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
481 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
482 | if ( xDockWindow.is() && xWindow.is() ) | ||||||||||||
483 | { | ||||||||||||
484 | try | ||||||||||||
485 | { | ||||||||||||
486 | xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( | ||||||||||||
487 | static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); | ||||||||||||
488 | xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( | ||||||||||||
489 | static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); | ||||||||||||
490 | xDockWindow->enableDocking( true ); | ||||||||||||
491 | } | ||||||||||||
492 | catch (const uno::Exception&) | ||||||||||||
493 | { | ||||||||||||
494 | } | ||||||||||||
495 | } | ||||||||||||
496 | |||||||||||||
497 | bool bVisible = false; | ||||||||||||
498 | bool bFloating = false; | ||||||||||||
499 | |||||||||||||
500 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
501 | { | ||||||||||||
502 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
503 | |||||||||||||
504 | UIElement& rElement = impl_findToolbar(rResourceURL); | ||||||||||||
505 | if (rElement.m_xUIElement.is()) | ||||||||||||
506 | { | ||||||||||||
507 | // somebody else must have created it while we released | ||||||||||||
508 | // the SolarMutex - just dispose our new instance and | ||||||||||||
509 | // do nothing. (We have to dispose either the new or the | ||||||||||||
510 | // existing m_xUIElement.) | ||||||||||||
511 | aWriteLock.clear(); | ||||||||||||
512 | uno::Reference<lang::XComponent> const xC(xUIElement, uno::UNO_QUERY); | ||||||||||||
513 | xC->dispose(); | ||||||||||||
514 | return false; | ||||||||||||
515 | } | ||||||||||||
516 | if (!rElement.m_aName.isEmpty()) | ||||||||||||
517 | { | ||||||||||||
518 | // Reuse a local entry so we are able to use the latest | ||||||||||||
519 | // UI changes for this document. | ||||||||||||
520 | implts_setElementData(rElement, xDockWindow); | ||||||||||||
521 | rElement.m_xUIElement = xUIElement; | ||||||||||||
522 | bVisible = rElement.m_bVisible; | ||||||||||||
523 | bFloating = rElement.m_bFloating; | ||||||||||||
524 | } | ||||||||||||
525 | else | ||||||||||||
526 | { | ||||||||||||
527 | // Create new UI element and try to read its state data | ||||||||||||
528 | UIElement aNewToolbar(rResourceURL, UIRESOURCETYPE_TOOLBAR"toolbar", xUIElement); | ||||||||||||
529 | implts_readWindowStateData(rResourceURL, aNewToolbar); | ||||||||||||
530 | implts_setElementData(aNewToolbar, xDockWindow); | ||||||||||||
531 | implts_insertToolbar(aNewToolbar); | ||||||||||||
532 | bVisible = aNewToolbar.m_bVisible; | ||||||||||||
533 | bFloating = rElement.m_bFloating; | ||||||||||||
534 | } | ||||||||||||
535 | } | ||||||||||||
536 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
537 | |||||||||||||
538 | // set toolbar menu style according to customize command state | ||||||||||||
539 | SvtCommandOptions aCmdOptions; | ||||||||||||
540 | |||||||||||||
541 | SolarMutexGuard aGuard; | ||||||||||||
542 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
543 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
544 | { | ||||||||||||
545 | ToolBox* pToolbar = static_cast<ToolBox *>(pWindow.get()); | ||||||||||||
546 | ToolBoxMenuType nMenuType = pToolbar->GetMenuType(); | ||||||||||||
547 | if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, "ConfigureDialog" )) | ||||||||||||
548 | pToolbar->SetMenuType( nMenuType & ~ToolBoxMenuType::Customize ); | ||||||||||||
549 | else | ||||||||||||
550 | pToolbar->SetMenuType( nMenuType | ToolBoxMenuType::Customize ); | ||||||||||||
551 | } | ||||||||||||
552 | bNotify = true; | ||||||||||||
553 | |||||||||||||
554 | implts_sortUIElements(); | ||||||||||||
555 | |||||||||||||
556 | if ( bVisible && !bFloating ) | ||||||||||||
557 | implts_setLayoutDirty(); | ||||||||||||
558 | } | ||||||||||||
559 | } | ||||||||||||
560 | |||||||||||||
561 | return bNotify; | ||||||||||||
562 | } | ||||||||||||
563 | |||||||||||||
564 | bool ToolbarLayoutManager::destroyToolbar( const OUString& rResourceURL ) | ||||||||||||
565 | { | ||||||||||||
566 | uno::Reference< lang::XComponent > xComponent; | ||||||||||||
567 | |||||||||||||
568 | bool bNotify( false ); | ||||||||||||
569 | bool bMustBeSorted( false ); | ||||||||||||
570 | bool bMustLayouted( false ); | ||||||||||||
571 | bool bMustBeDestroyed( !rResourceURL.startsWith("private:resource/toolbar/addon_") ); | ||||||||||||
572 | |||||||||||||
573 | { | ||||||||||||
574 | SolarMutexGuard aWriteLock; | ||||||||||||
575 | for (auto & elem : m_aUIElements) | ||||||||||||
576 | { | ||||||||||||
577 | if (elem.m_aName == rResourceURL) | ||||||||||||
578 | { | ||||||||||||
579 | xComponent.set(elem.m_xUIElement, uno::UNO_QUERY); | ||||||||||||
580 | if (bMustBeDestroyed) | ||||||||||||
581 | elem.m_xUIElement.clear(); | ||||||||||||
582 | else | ||||||||||||
583 | elem.m_bVisible = false; | ||||||||||||
584 | break; | ||||||||||||
585 | } | ||||||||||||
586 | } | ||||||||||||
587 | } | ||||||||||||
588 | |||||||||||||
589 | uno::Reference< ui::XUIElement > xUIElement( xComponent, uno::UNO_QUERY ); | ||||||||||||
590 | if ( xUIElement.is() ) | ||||||||||||
591 | { | ||||||||||||
592 | uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
593 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
594 | |||||||||||||
595 | if ( bMustBeDestroyed ) | ||||||||||||
596 | { | ||||||||||||
597 | try | ||||||||||||
598 | { | ||||||||||||
599 | if ( xWindow.is() ) | ||||||||||||
600 | xWindow->removeWindowListener( uno::Reference< awt::XWindowListener >( | ||||||||||||
601 | static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); | ||||||||||||
602 | } | ||||||||||||
603 | catch (const uno::Exception&) | ||||||||||||
604 | { | ||||||||||||
605 | } | ||||||||||||
606 | |||||||||||||
607 | try | ||||||||||||
608 | { | ||||||||||||
609 | if ( xDockWindow.is() ) | ||||||||||||
610 | xDockWindow->removeDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( | ||||||||||||
611 | static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); | ||||||||||||
612 | } | ||||||||||||
613 | catch (const uno::Exception&) | ||||||||||||
614 | { | ||||||||||||
615 | } | ||||||||||||
616 | } | ||||||||||||
617 | else | ||||||||||||
618 | { | ||||||||||||
619 | if ( xWindow.is() ) | ||||||||||||
620 | xWindow->setVisible( false ); | ||||||||||||
621 | bNotify = true; | ||||||||||||
622 | } | ||||||||||||
623 | |||||||||||||
624 | if ( !xDockWindow->isFloating() ) | ||||||||||||
625 | bMustLayouted = true; | ||||||||||||
626 | bMustBeSorted = true; | ||||||||||||
627 | } | ||||||||||||
628 | |||||||||||||
629 | if ( bMustBeDestroyed ) | ||||||||||||
630 | { | ||||||||||||
631 | if ( xComponent.is() ) | ||||||||||||
632 | xComponent->dispose(); | ||||||||||||
633 | bNotify = true; | ||||||||||||
634 | } | ||||||||||||
635 | |||||||||||||
636 | if ( bMustLayouted ) | ||||||||||||
637 | implts_setLayoutDirty(); | ||||||||||||
638 | |||||||||||||
639 | if ( bMustBeSorted ) | ||||||||||||
640 | implts_sortUIElements(); | ||||||||||||
641 | |||||||||||||
642 | return bNotify; | ||||||||||||
643 | } | ||||||||||||
644 | |||||||||||||
645 | void ToolbarLayoutManager::destroyToolbars() | ||||||||||||
646 | { | ||||||||||||
647 | UIElementVector aUIElementVector; | ||||||||||||
648 | implts_getUIElementVectorCopy( aUIElementVector ); | ||||||||||||
649 | |||||||||||||
650 | { | ||||||||||||
651 | SolarMutexGuard aWriteLock; | ||||||||||||
652 | m_aUIElements.clear(); | ||||||||||||
653 | m_bLayoutDirty = true; | ||||||||||||
654 | } | ||||||||||||
655 | |||||||||||||
656 | for (auto const& elem : aUIElementVector) | ||||||||||||
657 | { | ||||||||||||
658 | uno::Reference< lang::XComponent > xComponent( elem.m_xUIElement, uno::UNO_QUERY ); | ||||||||||||
659 | if ( xComponent.is() ) | ||||||||||||
660 | xComponent->dispose(); | ||||||||||||
661 | } | ||||||||||||
662 | } | ||||||||||||
663 | |||||||||||||
664 | bool ToolbarLayoutManager::showToolbar( const OUString& rResourceURL ) | ||||||||||||
665 | { | ||||||||||||
666 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
667 | |||||||||||||
668 | SolarMutexGuard aGuard; | ||||||||||||
669 | vcl::Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement ); | ||||||||||||
670 | |||||||||||||
671 | // Addons appear to need to be populated at start, but we don't | ||||||||||||
672 | // want to populate them with (scaled) images until later. | ||||||||||||
673 | AddonsToolBarWrapper *pAddOns; | ||||||||||||
674 | pAddOns = dynamic_cast<AddonsToolBarWrapper *>( aUIElement.m_xUIElement.get()); | ||||||||||||
675 | if (pAddOns) | ||||||||||||
676 | pAddOns->populateImages(); | ||||||||||||
677 | |||||||||||||
678 | if ( pWindow ) | ||||||||||||
679 | { | ||||||||||||
680 | if ( !aUIElement.m_bFloating ) | ||||||||||||
681 | implts_setLayoutDirty(); | ||||||||||||
682 | else | ||||||||||||
683 | pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate ); | ||||||||||||
684 | |||||||||||||
685 | aUIElement.m_bVisible = true; | ||||||||||||
686 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
687 | implts_setToolbar( aUIElement ); | ||||||||||||
688 | implts_sortUIElements(); | ||||||||||||
689 | return true; | ||||||||||||
690 | } | ||||||||||||
691 | |||||||||||||
692 | return false; | ||||||||||||
693 | } | ||||||||||||
694 | |||||||||||||
695 | bool ToolbarLayoutManager::hideToolbar( const OUString& rResourceURL ) | ||||||||||||
696 | { | ||||||||||||
697 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
698 | |||||||||||||
699 | SolarMutexGuard aGuard; | ||||||||||||
700 | vcl::Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement ); | ||||||||||||
701 | if ( pWindow ) | ||||||||||||
702 | { | ||||||||||||
703 | pWindow->Show( false ); | ||||||||||||
704 | if ( !aUIElement.m_bFloating ) | ||||||||||||
705 | implts_setLayoutDirty(); | ||||||||||||
706 | |||||||||||||
707 | aUIElement.m_bVisible = false; | ||||||||||||
708 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
709 | implts_setToolbar( aUIElement ); | ||||||||||||
710 | return true; | ||||||||||||
711 | } | ||||||||||||
712 | |||||||||||||
713 | return false; | ||||||||||||
714 | } | ||||||||||||
715 | |||||||||||||
716 | void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars ) | ||||||||||||
717 | { | ||||||||||||
718 | UIElementVector aUIElementVector; | ||||||||||||
719 | |||||||||||||
720 | if ( !bAutomaticToolbars ) | ||||||||||||
721 | return; | ||||||||||||
722 | |||||||||||||
723 | implts_getUIElementVectorCopy( aUIElementVector ); | ||||||||||||
724 | |||||||||||||
725 | UIElement aUIElement; | ||||||||||||
726 | SolarMutexGuard aGuard; | ||||||||||||
727 | for (auto const& elem : aUIElementVector) | ||||||||||||
728 | { | ||||||||||||
729 | if ( implts_readWindowStateData( elem.m_aName, aUIElement ) && | ||||||||||||
730 | ( elem.m_bVisible != aUIElement.m_bVisible ) && !elem.m_bMasterHide ) | ||||||||||||
731 | { | ||||||||||||
732 | SolarMutexGuard g; | ||||||||||||
733 | UIElement& rUIElement = impl_findToolbar( elem.m_aName ); | ||||||||||||
734 | if ( rUIElement.m_aName == elem.m_aName ) | ||||||||||||
735 | { | ||||||||||||
736 | rUIElement.m_bVisible = aUIElement.m_bVisible; | ||||||||||||
737 | implts_setLayoutDirty(); | ||||||||||||
738 | } | ||||||||||||
739 | } | ||||||||||||
740 | } | ||||||||||||
741 | } | ||||||||||||
742 | |||||||||||||
743 | void ToolbarLayoutManager::setFloatingToolbarsVisibility( bool bVisible ) | ||||||||||||
744 | { | ||||||||||||
745 | UIElementVector aUIElementVector; | ||||||||||||
746 | implts_getUIElementVectorCopy( aUIElementVector ); | ||||||||||||
747 | |||||||||||||
748 | SolarMutexGuard aGuard; | ||||||||||||
749 | for (auto const& elem : aUIElementVector) | ||||||||||||
750 | { | ||||||||||||
751 | vcl::Window* pWindow = getWindowFromXUIElement( elem.m_xUIElement ); | ||||||||||||
752 | if ( pWindow && elem.m_bFloating ) | ||||||||||||
753 | { | ||||||||||||
754 | if ( bVisible ) | ||||||||||||
755 | { | ||||||||||||
756 | if ( elem.m_bVisible && !elem.m_bMasterHide ) | ||||||||||||
757 | pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate ); | ||||||||||||
758 | } | ||||||||||||
759 | else | ||||||||||||
760 | pWindow->Show( false ); | ||||||||||||
761 | } | ||||||||||||
762 | } | ||||||||||||
763 | } | ||||||||||||
764 | |||||||||||||
765 | void ToolbarLayoutManager::setVisible( bool bVisible ) | ||||||||||||
766 | { | ||||||||||||
767 | UIElementVector aUIElementVector; | ||||||||||||
768 | implts_getUIElementVectorCopy( aUIElementVector ); | ||||||||||||
769 | |||||||||||||
770 | SolarMutexGuard aGuard; | ||||||||||||
771 | for (auto & elem : aUIElementVector) | ||||||||||||
772 | { | ||||||||||||
773 | if (!elem.m_bFloating) | ||||||||||||
774 | { | ||||||||||||
775 | elem.m_bMasterHide = !bVisible; | ||||||||||||
776 | implts_setToolbar(elem); | ||||||||||||
777 | implts_setLayoutDirty(); | ||||||||||||
778 | } | ||||||||||||
779 | |||||||||||||
780 | vcl::Window* pWindow = getWindowFromXUIElement( elem.m_xUIElement ); | ||||||||||||
781 | if ( pWindow ) | ||||||||||||
782 | { | ||||||||||||
783 | bool bSetVisible( elem.m_bVisible && bVisible ); | ||||||||||||
784 | if ( !bSetVisible ) | ||||||||||||
785 | pWindow->Hide(); | ||||||||||||
786 | else | ||||||||||||
787 | { | ||||||||||||
788 | if ( elem.m_bFloating ) | ||||||||||||
789 | pWindow->Show(true, ShowFlags::NoFocusChange | ShowFlags::NoActivate ); | ||||||||||||
790 | } | ||||||||||||
791 | } | ||||||||||||
792 | } | ||||||||||||
793 | |||||||||||||
794 | if ( !bVisible ) | ||||||||||||
795 | resetDockingArea(); | ||||||||||||
796 | } | ||||||||||||
797 | |||||||||||||
798 | bool ToolbarLayoutManager::dockToolbar( const OUString& rResourceURL, ui::DockingArea eDockingArea, const awt::Point& aPos ) | ||||||||||||
799 | { | ||||||||||||
800 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
801 | |||||||||||||
802 | if ( aUIElement.m_xUIElement.is() ) | ||||||||||||
803 | { | ||||||||||||
804 | try | ||||||||||||
805 | { | ||||||||||||
806 | uno::Reference< awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
807 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
808 | if ( xDockWindow.is() ) | ||||||||||||
809 | { | ||||||||||||
810 | if ( eDockingArea != ui::DockingArea_DOCKINGAREA_DEFAULT ) | ||||||||||||
811 | aUIElement.m_aDockedData.m_nDockedArea = eDockingArea; | ||||||||||||
812 | |||||||||||||
813 | if ( !isDefaultPos( aPos )) | ||||||||||||
814 | aUIElement.m_aDockedData.m_aPos = aPos; | ||||||||||||
815 | |||||||||||||
816 | if ( !xDockWindow->isFloating() ) | ||||||||||||
817 | { | ||||||||||||
818 | vcl::Window* pWindow( nullptr ); | ||||||||||||
819 | ToolBox* pToolBox( nullptr ); | ||||||||||||
820 | |||||||||||||
821 | { | ||||||||||||
822 | SolarMutexGuard aGuard; | ||||||||||||
823 | pWindow = VCLUnoHelper::GetWindow( xWindow ).get(); | ||||||||||||
824 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
825 | { | ||||||||||||
826 | pToolBox = static_cast<ToolBox *>(pWindow); | ||||||||||||
827 | |||||||||||||
828 | // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a | ||||||||||||
829 | // horizontal to a vertical docking area! | ||||||||||||
830 | pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea )); | ||||||||||||
831 | } | ||||||||||||
832 | } | ||||||||||||
833 | |||||||||||||
834 | if ( hasDefaultPosValue( aUIElement.m_aDockedData.m_aPos )) | ||||||||||||
835 | { | ||||||||||||
836 | // Docking on its default position without a preset position - | ||||||||||||
837 | // we have to find a good place for it. | ||||||||||||
838 | ::Size aSize; | ||||||||||||
839 | |||||||||||||
840 | SolarMutexGuard aGuard; | ||||||||||||
841 | { | ||||||||||||
842 | if (pToolBox) | ||||||||||||
843 | aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) ); | ||||||||||||
844 | else if (pWindow) | ||||||||||||
845 | aSize = pWindow->GetSizePixel(); | ||||||||||||
846 | } | ||||||||||||
847 | |||||||||||||
848 | ::Point aPixelPos; | ||||||||||||
849 | awt::Point aDockPos; | ||||||||||||
850 | implts_findNextDockingPos(aUIElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos ); | ||||||||||||
851 | aUIElement.m_aDockedData.m_aPos = aDockPos; | ||||||||||||
852 | } | ||||||||||||
853 | } | ||||||||||||
854 | |||||||||||||
855 | implts_setToolbar( aUIElement ); | ||||||||||||
856 | |||||||||||||
857 | if ( xDockWindow->isFloating() ) | ||||||||||||
858 | { | ||||||||||||
859 | // ATTENTION: This will call toggleFloatingMode() via notifications which | ||||||||||||
860 | // sets the floating member of the UIElement correctly! | ||||||||||||
861 | xDockWindow->setFloatingMode( false ); | ||||||||||||
862 | } | ||||||||||||
863 | else | ||||||||||||
864 | { | ||||||||||||
865 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
866 | implts_sortUIElements(); | ||||||||||||
867 | |||||||||||||
868 | if ( aUIElement.m_bVisible ) | ||||||||||||
869 | implts_setLayoutDirty(); | ||||||||||||
870 | } | ||||||||||||
871 | return true; | ||||||||||||
872 | } | ||||||||||||
873 | } | ||||||||||||
874 | catch (const lang::DisposedException&) | ||||||||||||
875 | { | ||||||||||||
876 | } | ||||||||||||
877 | } | ||||||||||||
878 | |||||||||||||
879 | return false; | ||||||||||||
880 | } | ||||||||||||
881 | |||||||||||||
882 | bool ToolbarLayoutManager::dockAllToolbars() | ||||||||||||
883 | { | ||||||||||||
884 | std::vector< OUString > aToolBarNameVector; | ||||||||||||
885 | |||||||||||||
886 | { | ||||||||||||
887 | SolarMutexGuard aReadLock; | ||||||||||||
888 | for (auto const& elem : m_aUIElements) | ||||||||||||
889 | { | ||||||||||||
890 | if (elem.m_aType == "toolbar" && elem.m_xUIElement.is() && elem.m_bFloating | ||||||||||||
891 | && elem.m_bVisible) | ||||||||||||
892 | aToolBarNameVector.push_back(elem.m_aName); | ||||||||||||
893 | } | ||||||||||||
894 | } | ||||||||||||
895 | |||||||||||||
896 | bool bResult(true); | ||||||||||||
897 | const sal_uInt32 nCount = aToolBarNameVector.size(); | ||||||||||||
898 | for ( sal_uInt32 i = 0; i < nCount; ++i ) | ||||||||||||
899 | { | ||||||||||||
900 | awt::Point aPoint; | ||||||||||||
901 | aPoint.X = aPoint.Y = SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF); | ||||||||||||
902 | bResult &= dockToolbar( aToolBarNameVector[i], ui::DockingArea_DOCKINGAREA_DEFAULT, aPoint ); | ||||||||||||
903 | } | ||||||||||||
904 | |||||||||||||
905 | return bResult; | ||||||||||||
906 | } | ||||||||||||
907 | |||||||||||||
908 | void ToolbarLayoutManager::childWindowEvent( VclSimpleEvent const * pEvent ) | ||||||||||||
909 | { | ||||||||||||
910 | // To enable toolbar controllers to change their image when a sub-toolbar function | ||||||||||||
911 | // is activated, we need this mechanism. We have NO connection between these toolbars | ||||||||||||
912 | // anymore! | ||||||||||||
913 | auto pWindowEvent = dynamic_cast< const VclWindowEvent* >(pEvent); | ||||||||||||
914 | if (!pWindowEvent) | ||||||||||||
915 | return; | ||||||||||||
916 | |||||||||||||
917 | if ( pEvent->GetId() == VclEventId::ToolboxSelect ) | ||||||||||||
918 | { | ||||||||||||
919 | OUString aToolbarName; | ||||||||||||
920 | OUString aCommand; | ||||||||||||
921 | ToolBox* pToolBox = getToolboxPtr( pWindowEvent->GetWindow() ); | ||||||||||||
922 | |||||||||||||
923 | if ( pToolBox ) | ||||||||||||
924 | { | ||||||||||||
925 | aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox ); | ||||||||||||
926 | sal_uInt16 nId = pToolBox->GetCurItemId(); | ||||||||||||
927 | if ( nId > 0 ) | ||||||||||||
928 | aCommand = pToolBox->GetItemCommand( nId ); | ||||||||||||
929 | } | ||||||||||||
930 | |||||||||||||
931 | if ( !aToolbarName.isEmpty() && !aCommand.isEmpty() ) | ||||||||||||
932 | { | ||||||||||||
933 | SolarMutexClearableGuard aReadLock; | ||||||||||||
934 | ::std::vector< uno::Reference< ui::XUIFunctionListener > > aListenerArray; | ||||||||||||
935 | |||||||||||||
936 | for (auto const& elem : m_aUIElements) | ||||||||||||
937 | { | ||||||||||||
938 | if ( elem.m_xUIElement.is() ) | ||||||||||||
939 | { | ||||||||||||
940 | uno::Reference< ui::XUIFunctionListener > xListener( elem.m_xUIElement, uno::UNO_QUERY ); | ||||||||||||
941 | if ( xListener.is() ) | ||||||||||||
942 | aListenerArray.push_back( xListener ); | ||||||||||||
943 | } | ||||||||||||
944 | } | ||||||||||||
945 | aReadLock.clear(); | ||||||||||||
946 | |||||||||||||
947 | const sal_uInt32 nCount = aListenerArray.size(); | ||||||||||||
948 | for ( sal_uInt32 i = 0; i < nCount; ++i ) | ||||||||||||
949 | { | ||||||||||||
950 | try | ||||||||||||
951 | { | ||||||||||||
952 | aListenerArray[i]->functionExecute( aToolbarName, aCommand ); | ||||||||||||
953 | } | ||||||||||||
954 | catch (const uno::RuntimeException&) | ||||||||||||
955 | { | ||||||||||||
956 | throw; | ||||||||||||
957 | } | ||||||||||||
958 | catch (const uno::Exception&) | ||||||||||||
959 | { | ||||||||||||
960 | } | ||||||||||||
961 | } | ||||||||||||
962 | } | ||||||||||||
963 | } | ||||||||||||
964 | else if ( pEvent->GetId() == VclEventId::ToolboxFormatChanged ) | ||||||||||||
965 | { | ||||||||||||
966 | if ( !implts_isToolbarCreationActive() ) | ||||||||||||
967 | { | ||||||||||||
968 | ToolBox* pToolBox = getToolboxPtr( static_cast<VclWindowEvent const *>(pEvent)->GetWindow() ); | ||||||||||||
969 | if ( pToolBox ) | ||||||||||||
970 | { | ||||||||||||
971 | OUString aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox ); | ||||||||||||
972 | if ( !aToolbarName.isEmpty() ) | ||||||||||||
973 | { | ||||||||||||
974 | OUString aToolbarUrl = "private:resource/toolbar/" + aToolbarName; | ||||||||||||
975 | |||||||||||||
976 | UIElement aToolbar = implts_findToolbar( aToolbarUrl ); | ||||||||||||
977 | if ( aToolbar.m_xUIElement.is() && !aToolbar.m_bFloating ) | ||||||||||||
978 | { | ||||||||||||
979 | implts_setLayoutDirty(); | ||||||||||||
980 | m_pParentLayouter->requestLayout(); | ||||||||||||
981 | } | ||||||||||||
982 | } | ||||||||||||
983 | } | ||||||||||||
984 | } | ||||||||||||
985 | } | ||||||||||||
986 | } | ||||||||||||
987 | |||||||||||||
988 | void ToolbarLayoutManager::resetDockingArea() | ||||||||||||
989 | { | ||||||||||||
990 | SolarMutexClearableGuard aReadLock; | ||||||||||||
991 | uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] ); | ||||||||||||
992 | uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] ); | ||||||||||||
993 | uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)] ); | ||||||||||||
994 | uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)] ); | ||||||||||||
995 | aReadLock.clear(); | ||||||||||||
996 | |||||||||||||
997 | if ( xTopDockingWindow.is() ) | ||||||||||||
998 | xTopDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); | ||||||||||||
999 | if ( xLeftDockingWindow.is() ) | ||||||||||||
1000 | xLeftDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); | ||||||||||||
1001 | if ( xRightDockingWindow.is() ) | ||||||||||||
1002 | xRightDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); | ||||||||||||
1003 | if ( xBottomDockingWindow.is() ) | ||||||||||||
1004 | xBottomDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); | ||||||||||||
1005 | } | ||||||||||||
1006 | |||||||||||||
1007 | void ToolbarLayoutManager::setParentWindow( | ||||||||||||
1008 | const uno::Reference< awt::XWindowPeer >& xParentWindow ) | ||||||||||||
1009 | { | ||||||||||||
1010 | static const char DOCKINGAREASTRING[] = "dockingarea"; | ||||||||||||
1011 | |||||||||||||
1012 | uno::Reference< awt::XWindow > xTopDockWindow( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY ); | ||||||||||||
1013 | uno::Reference< awt::XWindow > xLeftDockWindow( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY ); | ||||||||||||
1014 | uno::Reference< awt::XWindow > xRightDockWindow( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY ); | ||||||||||||
1015 | uno::Reference< awt::XWindow > xBottomDockWindow( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY ); | ||||||||||||
1016 | |||||||||||||
1017 | { | ||||||||||||
1018 | SolarMutexGuard aWriteLock; | ||||||||||||
1019 | m_xContainerWindow.set(xParentWindow, uno::UNO_QUERY); | ||||||||||||
1020 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] = xTopDockWindow; | ||||||||||||
1021 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] = xLeftDockWindow; | ||||||||||||
1022 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)] = xRightDockWindow; | ||||||||||||
1023 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)] = xBottomDockWindow; | ||||||||||||
1024 | } | ||||||||||||
1025 | |||||||||||||
1026 | if ( xParentWindow.is() ) | ||||||||||||
1027 | { | ||||||||||||
1028 | SolarMutexGuard aGuard; | ||||||||||||
1029 | VclPtr< ::DockingAreaWindow > pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xTopDockWindow ).get() ); | ||||||||||||
1030 | if( pWindow ) | ||||||||||||
1031 | pWindow->SetAlign( WindowAlign::Top ); | ||||||||||||
1032 | pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xBottomDockWindow ).get() ); | ||||||||||||
1033 | if( pWindow ) | ||||||||||||
1034 | pWindow->SetAlign( WindowAlign::Bottom ); | ||||||||||||
1035 | pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xLeftDockWindow ).get() ); | ||||||||||||
1036 | if( pWindow ) | ||||||||||||
1037 | pWindow->SetAlign( WindowAlign::Left ); | ||||||||||||
1038 | pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xRightDockWindow ).get() ); | ||||||||||||
1039 | if( pWindow ) | ||||||||||||
1040 | pWindow->SetAlign( WindowAlign::Right ); | ||||||||||||
1041 | implts_reparentToolbars(); | ||||||||||||
1042 | } | ||||||||||||
1043 | else | ||||||||||||
1044 | { | ||||||||||||
1045 | destroyToolbars(); | ||||||||||||
1046 | resetDockingArea(); | ||||||||||||
1047 | } | ||||||||||||
1048 | } | ||||||||||||
1049 | |||||||||||||
1050 | void ToolbarLayoutManager::setDockingAreaOffsets( const ::tools::Rectangle& rOffsets ) | ||||||||||||
1051 | { | ||||||||||||
1052 | SolarMutexGuard g; | ||||||||||||
1053 | m_aDockingAreaOffsets = rOffsets; | ||||||||||||
1054 | m_bLayoutDirty = true; | ||||||||||||
1055 | } | ||||||||||||
1056 | |||||||||||||
1057 | OUString ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const | ||||||||||||
1058 | { | ||||||||||||
1059 | OUString aAddonGenericTitle(FwkResId(STR_TOOLBAR_TITLE_ADDONreinterpret_cast<char const *>("STR_TOOLBAR_TITLE_ADDON" "\004" u8"Add-On %num%"))); | ||||||||||||
1060 | const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); | ||||||||||||
1061 | |||||||||||||
1062 | OUString aNumStr = rI18nHelper.GetNum( nNumber, 0, false, false ); | ||||||||||||
1063 | aAddonGenericTitle = aAddonGenericTitle.replaceFirst( "%num%", aNumStr ); | ||||||||||||
1064 | |||||||||||||
1065 | return aAddonGenericTitle; | ||||||||||||
1066 | } | ||||||||||||
1067 | |||||||||||||
1068 | void ToolbarLayoutManager::implts_createAddonsToolBars() | ||||||||||||
1069 | { | ||||||||||||
1070 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
1071 | if ( !m_pAddonOptions ) | ||||||||||||
1072 | m_pAddonOptions.reset( new AddonsOptions ); | ||||||||||||
1073 | |||||||||||||
1074 | uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); | ||||||||||||
1075 | uno::Reference< frame::XFrame > xFrame( m_xFrame ); | ||||||||||||
1076 | aWriteLock.clear(); | ||||||||||||
1077 | |||||||||||||
1078 | if (isPreviewFrame()) | ||||||||||||
1079 | return; // no addon toolbars for preview frame! | ||||||||||||
1080 | |||||||||||||
1081 | uno::Sequence< uno::Sequence< beans::PropertyValue > > aAddonToolBarData; | ||||||||||||
1082 | uno::Reference< ui::XUIElement > xUIElement; | ||||||||||||
1083 | |||||||||||||
1084 | sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount(); | ||||||||||||
1085 | |||||||||||||
1086 | uno::Sequence< beans::PropertyValue > aPropSeq( 2 ); | ||||||||||||
1087 | aPropSeq[0].Name = "Frame"; | ||||||||||||
1088 | aPropSeq[0].Value <<= xFrame; | ||||||||||||
1089 | aPropSeq[1].Name = "ConfigurationData"; | ||||||||||||
1090 | for ( sal_uInt32 i = 0; i < nCount; i++ ) | ||||||||||||
1091 | { | ||||||||||||
1092 | OUString aAddonToolBarName( "private:resource/toolbar/addon_" + | ||||||||||||
1093 | m_pAddonOptions->GetAddonsToolbarResourceName(i) ); | ||||||||||||
1094 | aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i ); | ||||||||||||
1095 | aPropSeq[1].Value <<= aAddonToolBarData; | ||||||||||||
1096 | |||||||||||||
1097 | UIElement aElement = implts_findToolbar( aAddonToolBarName ); | ||||||||||||
1098 | |||||||||||||
1099 | // #i79828 | ||||||||||||
1100 | // It's now possible that we are called more than once. Be sure to not create | ||||||||||||
1101 | // add-on toolbars more than once! | ||||||||||||
1102 | if ( aElement.m_xUIElement.is() ) | ||||||||||||
1103 | continue; | ||||||||||||
1104 | |||||||||||||
1105 | try | ||||||||||||
1106 | { | ||||||||||||
1107 | xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq ); | ||||||||||||
1108 | if ( xUIElement.is() ) | ||||||||||||
1109 | { | ||||||||||||
1110 | uno::Reference< awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
1111 | if ( xDockWindow.is() ) | ||||||||||||
1112 | { | ||||||||||||
1113 | try | ||||||||||||
1114 | { | ||||||||||||
1115 | xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); | ||||||||||||
1116 | xDockWindow->enableDocking( true ); | ||||||||||||
1117 | uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY ); | ||||||||||||
1118 | if ( xWindow.is() ) | ||||||||||||
1119 | xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); | ||||||||||||
1120 | } | ||||||||||||
1121 | catch (const uno::Exception&) | ||||||||||||
1122 | { | ||||||||||||
1123 | } | ||||||||||||
1124 | } | ||||||||||||
1125 | |||||||||||||
1126 | OUString aGenericAddonTitle = implts_generateGenericAddonToolbarTitle( i+1 ); | ||||||||||||
1127 | |||||||||||||
1128 | if ( !aElement.m_aName.isEmpty() ) | ||||||||||||
1129 | { | ||||||||||||
1130 | // Reuse a local entry so we are able to use the latest | ||||||||||||
1131 | // UI changes for this document. | ||||||||||||
1132 | implts_setElementData( aElement, xDockWindow ); | ||||||||||||
1133 | aElement.m_xUIElement = xUIElement; | ||||||||||||
1134 | if ( aElement.m_aUIName.isEmpty() ) | ||||||||||||
1135 | { | ||||||||||||
1136 | aElement.m_aUIName = aGenericAddonTitle; | ||||||||||||
1137 | implts_writeWindowStateData( aElement ); | ||||||||||||
1138 | } | ||||||||||||
1139 | } | ||||||||||||
1140 | else | ||||||||||||
1141 | { | ||||||||||||
1142 | // Create new UI element and try to read its state data | ||||||||||||
1143 | UIElement aNewToolbar( aAddonToolBarName, "toolbar", xUIElement ); | ||||||||||||
1144 | aNewToolbar.m_bFloating = true; | ||||||||||||
1145 | implts_readWindowStateData( aAddonToolBarName, aNewToolbar ); | ||||||||||||
1146 | implts_setElementData( aNewToolbar, xDockWindow ); | ||||||||||||
1147 | if ( aNewToolbar.m_aUIName.isEmpty() ) | ||||||||||||
1148 | { | ||||||||||||
1149 | aNewToolbar.m_aUIName = aGenericAddonTitle; | ||||||||||||
1150 | implts_writeWindowStateData( aNewToolbar ); | ||||||||||||
1151 | } | ||||||||||||
1152 | implts_insertToolbar( aNewToolbar ); | ||||||||||||
1153 | } | ||||||||||||
1154 | |||||||||||||
1155 | uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY ); | ||||||||||||
1156 | if ( xWindow.is() ) | ||||||||||||
1157 | { | ||||||||||||
1158 | // Set generic title for add-on toolbar | ||||||||||||
1159 | SolarMutexGuard aGuard; | ||||||||||||
1160 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
1161 | if ( pWindow->GetText().isEmpty() ) | ||||||||||||
1162 | pWindow->SetText( aGenericAddonTitle ); | ||||||||||||
1163 | if ( pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
1164 | { | ||||||||||||
1165 | ToolBox* pToolbar = static_cast<ToolBox *>(pWindow.get()); | ||||||||||||
1166 | pToolbar->SetMenuType(); | ||||||||||||
1167 | } | ||||||||||||
1168 | } | ||||||||||||
1169 | } | ||||||||||||
1170 | } | ||||||||||||
1171 | catch (const container::NoSuchElementException&) | ||||||||||||
1172 | { | ||||||||||||
1173 | } | ||||||||||||
1174 | catch (const lang::IllegalArgumentException&) | ||||||||||||
1175 | { | ||||||||||||
1176 | } | ||||||||||||
1177 | } | ||||||||||||
1178 | } | ||||||||||||
1179 | |||||||||||||
1180 | void ToolbarLayoutManager::implts_createCustomToolBars() | ||||||||||||
1181 | { | ||||||||||||
1182 | SolarMutexClearableGuard aReadLock; | ||||||||||||
1183 | if ( !m_bComponentAttached ) | ||||||||||||
1184 | return; | ||||||||||||
1185 | |||||||||||||
1186 | uno::Reference< frame::XFrame > xFrame( m_xFrame ); | ||||||||||||
1187 | uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr = m_xModuleCfgMgr; | ||||||||||||
1188 | uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr = m_xDocCfgMgr; | ||||||||||||
1189 | aReadLock.clear(); | ||||||||||||
1190 | |||||||||||||
1191 | if ( !xFrame.is() ) | ||||||||||||
1192 | return; | ||||||||||||
1193 | |||||||||||||
1194 | if (isPreviewFrame()) | ||||||||||||
1195 | return; // no custom toolbars for preview frame! | ||||||||||||
1196 | |||||||||||||
1197 | uno::Sequence< uno::Sequence< beans::PropertyValue > > aTbxSeq; | ||||||||||||
1198 | if ( xDocCfgMgr.is() ) | ||||||||||||
1199 | { | ||||||||||||
1200 | aTbxSeq = xDocCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR ); | ||||||||||||
1201 | implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars | ||||||||||||
1202 | } | ||||||||||||
1203 | if ( xModuleCfgMgr.is() ) | ||||||||||||
1204 | { | ||||||||||||
1205 | aTbxSeq = xModuleCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR ); | ||||||||||||
1206 | implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars | ||||||||||||
1207 | } | ||||||||||||
1208 | } | ||||||||||||
1209 | |||||||||||||
1210 | void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars() | ||||||||||||
1211 | { | ||||||||||||
1212 | SolarMutexClearableGuard aReadLock; | ||||||||||||
1213 | |||||||||||||
1214 | if ( !m_xPersistentWindowState.is() || !m_xFrame.is() || !m_bComponentAttached ) | ||||||||||||
1215 | return; | ||||||||||||
1216 | |||||||||||||
1217 | uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); | ||||||||||||
1218 | aReadLock.clear(); | ||||||||||||
1219 | |||||||||||||
1220 | if (isPreviewFrame()) | ||||||||||||
1221 | return; | ||||||||||||
1222 | |||||||||||||
1223 | std::vector< OUString > aMakeVisibleToolbars; | ||||||||||||
1224 | |||||||||||||
1225 | try | ||||||||||||
1226 | { | ||||||||||||
1227 | const uno::Sequence< OUString > aToolbarNames = xPersistentWindowState->getElementNames(); | ||||||||||||
1228 | |||||||||||||
1229 | if ( aToolbarNames.hasElements() ) | ||||||||||||
1230 | { | ||||||||||||
1231 | OUString aElementType; | ||||||||||||
1232 | OUString aElementName; | ||||||||||||
1233 | |||||||||||||
1234 | aMakeVisibleToolbars.reserve(aToolbarNames.getLength()); | ||||||||||||
1235 | |||||||||||||
1236 | SolarMutexGuard g; | ||||||||||||
1237 | |||||||||||||
1238 | for ( OUString const & aName : aToolbarNames ) | ||||||||||||
1239 | { | ||||||||||||
1240 | parseResourceURL( aName, aElementType, aElementName ); | ||||||||||||
1241 | |||||||||||||
1242 | // Check that we only create: | ||||||||||||
1243 | // - Toolbars (the statusbar is also member of the persistent window state) | ||||||||||||
1244 | // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars) | ||||||||||||
1245 | if ( aElementType.equalsIgnoreAsciiCase("toolbar") && | ||||||||||||
1246 | aElementName.indexOf( "custom_" ) == -1 ) | ||||||||||||
1247 | { | ||||||||||||
1248 | UIElement aNewToolbar = implts_findToolbar( aName ); | ||||||||||||
1249 | bool bFound = ( aNewToolbar.m_aName == aName ); | ||||||||||||
1250 | if ( !bFound ) | ||||||||||||
1251 | implts_readWindowStateData( aName, aNewToolbar ); | ||||||||||||
1252 | |||||||||||||
1253 | if ( aNewToolbar.m_bVisible && !aNewToolbar.m_bContextSensitive ) | ||||||||||||
1254 | { | ||||||||||||
1255 | if ( !bFound ) | ||||||||||||
1256 | implts_insertToolbar( aNewToolbar ); | ||||||||||||
1257 | aMakeVisibleToolbars.push_back( aName ); | ||||||||||||
1258 | } | ||||||||||||
1259 | } | ||||||||||||
1260 | } | ||||||||||||
1261 | } | ||||||||||||
1262 | } | ||||||||||||
1263 | catch (const uno::RuntimeException&) | ||||||||||||
1264 | { | ||||||||||||
1265 | throw; | ||||||||||||
1266 | } | ||||||||||||
1267 | catch (const uno::Exception&) | ||||||||||||
1268 | { | ||||||||||||
1269 | } | ||||||||||||
1270 | |||||||||||||
1271 | for (auto const& rURL : aMakeVisibleToolbars) | ||||||||||||
1272 | { | ||||||||||||
1273 | requestToolbar(rURL); | ||||||||||||
1274 | } | ||||||||||||
1275 | } | ||||||||||||
1276 | |||||||||||||
1277 | void ToolbarLayoutManager::implts_createCustomToolBars( const uno::Sequence< uno::Sequence< beans::PropertyValue > >& aTbxSeqSeq ) | ||||||||||||
1278 | { | ||||||||||||
1279 | for ( const uno::Sequence< beans::PropertyValue >& rTbxSeq : aTbxSeqSeq ) | ||||||||||||
1280 | { | ||||||||||||
1281 | OUString aTbxResName; | ||||||||||||
1282 | OUString aTbxTitle; | ||||||||||||
1283 | for ( const beans::PropertyValue& rProp : rTbxSeq ) | ||||||||||||
1284 | { | ||||||||||||
1285 | if ( rProp.Name == "ResourceURL" ) | ||||||||||||
1286 | rProp.Value >>= aTbxResName; | ||||||||||||
1287 | else if ( rProp.Name == "UIName" ) | ||||||||||||
1288 | rProp.Value >>= aTbxTitle; | ||||||||||||
1289 | } | ||||||||||||
1290 | |||||||||||||
1291 | // Only create custom toolbars. Their name have to start with "custom_"! | ||||||||||||
1292 | if ( !aTbxResName.isEmpty() && ( aTbxResName.indexOf( "custom_" ) != -1 ) ) | ||||||||||||
1293 | implts_createCustomToolBar( aTbxResName, aTbxTitle ); | ||||||||||||
1294 | } | ||||||||||||
1295 | } | ||||||||||||
1296 | |||||||||||||
1297 | void ToolbarLayoutManager::implts_createCustomToolBar( const OUString& aTbxResName, const OUString& aTitle ) | ||||||||||||
1298 | { | ||||||||||||
1299 | if ( aTbxResName.isEmpty() ) | ||||||||||||
1300 | return; | ||||||||||||
1301 | |||||||||||||
1302 | if ( !createToolbar( aTbxResName ) ) | ||||||||||||
1303 | SAL_WARN("fwk.uielement", "ToolbarLayoutManager cannot create custom toolbar")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "fwk.uielement")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "ToolbarLayoutManager cannot create custom toolbar" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("fwk.uielement" ), ("/home/maarten/src/libreoffice/core/framework/source/layoutmanager/toolbarlayoutmanager.cxx" ":" "1303" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "ToolbarLayoutManager cannot create custom toolbar" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "ToolbarLayoutManager cannot create custom toolbar" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("fwk.uielement" ), ("/home/maarten/src/libreoffice/core/framework/source/layoutmanager/toolbarlayoutmanager.cxx" ":" "1303" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "ToolbarLayoutManager cannot create custom toolbar" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("fwk.uielement" ), ("/home/maarten/src/libreoffice/core/framework/source/layoutmanager/toolbarlayoutmanager.cxx" ":" "1303" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "ToolbarLayoutManager cannot create custom toolbar" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "ToolbarLayoutManager cannot create custom toolbar" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("fwk.uielement" ), ("/home/maarten/src/libreoffice/core/framework/source/layoutmanager/toolbarlayoutmanager.cxx" ":" "1303" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||||||||
1304 | |||||||||||||
1305 | uno::Reference< ui::XUIElement > xUIElement = getToolbar( aTbxResName ); | ||||||||||||
1306 | |||||||||||||
1307 | if ( !aTitle.isEmpty() && xUIElement.is() ) | ||||||||||||
1308 | { | ||||||||||||
1309 | SolarMutexGuard aGuard; | ||||||||||||
1310 | |||||||||||||
1311 | vcl::Window* pWindow = getWindowFromXUIElement( xUIElement ); | ||||||||||||
1312 | if ( pWindow ) | ||||||||||||
1313 | pWindow->SetText( aTitle ); | ||||||||||||
1314 | } | ||||||||||||
1315 | } | ||||||||||||
1316 | |||||||||||||
1317 | void ToolbarLayoutManager::implts_reparentToolbars() | ||||||||||||
1318 | { | ||||||||||||
1319 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
1320 | UIElementVector aUIElementVector = m_aUIElements; | ||||||||||||
1321 | VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); | ||||||||||||
1322 | VclPtr<vcl::Window> pTopDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] ); | ||||||||||||
1323 | VclPtr<vcl::Window> pBottomDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)] ); | ||||||||||||
1324 | VclPtr<vcl::Window> pLeftDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] ); | ||||||||||||
1325 | VclPtr<vcl::Window> pRightDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)] ); | ||||||||||||
1326 | aWriteLock.clear(); | ||||||||||||
1327 | |||||||||||||
1328 | SolarMutexGuard aGuard; | ||||||||||||
1329 | if ( !pContainerWindow ) | ||||||||||||
1330 | return; | ||||||||||||
1331 | |||||||||||||
1332 | for (auto const& elem : aUIElementVector) | ||||||||||||
1333 | { | ||||||||||||
1334 | uno::Reference< ui::XUIElement > xUIElement( elem.m_xUIElement ); | ||||||||||||
1335 | if ( xUIElement.is() ) | ||||||||||||
1336 | { | ||||||||||||
1337 | uno::Reference< awt::XWindow > xWindow; | ||||||||||||
1338 | try | ||||||||||||
1339 | { | ||||||||||||
1340 | // We have to retrieve the window reference with try/catch as it is | ||||||||||||
1341 | // possible that all elements have been disposed! | ||||||||||||
1342 | xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
1343 | } | ||||||||||||
1344 | catch (const uno::RuntimeException&) | ||||||||||||
1345 | { | ||||||||||||
1346 | throw; | ||||||||||||
1347 | } | ||||||||||||
1348 | catch (const uno::Exception&) | ||||||||||||
1349 | { | ||||||||||||
1350 | } | ||||||||||||
1351 | |||||||||||||
1352 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
1353 | if ( pWindow ) | ||||||||||||
1354 | { | ||||||||||||
1355 | // Reparent our child windows according to their current state. | ||||||||||||
1356 | if ( elem.m_bFloating ) | ||||||||||||
1357 | pWindow->SetParent( pContainerWindow ); | ||||||||||||
1358 | else | ||||||||||||
1359 | { | ||||||||||||
1360 | if ( elem.m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
1361 | pWindow->SetParent( pTopDockWindow ); | ||||||||||||
1362 | else if ( elem.m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) | ||||||||||||
1363 | pWindow->SetParent( pBottomDockWindow ); | ||||||||||||
1364 | else if ( elem.m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
1365 | pWindow->SetParent( pLeftDockWindow ); | ||||||||||||
1366 | else | ||||||||||||
1367 | pWindow->SetParent( pRightDockWindow ); | ||||||||||||
1368 | } | ||||||||||||
1369 | } | ||||||||||||
1370 | } | ||||||||||||
1371 | } | ||||||||||||
1372 | } | ||||||||||||
1373 | |||||||||||||
1374 | void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart ) | ||||||||||||
1375 | { | ||||||||||||
1376 | SolarMutexGuard g; | ||||||||||||
1377 | m_bToolbarCreation = bStart; | ||||||||||||
1378 | } | ||||||||||||
1379 | |||||||||||||
1380 | bool ToolbarLayoutManager::implts_isToolbarCreationActive() | ||||||||||||
1381 | { | ||||||||||||
1382 | SolarMutexGuard g; | ||||||||||||
1383 | return m_bToolbarCreation; | ||||||||||||
1384 | } | ||||||||||||
1385 | |||||||||||||
1386 | void ToolbarLayoutManager::implts_setElementData( UIElement& rElement, const uno::Reference< awt::XDockableWindow >& rDockWindow ) | ||||||||||||
1387 | { | ||||||||||||
1388 | SolarMutexClearableGuard aReadLock; | ||||||||||||
1389 | bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && implts_isParentWindowVisible() ); | ||||||||||||
1390 | aReadLock.clear(); | ||||||||||||
1391 | |||||||||||||
1392 | uno::Reference< awt::XWindow2 > xWindow( rDockWindow, uno::UNO_QUERY ); | ||||||||||||
1393 | |||||||||||||
1394 | vcl::Window* pWindow( nullptr ); | ||||||||||||
1395 | ToolBox* pToolBox( nullptr ); | ||||||||||||
1396 | |||||||||||||
1397 | if ( !(rDockWindow.is() && xWindow.is()) ) | ||||||||||||
1398 | return; | ||||||||||||
1399 | |||||||||||||
1400 | { | ||||||||||||
1401 | SolarMutexGuard aGuard; | ||||||||||||
1402 | pWindow = VCLUnoHelper::GetWindow( xWindow ).get(); | ||||||||||||
1403 | if ( pWindow ) | ||||||||||||
1404 | { | ||||||||||||
1405 | OUString aText = pWindow->GetText(); | ||||||||||||
1406 | if ( aText.isEmpty() ) | ||||||||||||
1407 | pWindow->SetText( rElement.m_aUIName ); | ||||||||||||
1408 | if ( rElement.m_bNoClose ) | ||||||||||||
1409 | pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE ); | ||||||||||||
1410 | if ( pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
1411 | pToolBox = static_cast<ToolBox *>(pWindow); | ||||||||||||
1412 | } | ||||||||||||
1413 | if ( pToolBox ) | ||||||||||||
1414 | { | ||||||||||||
1415 | pToolBox->SetButtonType( rElement.m_nStyle ); | ||||||||||||
1416 | if ( rElement.m_bNoClose ) | ||||||||||||
1417 | pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE ); | ||||||||||||
1418 | } | ||||||||||||
1419 | } | ||||||||||||
1420 | |||||||||||||
1421 | if ( rElement.m_bFloating ) | ||||||||||||
1422 | { | ||||||||||||
1423 | if ( pWindow ) | ||||||||||||
1424 | { | ||||||||||||
1425 | SolarMutexGuard aGuard; | ||||||||||||
1426 | OUString aText = pWindow->GetText(); | ||||||||||||
1427 | if ( aText.isEmpty() ) | ||||||||||||
1428 | pWindow->SetText( rElement.m_aUIName ); | ||||||||||||
1429 | } | ||||||||||||
1430 | |||||||||||||
1431 | awt::Point aPos(rElement.m_aFloatingData.m_aPos); | ||||||||||||
1432 | bool bWriteData( false ); | ||||||||||||
1433 | bool bUndefPos = hasDefaultPosValue( rElement.m_aFloatingData.m_aPos ); | ||||||||||||
1434 | bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width != 0 && | ||||||||||||
1435 | rElement.m_aFloatingData.m_aSize.Height != 0 ); | ||||||||||||
1436 | rDockWindow->setFloatingMode( true ); | ||||||||||||
1437 | if ( bUndefPos ) | ||||||||||||
1438 | { | ||||||||||||
1439 | aPos = implts_findNextCascadeFloatingPos(); | ||||||||||||
1440 | rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position | ||||||||||||
1441 | bWriteData = true; | ||||||||||||
1442 | } | ||||||||||||
1443 | |||||||||||||
1444 | if( bSetSize ) | ||||||||||||
1445 | xWindow->setOutputSize(rElement.m_aFloatingData.m_aSize); | ||||||||||||
1446 | else | ||||||||||||
1447 | { | ||||||||||||
1448 | if( pToolBox ) | ||||||||||||
1449 | { | ||||||||||||
1450 | // set an optimal initial floating size | ||||||||||||
1451 | SolarMutexGuard aGuard; | ||||||||||||
1452 | ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() ); | ||||||||||||
1453 | pToolBox->SetOutputSizePixel( aSize ); | ||||||||||||
1454 | } | ||||||||||||
1455 | } | ||||||||||||
1456 | |||||||||||||
1457 | // #i60882# IMPORTANT: Set position after size as it is | ||||||||||||
1458 | // possible that we position some part of the toolbar | ||||||||||||
1459 | // outside of the desktop. A default constructed toolbar | ||||||||||||
1460 | // always has one line. Now VCL automatically | ||||||||||||
1461 | // position the toolbar back into the desktop. Therefore | ||||||||||||
1462 | // we resize the toolbar with the new (wrong) position. | ||||||||||||
1463 | // To fix this problem we have to set the size BEFORE the | ||||||||||||
1464 | // position. | ||||||||||||
1465 | xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS ); | ||||||||||||
1466 | |||||||||||||
1467 | if ( bWriteData ) | ||||||||||||
1468 | implts_writeWindowStateData( rElement ); | ||||||||||||
1469 | if ( bShowElement && pWindow ) | ||||||||||||
1470 | { | ||||||||||||
1471 | SolarMutexGuard aGuard; | ||||||||||||
1472 | pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate ); | ||||||||||||
1473 | } | ||||||||||||
1474 | } | ||||||||||||
1475 | else | ||||||||||||
1476 | { | ||||||||||||
1477 | bool bSetSize( false ); | ||||||||||||
1478 | ::Point aPixelPos; | ||||||||||||
1479 | ::Size aSize; | ||||||||||||
1480 | |||||||||||||
1481 | if ( pToolBox ) | ||||||||||||
1482 | { | ||||||||||||
1483 | SolarMutexGuard aGuard; | ||||||||||||
1484 | pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea ) ); | ||||||||||||
1485 | pToolBox->SetLineCount( 1 ); | ||||||||||||
1486 | rDockWindow->setFloatingMode( false ); | ||||||||||||
1487 | if ( rElement.m_aDockedData.m_bLocked ) | ||||||||||||
1488 | rDockWindow->lock(); | ||||||||||||
1489 | aSize = pToolBox->CalcWindowSizePixel(); | ||||||||||||
1490 | bSetSize = true; | ||||||||||||
1491 | |||||||||||||
1492 | if ( isDefaultPos( rElement.m_aDockedData.m_aPos )) | ||||||||||||
1493 | { | ||||||||||||
1494 | awt::Point aDockPos; | ||||||||||||
1495 | implts_findNextDockingPos( rElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos ); | ||||||||||||
1496 | rElement.m_aDockedData.m_aPos = aDockPos; | ||||||||||||
1497 | } | ||||||||||||
1498 | } | ||||||||||||
1499 | |||||||||||||
1500 | xWindow->setPosSize( aPixelPos.X(), aPixelPos.Y(), 0, 0, awt::PosSize::POS ); | ||||||||||||
1501 | if( bSetSize ) | ||||||||||||
1502 | xWindow->setOutputSize( AWTSize( aSize) ); | ||||||||||||
1503 | |||||||||||||
1504 | if ( pWindow ) | ||||||||||||
1505 | { | ||||||||||||
1506 | SolarMutexGuard aGuard; | ||||||||||||
1507 | if ( !bShowElement ) | ||||||||||||
1508 | pWindow->Hide(); | ||||||||||||
1509 | } | ||||||||||||
1510 | } | ||||||||||||
1511 | } | ||||||||||||
1512 | |||||||||||||
1513 | void ToolbarLayoutManager::implts_destroyDockingAreaWindows() | ||||||||||||
1514 | { | ||||||||||||
1515 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
1516 | uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] ); | ||||||||||||
1517 | uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] ); | ||||||||||||
1518 | uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)] ); | ||||||||||||
1519 | uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)] ); | ||||||||||||
1520 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)].clear(); | ||||||||||||
1521 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)].clear(); | ||||||||||||
1522 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)].clear(); | ||||||||||||
1523 | m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)].clear(); | ||||||||||||
1524 | aWriteLock.clear(); | ||||||||||||
1525 | |||||||||||||
1526 | // destroy windows | ||||||||||||
1527 | xTopDockingWindow->dispose(); | ||||||||||||
1528 | xLeftDockingWindow->dispose(); | ||||||||||||
1529 | xRightDockingWindow->dispose(); | ||||||||||||
1530 | xBottomDockingWindow->dispose(); | ||||||||||||
1531 | } | ||||||||||||
1532 | |||||||||||||
1533 | // persistence methods | ||||||||||||
1534 | |||||||||||||
1535 | bool ToolbarLayoutManager::implts_readWindowStateData( const OUString& aName, UIElement& rElementData ) | ||||||||||||
1536 | { | ||||||||||||
1537 | return LayoutManager::readWindowStateData( aName, rElementData, m_xPersistentWindowState, | ||||||||||||
1538 | m_pGlobalSettings, m_bGlobalSettings, m_xContext ); | ||||||||||||
1539 | } | ||||||||||||
1540 | |||||||||||||
1541 | void ToolbarLayoutManager::implts_writeWindowStateData( const UIElement& rElementData ) | ||||||||||||
1542 | { | ||||||||||||
1543 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
1544 | uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); | ||||||||||||
1545 | aWriteLock.clear(); | ||||||||||||
1546 | |||||||||||||
1547 | bool bPersistent( false ); | ||||||||||||
1548 | uno::Reference< beans::XPropertySet > xPropSet( rElementData.m_xUIElement, uno::UNO_QUERY ); | ||||||||||||
1549 | if ( xPropSet.is() ) | ||||||||||||
1550 | { | ||||||||||||
1551 | try | ||||||||||||
1552 | { | ||||||||||||
1553 | // Check persistent flag of the user interface element | ||||||||||||
1554 | xPropSet->getPropertyValue("Persistent") >>= bPersistent; | ||||||||||||
1555 | } | ||||||||||||
1556 | catch (const beans::UnknownPropertyException&) | ||||||||||||
1557 | { | ||||||||||||
1558 | bPersistent = true; // Non-configurable elements should at least store their dimension/position | ||||||||||||
1559 | } | ||||||||||||
1560 | catch (const lang::WrappedTargetException&) | ||||||||||||
1561 | { | ||||||||||||
1562 | } | ||||||||||||
1563 | } | ||||||||||||
1564 | |||||||||||||
1565 | if ( !(bPersistent && xPersistentWindowState.is()) ) | ||||||||||||
1566 | return; | ||||||||||||
1567 | |||||||||||||
1568 | try | ||||||||||||
1569 | { | ||||||||||||
1570 | uno::Sequence< beans::PropertyValue > aWindowState( 9 ); | ||||||||||||
1571 | |||||||||||||
1572 | aWindowState[0].Name = WINDOWSTATE_PROPERTY_DOCKED"Docked"; | ||||||||||||
1573 | aWindowState[0].Value <<= !rElementData.m_bFloating; | ||||||||||||
1574 | aWindowState[1].Name = WINDOWSTATE_PROPERTY_VISIBLE"Visible"; | ||||||||||||
1575 | aWindowState[1].Value <<= rElementData.m_bVisible; | ||||||||||||
1576 | aWindowState[2].Name = WINDOWSTATE_PROPERTY_DOCKINGAREA"DockingArea"; | ||||||||||||
1577 | aWindowState[2].Value <<= rElementData.m_aDockedData.m_nDockedArea; | ||||||||||||
1578 | |||||||||||||
1579 | awt::Point aPos = rElementData.m_aDockedData.m_aPos; | ||||||||||||
1580 | aWindowState[3].Name = WINDOWSTATE_PROPERTY_DOCKPOS"DockPos"; | ||||||||||||
1581 | aWindowState[3].Value <<= aPos; | ||||||||||||
1582 | |||||||||||||
1583 | aPos = rElementData.m_aFloatingData.m_aPos; | ||||||||||||
1584 | aWindowState[4].Name = WINDOWSTATE_PROPERTY_POS"Pos"; | ||||||||||||
1585 | aWindowState[4].Value <<= aPos; | ||||||||||||
1586 | |||||||||||||
1587 | aWindowState[5].Name = WINDOWSTATE_PROPERTY_SIZE"Size"; | ||||||||||||
1588 | aWindowState[5].Value <<= rElementData.m_aFloatingData.m_aSize; | ||||||||||||
1589 | aWindowState[6].Name = WINDOWSTATE_PROPERTY_UINAME"UIName"; | ||||||||||||
1590 | aWindowState[6].Value <<= rElementData.m_aUIName; | ||||||||||||
1591 | aWindowState[7].Name = WINDOWSTATE_PROPERTY_LOCKED"Locked"; | ||||||||||||
1592 | aWindowState[7].Value <<= rElementData.m_aDockedData.m_bLocked; | ||||||||||||
1593 | aWindowState[8].Name = WINDOWSTATE_PROPERTY_STYLE"Style"; | ||||||||||||
1594 | aWindowState[8].Value <<= static_cast<sal_uInt16>(rElementData.m_nStyle); | ||||||||||||
1595 | |||||||||||||
1596 | OUString aName = rElementData.m_aName; | ||||||||||||
1597 | if ( xPersistentWindowState->hasByName( aName )) | ||||||||||||
1598 | { | ||||||||||||
1599 | uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY ); | ||||||||||||
1600 | xReplace->replaceByName( aName, uno::makeAny( aWindowState )); | ||||||||||||
1601 | } | ||||||||||||
1602 | else | ||||||||||||
1603 | { | ||||||||||||
1604 | uno::Reference< container::XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY ); | ||||||||||||
1605 | xInsert->insertByName( aName, uno::makeAny( aWindowState )); | ||||||||||||
1606 | } | ||||||||||||
1607 | } | ||||||||||||
1608 | catch (const uno::Exception&) | ||||||||||||
1609 | { | ||||||||||||
1610 | } | ||||||||||||
1611 | } | ||||||||||||
1612 | |||||||||||||
1613 | /****************************************************************************** | ||||||||||||
1614 | LOOKUP PART FOR TOOLBARS | ||||||||||||
1615 | ******************************************************************************/ | ||||||||||||
1616 | |||||||||||||
1617 | UIElement& ToolbarLayoutManager::impl_findToolbar( const OUString& aName ) | ||||||||||||
1618 | { | ||||||||||||
1619 | static UIElement aEmptyElement; | ||||||||||||
1620 | |||||||||||||
1621 | SolarMutexGuard g; | ||||||||||||
1622 | for (auto & elem : m_aUIElements) | ||||||||||||
1623 | { | ||||||||||||
1624 | if ( elem.m_aName == aName ) | ||||||||||||
1625 | return elem; | ||||||||||||
1626 | } | ||||||||||||
1627 | |||||||||||||
1628 | return aEmptyElement; | ||||||||||||
1629 | } | ||||||||||||
1630 | |||||||||||||
1631 | UIElement ToolbarLayoutManager::implts_findToolbar( const OUString& aName ) | ||||||||||||
1632 | { | ||||||||||||
1633 | SolarMutexGuard g; | ||||||||||||
1634 | return impl_findToolbar( aName ); | ||||||||||||
1635 | } | ||||||||||||
1636 | |||||||||||||
1637 | UIElement ToolbarLayoutManager::implts_findToolbar( const uno::Reference< uno::XInterface >& xToolbar ) | ||||||||||||
1638 | { | ||||||||||||
1639 | UIElement aToolbar; | ||||||||||||
1640 | |||||||||||||
1641 | SolarMutexGuard g; | ||||||||||||
1642 | for (auto const& elem : m_aUIElements) | ||||||||||||
1643 | { | ||||||||||||
1644 | if ( elem.m_xUIElement.is() ) | ||||||||||||
1645 | { | ||||||||||||
1646 | uno::Reference< uno::XInterface > xIfac( elem.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
1647 | if ( xIfac == xToolbar ) | ||||||||||||
1648 | { | ||||||||||||
1649 | aToolbar = elem; | ||||||||||||
1650 | break; | ||||||||||||
1651 | } | ||||||||||||
1652 | } | ||||||||||||
1653 | } | ||||||||||||
1654 | |||||||||||||
1655 | return aToolbar; | ||||||||||||
1656 | } | ||||||||||||
1657 | |||||||||||||
1658 | uno::Reference< awt::XWindow > ToolbarLayoutManager::implts_getXWindow( const OUString& aName ) | ||||||||||||
1659 | { | ||||||||||||
1660 | uno::Reference< awt::XWindow > xWindow; | ||||||||||||
1661 | |||||||||||||
1662 | SolarMutexGuard g; | ||||||||||||
1663 | for (auto const& elem : m_aUIElements) | ||||||||||||
1664 | { | ||||||||||||
1665 | if ( elem.m_aName == aName && elem.m_xUIElement.is() ) | ||||||||||||
1666 | { | ||||||||||||
1667 | xWindow.set( elem.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
1668 | break; | ||||||||||||
1669 | } | ||||||||||||
1670 | } | ||||||||||||
1671 | |||||||||||||
1672 | return xWindow; | ||||||||||||
1673 | } | ||||||||||||
1674 | |||||||||||||
1675 | vcl::Window* ToolbarLayoutManager::implts_getWindow( const OUString& aName ) | ||||||||||||
1676 | { | ||||||||||||
1677 | uno::Reference< awt::XWindow > xWindow = implts_getXWindow( aName ); | ||||||||||||
1678 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
1679 | |||||||||||||
1680 | return pWindow; | ||||||||||||
1681 | } | ||||||||||||
1682 | |||||||||||||
1683 | bool ToolbarLayoutManager::implts_insertToolbar( const UIElement& rUIElement ) | ||||||||||||
1684 | { | ||||||||||||
1685 | UIElement aTempData; | ||||||||||||
1686 | bool bFound( false ); | ||||||||||||
1687 | bool bResult( false ); | ||||||||||||
1688 | |||||||||||||
1689 | aTempData = implts_findToolbar( rUIElement.m_aName ); | ||||||||||||
1690 | if ( aTempData.m_aName == rUIElement.m_aName ) | ||||||||||||
1691 | bFound = true; | ||||||||||||
1692 | |||||||||||||
1693 | if ( !bFound ) | ||||||||||||
1694 | { | ||||||||||||
1695 | SolarMutexGuard g; | ||||||||||||
1696 | m_aUIElements.push_back( rUIElement ); | ||||||||||||
1697 | bResult = true; | ||||||||||||
1698 | } | ||||||||||||
1699 | |||||||||||||
1700 | return bResult; | ||||||||||||
1701 | } | ||||||||||||
1702 | |||||||||||||
1703 | void ToolbarLayoutManager::implts_setToolbar( const UIElement& rUIElement ) | ||||||||||||
1704 | { | ||||||||||||
1705 | SolarMutexGuard g; | ||||||||||||
1706 | UIElement& rData = impl_findToolbar( rUIElement.m_aName ); | ||||||||||||
1707 | if ( rData.m_aName == rUIElement.m_aName ) | ||||||||||||
1708 | rData = rUIElement; | ||||||||||||
1709 | else | ||||||||||||
1710 | m_aUIElements.push_back( rUIElement ); | ||||||||||||
1711 | } | ||||||||||||
1712 | |||||||||||||
1713 | /****************************************************************************** | ||||||||||||
1714 | LAYOUT CODE PART FOR TOOLBARS | ||||||||||||
1715 | ******************************************************************************/ | ||||||||||||
1716 | |||||||||||||
1717 | awt::Point ToolbarLayoutManager::implts_findNextCascadeFloatingPos() | ||||||||||||
1718 | { | ||||||||||||
1719 | const sal_Int32 nHotZoneX = 50; | ||||||||||||
1720 | const sal_Int32 nHotZoneY = 50; | ||||||||||||
1721 | const sal_Int32 nCascadeIndentX = 15; | ||||||||||||
1722 | const sal_Int32 nCascadeIndentY = 15; | ||||||||||||
1723 | |||||||||||||
1724 | SolarMutexClearableGuard aReadLock; | ||||||||||||
1725 | uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); | ||||||||||||
1726 | uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] ); | ||||||||||||
1727 | uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] ); | ||||||||||||
1728 | aReadLock.clear(); | ||||||||||||
1729 | |||||||||||||
1730 | awt::Point aStartPos( nCascadeIndentX, nCascadeIndentY ); | ||||||||||||
1731 | awt::Point aCurrPos( aStartPos ); | ||||||||||||
1732 | |||||||||||||
1733 | if ( xContainerWindow.is() ) | ||||||||||||
1734 | { | ||||||||||||
1735 | SolarMutexGuard aGuard; | ||||||||||||
1736 | VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); | ||||||||||||
1737 | if ( pContainerWindow ) | ||||||||||||
1738 | aStartPos = AWTPoint(pContainerWindow->OutputToScreenPixel(VCLPoint(aStartPos))); | ||||||||||||
1739 | } | ||||||||||||
1740 | |||||||||||||
1741 | // Determine size of top and left docking area | ||||||||||||
1742 | awt::Rectangle aTopRect( xTopDockingWindow->getPosSize() ); | ||||||||||||
1743 | awt::Rectangle aLeftRect( xLeftDockingWindow->getPosSize() ); | ||||||||||||
1744 | |||||||||||||
1745 | aStartPos.X += aLeftRect.Width + nCascadeIndentX; | ||||||||||||
1746 | aStartPos.Y += aTopRect.Height + nCascadeIndentY; | ||||||||||||
1747 | aCurrPos = aStartPos; | ||||||||||||
1748 | |||||||||||||
1749 | // Try to find a cascaded position for the new floating window | ||||||||||||
1750 | for (auto const& elem : m_aUIElements) | ||||||||||||
1751 | { | ||||||||||||
1752 | if ( elem.m_xUIElement.is() ) | ||||||||||||
1753 | { | ||||||||||||
1754 | uno::Reference< awt::XDockableWindow > xDockWindow( elem.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
1755 | uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY ); | ||||||||||||
1756 | if ( xDockWindow.is() && xDockWindow->isFloating() ) | ||||||||||||
1757 | { | ||||||||||||
1758 | SolarMutexGuard aGuard; | ||||||||||||
1759 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
1760 | if ( pWindow && pWindow->IsVisible() ) | ||||||||||||
1761 | { | ||||||||||||
1762 | awt::Rectangle aFloatRect = xWindow->getPosSize(); | ||||||||||||
1763 | if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X ) && | ||||||||||||
1764 | ( aFloatRect.X >= aCurrPos.X ) && | ||||||||||||
1765 | (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y ) && | ||||||||||||
1766 | ( aFloatRect.Y >= aCurrPos.Y )) | ||||||||||||
1767 | { | ||||||||||||
1768 | aCurrPos.X = aFloatRect.X + nCascadeIndentX; | ||||||||||||
1769 | aCurrPos.Y = aFloatRect.Y + nCascadeIndentY; | ||||||||||||
1770 | } | ||||||||||||
1771 | } | ||||||||||||
1772 | } | ||||||||||||
1773 | } | ||||||||||||
1774 | } | ||||||||||||
1775 | |||||||||||||
1776 | return aCurrPos; | ||||||||||||
1777 | } | ||||||||||||
1778 | |||||||||||||
1779 | void ToolbarLayoutManager::implts_sortUIElements() | ||||||||||||
1780 | { | ||||||||||||
1781 | SolarMutexGuard g; | ||||||||||||
1782 | |||||||||||||
1783 | std::stable_sort( m_aUIElements.begin(), m_aUIElements.end()); // first created element should first | ||||||||||||
1784 | |||||||||||||
1785 | // We have to reset our temporary flags. | ||||||||||||
1786 | for (auto & elem : m_aUIElements) | ||||||||||||
1787 | elem.m_bUserActive = false; | ||||||||||||
1788 | } | ||||||||||||
1789 | |||||||||||||
1790 | void ToolbarLayoutManager::implts_getUIElementVectorCopy( UIElementVector& rCopy ) | ||||||||||||
1791 | { | ||||||||||||
1792 | SolarMutexGuard g; | ||||||||||||
1793 | rCopy = m_aUIElements; | ||||||||||||
1794 | } | ||||||||||||
1795 | |||||||||||||
1796 | ::Size ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes() | ||||||||||||
1797 | { | ||||||||||||
1798 | ::Size aSize; | ||||||||||||
1799 | uno::Reference< awt::XWindow > xTopDockingAreaWindow; | ||||||||||||
1800 | uno::Reference< awt::XWindow > xBottomDockingAreaWindow; | ||||||||||||
1801 | |||||||||||||
1802 | { | ||||||||||||
1803 | SolarMutexGuard aReadLock; | ||||||||||||
1804 | xTopDockingAreaWindow = m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)]; | ||||||||||||
1805 | xBottomDockingAreaWindow = m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)]; | ||||||||||||
1806 | } | ||||||||||||
1807 | |||||||||||||
1808 | if ( xTopDockingAreaWindow.is() ) | ||||||||||||
1809 | aSize.setWidth( xTopDockingAreaWindow->getPosSize().Height ); | ||||||||||||
1810 | if ( xBottomDockingAreaWindow.is() ) | ||||||||||||
1811 | aSize.setHeight( xBottomDockingAreaWindow->getPosSize().Height ); | ||||||||||||
1812 | |||||||||||||
1813 | return aSize; | ||||||||||||
1814 | } | ||||||||||||
1815 | |||||||||||||
1816 | void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData ) | ||||||||||||
1817 | { | ||||||||||||
1818 | std::vector< UIElement > aWindowVector; | ||||||||||||
1819 | |||||||||||||
1820 | if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) | ||||||||||||
1821 | eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
1822 | |||||||||||||
1823 | uno::Reference< awt::XWindow > xDockAreaWindow; | ||||||||||||
1824 | |||||||||||||
1825 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
1826 | { | ||||||||||||
1827 | SolarMutexGuard aReadLock; | ||||||||||||
1828 | aWindowVector.reserve(m_aUIElements.size()); | ||||||||||||
1829 | xDockAreaWindow = m_xDockAreaWindows[static_cast<int>(eDockingArea)]; | ||||||||||||
1830 | for (auto const& elem : m_aUIElements) | ||||||||||||
1831 | { | ||||||||||||
1832 | if (elem.m_aDockedData.m_nDockedArea == eDockingArea && elem.m_bVisible) | ||||||||||||
1833 | { | ||||||||||||
1834 | uno::Reference<ui::XUIElement> xUIElement(elem.m_xUIElement); | ||||||||||||
1835 | if (xUIElement.is()) | ||||||||||||
1836 | { | ||||||||||||
1837 | uno::Reference<awt::XWindow> xWindow(xUIElement->getRealInterface(), | ||||||||||||
1838 | uno::UNO_QUERY); | ||||||||||||
1839 | uno::Reference<awt::XDockableWindow> xDockWindow(xWindow, uno::UNO_QUERY); | ||||||||||||
1840 | if (xDockWindow.is()) | ||||||||||||
1841 | { | ||||||||||||
1842 | if (!elem.m_bFloating) | ||||||||||||
1843 | { | ||||||||||||
1844 | // docked windows | ||||||||||||
1845 | aWindowVector.push_back(elem); | ||||||||||||
1846 | } | ||||||||||||
1847 | else | ||||||||||||
1848 | { | ||||||||||||
1849 | // floating windows | ||||||||||||
1850 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow); | ||||||||||||
1851 | DockingManager* pDockMgr = vcl::Window::GetDockingManager(); | ||||||||||||
1852 | if (pDockMgr != nullptr) | ||||||||||||
1853 | { | ||||||||||||
1854 | ImplDockingWindowWrapper* pWrapper | ||||||||||||
1855 | = pDockMgr->GetDockingWindowWrapper(pWindow); | ||||||||||||
1856 | if (pWrapper != nullptr && pWrapper->GetFloatingWindow()) | ||||||||||||
1857 | { | ||||||||||||
1858 | // update the position data of the floating window | ||||||||||||
1859 | if (pWrapper->GetFloatingWindow()->UpdatePositionData()) | ||||||||||||
1860 | { | ||||||||||||
1861 | awt::Rectangle aTmpRect = xWindow->getPosSize(); | ||||||||||||
1862 | UIElement uiElem = elem; | ||||||||||||
1863 | uiElem.m_aFloatingData.m_aPos | ||||||||||||
1864 | = awt::Point(aTmpRect.X, aTmpRect.Y); | ||||||||||||
1865 | implts_setToolbar(uiElem); | ||||||||||||
1866 | implts_writeWindowStateData(uiElem); | ||||||||||||
1867 | } | ||||||||||||
1868 | } | ||||||||||||
1869 | } | ||||||||||||
1870 | } | ||||||||||||
1871 | } | ||||||||||||
1872 | } | ||||||||||||
1873 | } | ||||||||||||
1874 | } | ||||||||||||
1875 | } | ||||||||||||
1876 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
1877 | |||||||||||||
1878 | rRowColumnsWindowData.clear(); | ||||||||||||
1879 | |||||||||||||
1880 | // Collect data from windows that are on the same row/column | ||||||||||||
1881 | sal_Int32 j; | ||||||||||||
1882 | sal_Int32 nIndex( 0 ); | ||||||||||||
1883 | sal_Int32 nLastPos( 0 ); | ||||||||||||
1884 | sal_Int32 nCurrPos( -1 ); | ||||||||||||
1885 | sal_Int32 nLastRowColPixelPos( 0 ); | ||||||||||||
1886 | awt::Rectangle aDockAreaRect; | ||||||||||||
1887 | |||||||||||||
1888 | if ( xDockAreaWindow.is() ) | ||||||||||||
1889 | aDockAreaRect = xDockAreaWindow->getPosSize(); | ||||||||||||
1890 | |||||||||||||
1891 | if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
1892 | nLastRowColPixelPos = 0; | ||||||||||||
1893 | else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) | ||||||||||||
1894 | nLastRowColPixelPos = aDockAreaRect.Height; | ||||||||||||
1895 | else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
1896 | nLastRowColPixelPos = 0; | ||||||||||||
1897 | else | ||||||||||||
1898 | nLastRowColPixelPos = aDockAreaRect.Width; | ||||||||||||
1899 | |||||||||||||
1900 | const sal_uInt32 nCount = aWindowVector.size(); | ||||||||||||
1901 | for ( j = 0; j < sal_Int32( nCount); j++ ) | ||||||||||||
1902 | { | ||||||||||||
1903 | const UIElement& rElement = aWindowVector[j]; | ||||||||||||
1904 | uno::Reference< awt::XWindow > xWindow; | ||||||||||||
1905 | uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement ); | ||||||||||||
1906 | awt::Rectangle aPosSize; | ||||||||||||
1907 | |||||||||||||
1908 | if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) | ||||||||||||
1909 | continue; | ||||||||||||
1910 | if ( isHorizontalDockingArea( eDockingArea )) | ||||||||||||
1911 | { | ||||||||||||
1912 | if ( nCurrPos == -1 ) | ||||||||||||
1913 | { | ||||||||||||
1914 | nCurrPos = rElement.m_aDockedData.m_aPos.Y; | ||||||||||||
1915 | nLastPos = 0; | ||||||||||||
1916 | |||||||||||||
1917 | SingleRowColumnWindowData aRowColumnWindowData; | ||||||||||||
1918 | aRowColumnWindowData.nRowColumn = nCurrPos; | ||||||||||||
1919 | rRowColumnsWindowData.push_back( aRowColumnWindowData ); | ||||||||||||
1920 | } | ||||||||||||
1921 | |||||||||||||
1922 | sal_Int32 nSpace( 0 ); | ||||||||||||
1923 | if ( rElement.m_aDockedData.m_aPos.Y != nCurrPos ) | ||||||||||||
1924 | { | ||||||||||||
1925 | if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
1926 | nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; | ||||||||||||
1927 | else | ||||||||||||
1928 | nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; | ||||||||||||
1929 | ++nIndex; | ||||||||||||
1930 | nLastPos = 0; | ||||||||||||
1931 | nCurrPos = rElement.m_aDockedData.m_aPos.Y; | ||||||||||||
1932 | SingleRowColumnWindowData aRowColumnWindowData; | ||||||||||||
1933 | aRowColumnWindowData.nRowColumn = nCurrPos; | ||||||||||||
1934 | rRowColumnsWindowData.push_back( aRowColumnWindowData ); | ||||||||||||
1935 | } | ||||||||||||
1936 | |||||||||||||
1937 | // Calc space before an element and store it | ||||||||||||
1938 | nSpace = ( rElement.m_aDockedData.m_aPos.X - nLastPos ); | ||||||||||||
1939 | if ( rElement.m_aDockedData.m_aPos.X >= nLastPos ) | ||||||||||||
1940 | { | ||||||||||||
1941 | rRowColumnsWindowData[nIndex].nSpace += nSpace; | ||||||||||||
1942 | nLastPos = rElement.m_aDockedData.m_aPos.X + aPosSize.Width; | ||||||||||||
1943 | } | ||||||||||||
1944 | else | ||||||||||||
1945 | { | ||||||||||||
1946 | nSpace = 0; | ||||||||||||
1947 | nLastPos += aPosSize.Width; | ||||||||||||
1948 | } | ||||||||||||
1949 | rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); | ||||||||||||
1950 | |||||||||||||
1951 | rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); | ||||||||||||
1952 | rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); | ||||||||||||
1953 | rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.emplace_back( | ||||||||||||
1954 | rElement.m_aDockedData.m_aPos.X, | ||||||||||||
1955 | rElement.m_aDockedData.m_aPos.Y, | ||||||||||||
1956 | aPosSize.Width, | ||||||||||||
1957 | aPosSize.Height ); | ||||||||||||
1958 | if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height ) | ||||||||||||
1959 | rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height; | ||||||||||||
1960 | if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
1961 | rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, nLastRowColPixelPos, | ||||||||||||
1962 | aDockAreaRect.Width, aPosSize.Height ); | ||||||||||||
1963 | else | ||||||||||||
1964 | rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ), | ||||||||||||
1965 | aDockAreaRect.Width, aPosSize.Height ); | ||||||||||||
1966 | rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace; | ||||||||||||
1967 | } | ||||||||||||
1968 | else | ||||||||||||
1969 | { | ||||||||||||
1970 | if ( nCurrPos == -1 ) | ||||||||||||
1971 | { | ||||||||||||
1972 | nCurrPos = rElement.m_aDockedData.m_aPos.X; | ||||||||||||
1973 | nLastPos = 0; | ||||||||||||
1974 | |||||||||||||
1975 | SingleRowColumnWindowData aRowColumnWindowData; | ||||||||||||
1976 | aRowColumnWindowData.nRowColumn = nCurrPos; | ||||||||||||
1977 | rRowColumnsWindowData.push_back( aRowColumnWindowData ); | ||||||||||||
1978 | } | ||||||||||||
1979 | |||||||||||||
1980 | sal_Int32 nSpace( 0 ); | ||||||||||||
1981 | if ( rElement.m_aDockedData.m_aPos.X != nCurrPos ) | ||||||||||||
1982 | { | ||||||||||||
1983 | if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
1984 | nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; | ||||||||||||
1985 | else | ||||||||||||
1986 | nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; | ||||||||||||
1987 | ++nIndex; | ||||||||||||
1988 | nLastPos = 0; | ||||||||||||
1989 | nCurrPos = rElement.m_aDockedData.m_aPos.X; | ||||||||||||
1990 | SingleRowColumnWindowData aRowColumnWindowData; | ||||||||||||
1991 | aRowColumnWindowData.nRowColumn = nCurrPos; | ||||||||||||
1992 | rRowColumnsWindowData.push_back( aRowColumnWindowData ); | ||||||||||||
1993 | } | ||||||||||||
1994 | |||||||||||||
1995 | // Calc space before an element and store it | ||||||||||||
1996 | nSpace = ( rElement.m_aDockedData.m_aPos.Y - nLastPos ); | ||||||||||||
1997 | if ( rElement.m_aDockedData.m_aPos.Y > nLastPos ) | ||||||||||||
1998 | { | ||||||||||||
1999 | rRowColumnsWindowData[nIndex].nSpace += nSpace; | ||||||||||||
2000 | nLastPos = rElement.m_aDockedData.m_aPos.Y + aPosSize.Height; | ||||||||||||
2001 | } | ||||||||||||
2002 | else | ||||||||||||
2003 | { | ||||||||||||
2004 | nSpace = 0; | ||||||||||||
2005 | nLastPos += aPosSize.Height; | ||||||||||||
2006 | } | ||||||||||||
2007 | rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); | ||||||||||||
2008 | |||||||||||||
2009 | rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); | ||||||||||||
2010 | rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); | ||||||||||||
2011 | rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.emplace_back( | ||||||||||||
2012 | rElement.m_aDockedData.m_aPos.X, | ||||||||||||
2013 | rElement.m_aDockedData.m_aPos.Y, | ||||||||||||
2014 | aPosSize.Width, | ||||||||||||
2015 | aPosSize.Height ); | ||||||||||||
2016 | if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width ) | ||||||||||||
2017 | rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width; | ||||||||||||
2018 | if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
2019 | rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( nLastRowColPixelPos, 0, | ||||||||||||
2020 | aPosSize.Width, aDockAreaRect.Height ); | ||||||||||||
2021 | else | ||||||||||||
2022 | rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0, | ||||||||||||
2023 | aPosSize.Width, aDockAreaRect.Height ); | ||||||||||||
2024 | rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace; | ||||||||||||
2025 | } | ||||||||||||
2026 | } | ||||||||||||
2027 | } | ||||||||||||
2028 | |||||||||||||
2029 | void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData ) | ||||||||||||
2030 | { | ||||||||||||
2031 | std::vector< UIElement > aWindowVector; | ||||||||||||
2032 | |||||||||||||
2033 | if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) | ||||||||||||
2034 | eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
2035 | |||||||||||||
2036 | bool bHorzDockArea = isHorizontalDockingArea( eDockingArea ); | ||||||||||||
2037 | |||||||||||||
2038 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
2039 | { | ||||||||||||
2040 | SolarMutexGuard aReadLock; | ||||||||||||
2041 | for (auto const& elem : m_aUIElements) | ||||||||||||
2042 | { | ||||||||||||
2043 | if (elem.m_aDockedData.m_nDockedArea == eDockingArea) | ||||||||||||
2044 | { | ||||||||||||
2045 | bool bSameRowCol = bHorzDockArea ? (elem.m_aDockedData.m_aPos.Y == nRowCol) | ||||||||||||
2046 | : (elem.m_aDockedData.m_aPos.X == nRowCol); | ||||||||||||
2047 | uno::Reference<ui::XUIElement> xUIElement(elem.m_xUIElement); | ||||||||||||
2048 | |||||||||||||
2049 | if (bSameRowCol && xUIElement.is()) | ||||||||||||
2050 | { | ||||||||||||
2051 | uno::Reference<awt::XWindow> xWindow(xUIElement->getRealInterface(), | ||||||||||||
2052 | uno::UNO_QUERY); | ||||||||||||
2053 | if (xWindow.is()) | ||||||||||||
2054 | { | ||||||||||||
2055 | SolarMutexGuard aGuard; | ||||||||||||
2056 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow); | ||||||||||||
2057 | uno::Reference<awt::XDockableWindow> xDockWindow(xWindow, uno::UNO_QUERY); | ||||||||||||
2058 | if (pWindow && elem.m_bVisible && xDockWindow.is() && !elem.m_bFloating) | ||||||||||||
2059 | aWindowVector.push_back(elem); // docked windows | ||||||||||||
2060 | } | ||||||||||||
2061 | } | ||||||||||||
2062 | } | ||||||||||||
2063 | } | ||||||||||||
2064 | } | ||||||||||||
2065 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
2066 | |||||||||||||
2067 | // Initialize structure | ||||||||||||
2068 | rRowColumnWindowData.aUIElementNames.clear(); | ||||||||||||
2069 | rRowColumnWindowData.aRowColumnWindows.clear(); | ||||||||||||
2070 | rRowColumnWindowData.aRowColumnWindowSizes.clear(); | ||||||||||||
2071 | rRowColumnWindowData.aRowColumnSpace.clear(); | ||||||||||||
2072 | rRowColumnWindowData.nVarSize = 0; | ||||||||||||
2073 | rRowColumnWindowData.nStaticSize = 0; | ||||||||||||
2074 | rRowColumnWindowData.nSpace = 0; | ||||||||||||
2075 | rRowColumnWindowData.nRowColumn = nRowCol; | ||||||||||||
2076 | |||||||||||||
2077 | // Collect data from windows that are on the same row/column | ||||||||||||
2078 | sal_Int32 j; | ||||||||||||
2079 | sal_Int32 nLastPos( 0 ); | ||||||||||||
2080 | |||||||||||||
2081 | const sal_uInt32 nCount = aWindowVector.size(); | ||||||||||||
2082 | for ( j = 0; j < sal_Int32( nCount); j++ ) | ||||||||||||
2083 | { | ||||||||||||
2084 | const UIElement& rElement = aWindowVector[j]; | ||||||||||||
2085 | uno::Reference< awt::XWindow > xWindow; | ||||||||||||
2086 | uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement ); | ||||||||||||
2087 | awt::Rectangle aPosSize; | ||||||||||||
2088 | if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) | ||||||||||||
2089 | continue; | ||||||||||||
2090 | |||||||||||||
2091 | sal_Int32 nSpace; | ||||||||||||
2092 | if ( isHorizontalDockingArea( eDockingArea )) | ||||||||||||
2093 | { | ||||||||||||
2094 | nSpace = ( rElement.m_aDockedData.m_aPos.X - nLastPos ); | ||||||||||||
2095 | |||||||||||||
2096 | // Calc space before an element and store it | ||||||||||||
2097 | if ( rElement.m_aDockedData.m_aPos.X > nLastPos ) | ||||||||||||
2098 | rRowColumnWindowData.nSpace += nSpace; | ||||||||||||
2099 | else | ||||||||||||
2100 | nSpace = 0; | ||||||||||||
2101 | |||||||||||||
2102 | nLastPos = rElement.m_aDockedData.m_aPos.X + aPosSize.Width; | ||||||||||||
2103 | |||||||||||||
2104 | rRowColumnWindowData.aRowColumnWindowSizes.emplace_back( | ||||||||||||
2105 | rElement.m_aDockedData.m_aPos.X, rElement.m_aDockedData.m_aPos.Y, | ||||||||||||
2106 | aPosSize.Width, aPosSize.Height ); | ||||||||||||
2107 | if ( rRowColumnWindowData.nStaticSize < aPosSize.Height ) | ||||||||||||
2108 | rRowColumnWindowData.nStaticSize = aPosSize.Height; | ||||||||||||
2109 | rRowColumnWindowData.nVarSize += aPosSize.Width; | ||||||||||||
2110 | } | ||||||||||||
2111 | else | ||||||||||||
2112 | { | ||||||||||||
2113 | // Calc space before an element and store it | ||||||||||||
2114 | nSpace = ( rElement.m_aDockedData.m_aPos.Y - nLastPos ); | ||||||||||||
2115 | if ( rElement.m_aDockedData.m_aPos.Y > nLastPos ) | ||||||||||||
2116 | rRowColumnWindowData.nSpace += nSpace; | ||||||||||||
2117 | else | ||||||||||||
2118 | nSpace = 0; | ||||||||||||
2119 | |||||||||||||
2120 | nLastPos = rElement.m_aDockedData.m_aPos.Y + aPosSize.Height; | ||||||||||||
2121 | |||||||||||||
2122 | rRowColumnWindowData.aRowColumnWindowSizes.emplace_back( | ||||||||||||
2123 | rElement.m_aDockedData.m_aPos.X, rElement.m_aDockedData.m_aPos.Y, | ||||||||||||
2124 | aPosSize.Width, aPosSize.Height ); | ||||||||||||
2125 | if ( rRowColumnWindowData.nStaticSize < aPosSize.Width ) | ||||||||||||
2126 | rRowColumnWindowData.nStaticSize = aPosSize.Width; | ||||||||||||
2127 | rRowColumnWindowData.nVarSize += aPosSize.Height; | ||||||||||||
2128 | } | ||||||||||||
2129 | |||||||||||||
2130 | rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName ); | ||||||||||||
2131 | rRowColumnWindowData.aRowColumnWindows.push_back( xWindow ); | ||||||||||||
2132 | rRowColumnWindowData.aRowColumnSpace.push_back( nSpace ); | ||||||||||||
2133 | rRowColumnWindowData.nVarSize += nSpace; | ||||||||||||
2134 | } | ||||||||||||
2135 | } | ||||||||||||
2136 | |||||||||||||
2137 | ::tools::Rectangle ToolbarLayoutManager::implts_getWindowRectFromRowColumn( | ||||||||||||
2138 | ui::DockingArea DockingArea, | ||||||||||||
2139 | const SingleRowColumnWindowData& rRowColumnWindowData, | ||||||||||||
2140 | const ::Point& rMousePos, | ||||||||||||
2141 | const OUString& rExcludeElementName ) | ||||||||||||
2142 | { | ||||||||||||
2143 | ::tools::Rectangle aWinRect; | ||||||||||||
2144 | |||||||||||||
2145 | if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) | ||||||||||||
2146 | DockingArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
2147 | |||||||||||||
2148 | if ( rRowColumnWindowData.aRowColumnWindows.empty() ) | ||||||||||||
2149 | return aWinRect; | ||||||||||||
2150 | else | ||||||||||||
2151 | { | ||||||||||||
2152 | SolarMutexClearableGuard aReadLock; | ||||||||||||
2153 | VclPtr<vcl::Window> pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow )); | ||||||||||||
2154 | VclPtr<vcl::Window> pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows[static_cast<int>(DockingArea)] )); | ||||||||||||
2155 | aReadLock.clear(); | ||||||||||||
2156 | |||||||||||||
2157 | // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect | ||||||||||||
2158 | SolarMutexGuard aGuard; | ||||||||||||
2159 | |||||||||||||
2160 | // Retrieve output size from container Window | ||||||||||||
2161 | if ( pDockingAreaWindow && pContainerWindow ) | ||||||||||||
2162 | { | ||||||||||||
2163 | const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size(); | ||||||||||||
2164 | for ( sal_uInt32 i = 0; i < nCount; i++ ) | ||||||||||||
2165 | { | ||||||||||||
2166 | awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize(); | ||||||||||||
2167 | ::tools::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height ); | ||||||||||||
2168 | aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); | ||||||||||||
2169 | if ( aRect.IsInside( rMousePos )) | ||||||||||||
2170 | { | ||||||||||||
2171 | // Check if we have found the excluded element. If yes, we have to provide an empty rectangle. | ||||||||||||
2172 | // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle! | ||||||||||||
2173 | if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] ) | ||||||||||||
2174 | return aRect; | ||||||||||||
2175 | else | ||||||||||||
2176 | break; | ||||||||||||
2177 | } | ||||||||||||
2178 | } | ||||||||||||
2179 | } | ||||||||||||
2180 | } | ||||||||||||
2181 | |||||||||||||
2182 | return aWinRect; | ||||||||||||
2183 | } | ||||||||||||
2184 | |||||||||||||
2185 | ::tools::Rectangle ToolbarLayoutManager::implts_determineFrontDockingRect( | ||||||||||||
2186 | ui::DockingArea eDockingArea, | ||||||||||||
2187 | sal_Int32 nRowCol, | ||||||||||||
2188 | const ::tools::Rectangle& rDockedElementRect, | ||||||||||||
2189 | const OUString& rMovedElementName, | ||||||||||||
2190 | const ::tools::Rectangle& rMovedElementRect ) | ||||||||||||
2191 | { | ||||||||||||
2192 | SingleRowColumnWindowData aRowColumnWindowData; | ||||||||||||
2193 | |||||||||||||
2194 | bool bHorzDockArea( isHorizontalDockingArea( eDockingArea )); | ||||||||||||
2195 | implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData ); | ||||||||||||
2196 | if ( aRowColumnWindowData.aRowColumnWindows.empty() ) | ||||||||||||
2197 | return rMovedElementRect; | ||||||||||||
2198 | else | ||||||||||||
2199 | { | ||||||||||||
2200 | sal_Int32 nSpace( 0 ); | ||||||||||||
2201 | ::tools::Rectangle aFrontDockingRect( rMovedElementRect ); | ||||||||||||
2202 | const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size(); | ||||||||||||
2203 | for ( sal_uInt32 i = 0; i < nCount; i++ ) | ||||||||||||
2204 | { | ||||||||||||
2205 | if ( bHorzDockArea ) | ||||||||||||
2206 | { | ||||||||||||
2207 | if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() ) | ||||||||||||
2208 | { | ||||||||||||
2209 | nSpace += aRowColumnWindowData.aRowColumnSpace[i]; | ||||||||||||
2210 | break; | ||||||||||||
2211 | } | ||||||||||||
2212 | else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) | ||||||||||||
2213 | nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width + | ||||||||||||
2214 | aRowColumnWindowData.aRowColumnSpace[i]; | ||||||||||||
2215 | else | ||||||||||||
2216 | nSpace = 0; | ||||||||||||
2217 | } | ||||||||||||
2218 | else | ||||||||||||
2219 | { | ||||||||||||
2220 | if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() ) | ||||||||||||
2221 | { | ||||||||||||
2222 | nSpace += aRowColumnWindowData.aRowColumnSpace[i]; | ||||||||||||
2223 | break; | ||||||||||||
2224 | } | ||||||||||||
2225 | else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) | ||||||||||||
2226 | nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height + | ||||||||||||
2227 | aRowColumnWindowData.aRowColumnSpace[i]; | ||||||||||||
2228 | else | ||||||||||||
2229 | nSpace = 0; | ||||||||||||
2230 | } | ||||||||||||
2231 | } | ||||||||||||
2232 | |||||||||||||
2233 | if ( nSpace > 0 ) | ||||||||||||
2234 | { | ||||||||||||
2235 | sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) ); | ||||||||||||
2236 | if ( bHorzDockArea ) | ||||||||||||
2237 | aFrontDockingRect.Move( -nMove, 0 ); | ||||||||||||
2238 | else | ||||||||||||
2239 | aFrontDockingRect.Move( 0, -nMove ); | ||||||||||||
2240 | } | ||||||||||||
2241 | |||||||||||||
2242 | return aFrontDockingRect; | ||||||||||||
2243 | } | ||||||||||||
2244 | } | ||||||||||||
2245 | |||||||||||||
2246 | void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea, const ::Size& aUIElementSize, awt::Point& rVirtualPos, ::Point& rPixelPos ) | ||||||||||||
2247 | { | ||||||||||||
2248 | SolarMutexClearableGuard aReadLock; | ||||||||||||
2249 | if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) | ||||||||||||
2250 | DockingArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
2251 | uno::Reference< awt::XWindow > xDockingWindow( m_xDockAreaWindows[static_cast<int>(DockingArea)] ); | ||||||||||||
2252 | ::Size aDockingWinSize; | ||||||||||||
2253 | |||||||||||||
2254 | // Retrieve output size from container Window | ||||||||||||
2255 | vcl::Window* pDockingWindow = VCLUnoHelper::GetWindow( xDockingWindow ).get(); | ||||||||||||
2256 | if ( pDockingWindow ) | ||||||||||||
2257 | aDockingWinSize = pDockingWindow->GetOutputSizePixel(); | ||||||||||||
2258 | aReadLock.clear(); | ||||||||||||
2259 | |||||||||||||
2260 | sal_Int32 nFreeRowColPixelPos( 0 ); | ||||||||||||
2261 | sal_Int32 nMaxSpace( 0 ); | ||||||||||||
2262 | sal_Int32 nNeededSpace( 0 ); | ||||||||||||
2263 | sal_Int32 nTopDockingAreaSize( 0 ); | ||||||||||||
2264 | |||||||||||||
2265 | if ( isHorizontalDockingArea( DockingArea )) | ||||||||||||
2266 | { | ||||||||||||
2267 | nMaxSpace = aDockingWinSize.Width(); | ||||||||||||
2268 | nNeededSpace = aUIElementSize.Width(); | ||||||||||||
2269 | } | ||||||||||||
2270 | else | ||||||||||||
2271 | { | ||||||||||||
2272 | nMaxSpace = aDockingWinSize.Height(); | ||||||||||||
2273 | nNeededSpace = aUIElementSize.Height(); | ||||||||||||
2274 | nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); | ||||||||||||
2275 | } | ||||||||||||
2276 | |||||||||||||
2277 | std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; | ||||||||||||
2278 | |||||||||||||
2279 | implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData ); | ||||||||||||
2280 | sal_Int32 nPixelPos( 0 ); | ||||||||||||
2281 | const sal_uInt32 nCount = aRowColumnsWindowData.size(); | ||||||||||||
2282 | for ( sal_uInt32 i = 0; i < nCount; i++ ) | ||||||||||||
2283 | { | ||||||||||||
2284 | SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i]; | ||||||||||||
2285 | |||||||||||||
2286 | if (( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || | ||||||||||||
2287 | ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )) | ||||||||||||
2288 | nPixelPos += rRowColumnWindowData.nStaticSize; | ||||||||||||
2289 | |||||||||||||
2290 | if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) || | ||||||||||||
2291 | ( rRowColumnWindowData.nSpace >= nNeededSpace )) | ||||||||||||
2292 | { | ||||||||||||
2293 | // Check current row where we can find the needed space | ||||||||||||
2294 | sal_Int32 nCurrPos( 0 ); | ||||||||||||
2295 | const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); | ||||||||||||
2296 | for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ ) | ||||||||||||
2297 | { | ||||||||||||
2298 | awt::Rectangle rRect = rRowColumnWindowData.aRowColumnWindowSizes[j]; | ||||||||||||
2299 | sal_Int32& rSpace = rRowColumnWindowData.aRowColumnSpace[j]; | ||||||||||||
2300 | if ( isHorizontalDockingArea( DockingArea )) | ||||||||||||
2301 | { | ||||||||||||
2302 | if ( rSpace >= nNeededSpace ) | ||||||||||||
2303 | { | ||||||||||||
2304 | rVirtualPos = awt::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); | ||||||||||||
2305 | if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
2306 | rPixelPos = ::Point( nCurrPos, nPixelPos ); | ||||||||||||
2307 | else | ||||||||||||
2308 | rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); | ||||||||||||
2309 | return; | ||||||||||||
2310 | } | ||||||||||||
2311 | nCurrPos = rRect.X + rRect.Width; | ||||||||||||
2312 | } | ||||||||||||
2313 | else | ||||||||||||
2314 | { | ||||||||||||
2315 | if ( rSpace >= nNeededSpace ) | ||||||||||||
2316 | { | ||||||||||||
2317 | rVirtualPos = awt::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); | ||||||||||||
2318 | if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
2319 | rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); | ||||||||||||
2320 | else | ||||||||||||
2321 | rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); | ||||||||||||
2322 | return; | ||||||||||||
2323 | } | ||||||||||||
2324 | nCurrPos = rRect.Y + rRect.Height; | ||||||||||||
2325 | } | ||||||||||||
2326 | } | ||||||||||||
2327 | |||||||||||||
2328 | if (( nCurrPos + nNeededSpace ) <= nMaxSpace ) | ||||||||||||
2329 | { | ||||||||||||
2330 | if ( isHorizontalDockingArea( DockingArea )) | ||||||||||||
2331 | { | ||||||||||||
2332 | rVirtualPos = awt::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); | ||||||||||||
2333 | if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
2334 | rPixelPos = ::Point( nCurrPos, nPixelPos ); | ||||||||||||
2335 | else | ||||||||||||
2336 | rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); | ||||||||||||
2337 | return; | ||||||||||||
2338 | } | ||||||||||||
2339 | else | ||||||||||||
2340 | { | ||||||||||||
2341 | rVirtualPos = awt::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); | ||||||||||||
2342 | if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
2343 | rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); | ||||||||||||
2344 | else | ||||||||||||
2345 | rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); | ||||||||||||
2346 | return; | ||||||||||||
2347 | } | ||||||||||||
2348 | } | ||||||||||||
2349 | } | ||||||||||||
2350 | |||||||||||||
2351 | if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )) | ||||||||||||
2352 | nPixelPos += rRowColumnWindowData.nStaticSize; | ||||||||||||
2353 | } | ||||||||||||
2354 | |||||||||||||
2355 | sal_Int32 nNextFreeRowCol( 0 ); | ||||||||||||
2356 | sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size(); | ||||||||||||
2357 | if ( nRowColumnsCount > 0 ) | ||||||||||||
2358 | nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1; | ||||||||||||
2359 | else | ||||||||||||
2360 | nNextFreeRowCol = 0; | ||||||||||||
2361 | |||||||||||||
2362 | if ( nNextFreeRowCol == 0 ) | ||||||||||||
2363 | { | ||||||||||||
2364 | if ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) | ||||||||||||
2365 | nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height(); | ||||||||||||
2366 | else if ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ) | ||||||||||||
2367 | nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width(); | ||||||||||||
2368 | } | ||||||||||||
2369 | |||||||||||||
2370 | if ( isHorizontalDockingArea( DockingArea )) | ||||||||||||
2371 | { | ||||||||||||
2372 | rVirtualPos = awt::Point( 0, nNextFreeRowCol ); | ||||||||||||
2373 | if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
2374 | rPixelPos = ::Point( 0, nFreeRowColPixelPos ); | ||||||||||||
2375 | else | ||||||||||||
2376 | rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos ); | ||||||||||||
2377 | } | ||||||||||||
2378 | else | ||||||||||||
2379 | { | ||||||||||||
2380 | rVirtualPos = awt::Point( nNextFreeRowCol, 0 ); | ||||||||||||
2381 | rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 ); | ||||||||||||
2382 | } | ||||||||||||
2383 | } | ||||||||||||
2384 | |||||||||||||
2385 | void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn( | ||||||||||||
2386 | sal_Int32 nDockingArea, | ||||||||||||
2387 | sal_Int32 nOffset, | ||||||||||||
2388 | SingleRowColumnWindowData& rRowColumnWindowData, | ||||||||||||
2389 | const ::Size& rContainerSize ) | ||||||||||||
2390 | { | ||||||||||||
2391 | sal_Int32 nDiff(0); | ||||||||||||
2392 | sal_Int32 nRCSpace( rRowColumnWindowData.nSpace ); | ||||||||||||
2393 | sal_Int32 nContainerClientSize(0); | ||||||||||||
2394 | |||||||||||||
2395 | if ( rRowColumnWindowData.aRowColumnWindows.empty() ) | ||||||||||||
2396 | return; | ||||||||||||
2397 | |||||||||||||
2398 | if ( isHorizontalDockingArea( nDockingArea )) | ||||||||||||
2399 | { | ||||||||||||
2400 | nContainerClientSize = rContainerSize.Width(); | ||||||||||||
2401 | nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; | ||||||||||||
2402 | } | ||||||||||||
2403 | else | ||||||||||||
2404 | { | ||||||||||||
2405 | sal_Int32 nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); | ||||||||||||
2406 | sal_Int32 nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height(); | ||||||||||||
2407 | nContainerClientSize = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize ); | ||||||||||||
2408 | nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; | ||||||||||||
2409 | } | ||||||||||||
2410 | |||||||||||||
2411 | const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); | ||||||||||||
2412 | if (( nDiff < 0 ) && ( nRCSpace > 0 )) | ||||||||||||
2413 | { | ||||||||||||
2414 | // First we try to reduce the size of blank space before/behind docked windows | ||||||||||||
2415 | sal_Int32 i = nCount - 1; | ||||||||||||
2416 | while ( i >= 0 ) | ||||||||||||
2417 | { | ||||||||||||
2418 | sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i]; | ||||||||||||
2419 | if ( nSpace >= -nDiff ) | ||||||||||||
2420 | { | ||||||||||||
2421 | if ( isHorizontalDockingArea( nDockingArea )) | ||||||||||||
2422 | { | ||||||||||||
2423 | // Try to move this and all user elements behind with the calculated difference | ||||||||||||
2424 | for ( sal_uInt32 j = i; j < nCount; j++ ) | ||||||||||||
2425 | rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; | ||||||||||||
2426 | } | ||||||||||||
2427 | else | ||||||||||||
2428 | { | ||||||||||||
2429 | // Try to move this and all user elements behind with the calculated difference | ||||||||||||
2430 | for ( sal_uInt32 j = i; j < nCount; j++ ) | ||||||||||||
2431 | rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; | ||||||||||||
2432 | } | ||||||||||||
2433 | nDiff = 0; | ||||||||||||
2434 | |||||||||||||
2435 | break; | ||||||||||||
2436 | } | ||||||||||||
2437 | else if ( nSpace > 0 ) | ||||||||||||
2438 | { | ||||||||||||
2439 | if ( isHorizontalDockingArea( nDockingArea )) | ||||||||||||
2440 | { | ||||||||||||
2441 | // Try to move this and all user elements behind with the calculated difference | ||||||||||||
2442 | for ( sal_uInt32 j = i; j < nCount; j++ ) | ||||||||||||
2443 | rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace; | ||||||||||||
2444 | } | ||||||||||||
2445 | else | ||||||||||||
2446 | { | ||||||||||||
2447 | // Try to move this and all user elements behind with the calculated difference | ||||||||||||
2448 | for ( sal_uInt32 j = i; j < nCount; j++ ) | ||||||||||||
2449 | rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace; | ||||||||||||
2450 | } | ||||||||||||
2451 | nDiff += nSpace; | ||||||||||||
2452 | } | ||||||||||||
2453 | --i; | ||||||||||||
2454 | } | ||||||||||||
2455 | } | ||||||||||||
2456 | |||||||||||||
2457 | // Check if we have to reduce further | ||||||||||||
2458 | if ( nDiff < 0 ) | ||||||||||||
2459 | { | ||||||||||||
2460 | // Now we have to reduce the size of certain docked windows | ||||||||||||
2461 | sal_Int32 i = sal_Int32( nCount - 1 ); | ||||||||||||
2462 | while ( i >= 0 ) | ||||||||||||
2463 | { | ||||||||||||
2464 | awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; | ||||||||||||
2465 | ::Size aMinSize; | ||||||||||||
2466 | |||||||||||||
2467 | SolarMutexGuard aGuard; | ||||||||||||
2468 | { | ||||||||||||
2469 | uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; | ||||||||||||
2470 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
2471 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
2472 | aMinSize = static_cast<ToolBox *>(pWindow.get())->CalcMinimumWindowSizePixel(); | ||||||||||||
2473 | } | ||||||||||||
2474 | |||||||||||||
2475 | if ( !aMinSize.IsEmpty() ) | ||||||||||||
2476 | { | ||||||||||||
2477 | if ( isHorizontalDockingArea( nDockingArea )) | ||||||||||||
2478 | { | ||||||||||||
2479 | sal_Int32 nMaxReducation = rWinRect.Width - aMinSize.Width(); | ||||||||||||
2480 | if ( nMaxReducation >= -nDiff ) | ||||||||||||
2481 | { | ||||||||||||
2482 | rWinRect.Width = rWinRect.Width + nDiff; | ||||||||||||
2483 | nDiff = 0; | ||||||||||||
2484 | } | ||||||||||||
2485 | else | ||||||||||||
2486 | { | ||||||||||||
2487 | rWinRect.Width = aMinSize.Width(); | ||||||||||||
2488 | nDiff += nMaxReducation; | ||||||||||||
2489 | } | ||||||||||||
2490 | |||||||||||||
2491 | // Try to move this and all user elements behind with the calculated difference | ||||||||||||
2492 | for ( sal_uInt32 j = i; j < nCount; j++ ) | ||||||||||||
2493 | rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; | ||||||||||||
2494 | } | ||||||||||||
2495 | else | ||||||||||||
2496 | { | ||||||||||||
2497 | sal_Int32 nMaxReducation = rWinRect.Height - aMinSize.Height(); | ||||||||||||
2498 | if ( nMaxReducation >= -nDiff ) | ||||||||||||
2499 | { | ||||||||||||
2500 | rWinRect.Height = rWinRect.Height + nDiff; | ||||||||||||
2501 | nDiff = 0; | ||||||||||||
2502 | } | ||||||||||||
2503 | else | ||||||||||||
2504 | { | ||||||||||||
2505 | rWinRect.Height = aMinSize.Height(); | ||||||||||||
2506 | nDiff += nMaxReducation; | ||||||||||||
2507 | } | ||||||||||||
2508 | |||||||||||||
2509 | // Try to move this and all user elements behind with the calculated difference | ||||||||||||
2510 | for ( sal_uInt32 j = i; j < nCount; j++ ) | ||||||||||||
2511 | rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; | ||||||||||||
2512 | } | ||||||||||||
2513 | } | ||||||||||||
2514 | |||||||||||||
2515 | if ( nDiff >= 0 ) | ||||||||||||
2516 | break; | ||||||||||||
2517 | |||||||||||||
2518 | --i; | ||||||||||||
2519 | } | ||||||||||||
2520 | } | ||||||||||||
2521 | |||||||||||||
2522 | SolarMutexClearableGuard aReadLock; | ||||||||||||
2523 | VclPtr<vcl::Window> pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] ); | ||||||||||||
2524 | aReadLock.clear(); | ||||||||||||
2525 | |||||||||||||
2526 | sal_Int32 nCurrPos( 0 ); | ||||||||||||
2527 | |||||||||||||
2528 | SolarMutexGuard aGuard; | ||||||||||||
2529 | for ( sal_uInt32 i = 0; i < nCount; i++ ) | ||||||||||||
2530 | { | ||||||||||||
2531 | uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; | ||||||||||||
2532 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
2533 | vcl::Window* pOldParentWindow = pWindow->GetParent(); | ||||||||||||
2534 | |||||||||||||
2535 | if ( pDockAreaWindow != pOldParentWindow ) | ||||||||||||
2536 | pWindow->SetParent( pDockAreaWindow ); | ||||||||||||
2537 | |||||||||||||
2538 | awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; | ||||||||||||
2539 | if ( isHorizontalDockingArea( nDockingArea )) | ||||||||||||
2540 | { | ||||||||||||
2541 | if ( aWinRect.X < nCurrPos ) | ||||||||||||
2542 | aWinRect.X = nCurrPos; | ||||||||||||
2543 | pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); | ||||||||||||
2544 | pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate ); | ||||||||||||
2545 | nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; | ||||||||||||
2546 | } | ||||||||||||
2547 | else | ||||||||||||
2548 | { | ||||||||||||
2549 | if ( aWinRect.Y < nCurrPos ) | ||||||||||||
2550 | aWinRect.Y = nCurrPos; | ||||||||||||
2551 | pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); | ||||||||||||
2552 | pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate ); | ||||||||||||
2553 | nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; | ||||||||||||
2554 | } | ||||||||||||
2555 | } | ||||||||||||
2556 | } | ||||||||||||
2557 | |||||||||||||
2558 | void ToolbarLayoutManager::implts_setLayoutDirty() | ||||||||||||
2559 | { | ||||||||||||
2560 | SolarMutexGuard g; | ||||||||||||
2561 | m_bLayoutDirty = true; | ||||||||||||
2562 | } | ||||||||||||
2563 | |||||||||||||
2564 | void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress ) | ||||||||||||
2565 | { | ||||||||||||
2566 | SolarMutexGuard g; | ||||||||||||
2567 | m_bLayoutInProgress = bInProgress; | ||||||||||||
2568 | } | ||||||||||||
2569 | |||||||||||||
2570 | ::tools::Rectangle ToolbarLayoutManager::implts_calcHotZoneRect( const ::tools::Rectangle& rRect, sal_Int32 nHotZoneOffset ) | ||||||||||||
2571 | { | ||||||||||||
2572 | ::tools::Rectangle aRect( rRect ); | ||||||||||||
2573 | |||||||||||||
2574 | aRect.AdjustLeft( -nHotZoneOffset ); | ||||||||||||
2575 | aRect.AdjustTop( -nHotZoneOffset ); | ||||||||||||
2576 | aRect.AdjustRight(nHotZoneOffset ); | ||||||||||||
2577 | aRect.AdjustBottom(nHotZoneOffset ); | ||||||||||||
2578 | |||||||||||||
2579 | return aRect; | ||||||||||||
2580 | } | ||||||||||||
2581 | |||||||||||||
2582 | void ToolbarLayoutManager::implts_calcDockingPosSize( | ||||||||||||
2583 | UIElement& rUIElement, | ||||||||||||
2584 | DockingOperation& rDockingOperation, | ||||||||||||
2585 | ::tools::Rectangle& rTrackingRect, | ||||||||||||
2586 | const Point& rMousePos ) | ||||||||||||
2587 | { | ||||||||||||
2588 | SolarMutexResettableGuard aReadLock; | ||||||||||||
2589 | uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); | ||||||||||||
2590 | ::Size aContainerWinSize; | ||||||||||||
2591 | vcl::Window* pContainerWindow( nullptr ); | ||||||||||||
2592 | ::tools::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets ); | ||||||||||||
2593 | aReadLock.clear(); | ||||||||||||
2594 | |||||||||||||
2595 | if ( !rUIElement.m_xUIElement.is() ) | ||||||||||||
| |||||||||||||
2596 | { | ||||||||||||
2597 | rTrackingRect = ::tools::Rectangle(); | ||||||||||||
2598 | return; | ||||||||||||
2599 | } | ||||||||||||
2600 | |||||||||||||
2601 | { | ||||||||||||
2602 | // Retrieve output size from container Window | ||||||||||||
2603 | SolarMutexGuard aGuard; | ||||||||||||
2604 | pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ).get(); | ||||||||||||
2605 | aContainerWinSize = pContainerWindow->GetOutputSizePixel(); | ||||||||||||
2606 | } | ||||||||||||
2607 | |||||||||||||
2608 | vcl::Window* pDockingAreaWindow( nullptr ); | ||||||||||||
2609 | uno::Reference< awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
2610 | uno::Reference< awt::XWindow > xDockingAreaWindow; | ||||||||||||
2611 | ::tools::Rectangle aTrackingRect( rTrackingRect ); | ||||||||||||
2612 | ui::DockingArea eDockedArea( rUIElement.m_aDockedData.m_nDockedArea ); | ||||||||||||
2613 | sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); | ||||||||||||
2614 | sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); | ||||||||||||
2615 | bool bHorizontalDockArea(( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || | ||||||||||||
2616 | ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); | ||||||||||||
2617 | sal_Int32 nMaxLeftRightDockAreaSize = aContainerWinSize.Height() - | ||||||||||||
2618 | nTopDockingAreaSize - | ||||||||||||
2619 | nBottomDockingAreaSize - | ||||||||||||
2620 | aDockingAreaOffsets.Top() - | ||||||||||||
2621 | aDockingAreaOffsets.Bottom(); | ||||||||||||
2622 | ::tools::Rectangle aDockingAreaRect; | ||||||||||||
2623 | |||||||||||||
2624 | aReadLock.reset(); | ||||||||||||
2625 | xDockingAreaWindow = m_xDockAreaWindows[static_cast<int>(eDockedArea)]; | ||||||||||||
2626 | aReadLock.clear(); | ||||||||||||
2627 | |||||||||||||
2628 | { | ||||||||||||
2629 | SolarMutexGuard aGuard; | ||||||||||||
2630 | pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ).get(); | ||||||||||||
2631 | VclPtr<vcl::Window> pDockWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
2632 | ToolBox* pToolBox( nullptr ); | ||||||||||||
2633 | if ( pDockWindow && pDockWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
2634 | pToolBox = static_cast<ToolBox *>(pDockWindow.get()); | ||||||||||||
2635 | |||||||||||||
2636 | aDockingAreaRect = ::tools::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() ); | ||||||||||||
2637 | if ( pToolBox
| ||||||||||||
2638 | { | ||||||||||||
2639 | // docked toolbars always have one line | ||||||||||||
2640 | ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( eDockedArea ) ); | ||||||||||||
2641 | aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() )); | ||||||||||||
2642 | } | ||||||||||||
2643 | } | ||||||||||||
2644 | |||||||||||||
2645 | // default docking operation, dock on the given row/column | ||||||||||||
2646 | bool bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos )); | ||||||||||||
2647 | |||||||||||||
2648 | std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; | ||||||||||||
2649 | |||||||||||||
2650 | rDockingOperation = DOCKOP_ON_COLROW; | ||||||||||||
2651 | implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData ); | ||||||||||||
2652 | |||||||||||||
2653 | // determine current first row/column and last row/column | ||||||||||||
2654 | sal_Int32 nMaxRowCol( -1 ); | ||||||||||||
2655 | sal_Int32 nMinRowCol( SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF) ); | ||||||||||||
2656 | const sal_uInt32 nCount = aRowColumnsWindowData.size(); | ||||||||||||
2657 | for ( sal_uInt32 i = 0; i < nCount; i++ ) | ||||||||||||
2658 | { | ||||||||||||
2659 | if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol ) | ||||||||||||
2660 | nMaxRowCol = aRowColumnsWindowData[i].nRowColumn; | ||||||||||||
2661 | if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol ) | ||||||||||||
2662 | nMinRowCol = aRowColumnsWindowData[i].nRowColumn; | ||||||||||||
2663 | } | ||||||||||||
2664 | |||||||||||||
2665 | if ( !bOpOutsideOfDockingArea
| ||||||||||||
2666 | { | ||||||||||||
2667 | // docking inside our docking area | ||||||||||||
2668 | sal_Int32 nIndex( -1 ); | ||||||||||||
2669 | sal_Int32 nRowCol( -1 ); | ||||||||||||
2670 | ::tools::Rectangle aWindowRect; | ||||||||||||
2671 | ::tools::Rectangle aRowColumnRect; | ||||||||||||
2672 | |||||||||||||
2673 | const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size(); | ||||||||||||
2674 | for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ ) | ||||||||||||
2675 | { | ||||||||||||
2676 | ::tools::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X, | ||||||||||||
2677 | aRowColumnsWindowData[i].aRowColumnRect.Y, | ||||||||||||
2678 | aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width, | ||||||||||||
2679 | aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height ); | ||||||||||||
2680 | |||||||||||||
2681 | { | ||||||||||||
2682 | // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect | ||||||||||||
2683 | SolarMutexGuard aGuard; | ||||||||||||
2684 | aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); | ||||||||||||
2685 | } | ||||||||||||
2686 | |||||||||||||
2687 | bool bIsInsideRowCol( aRect.IsInside( rMousePos ) ); | ||||||||||||
2688 | if ( bIsInsideRowCol ) | ||||||||||||
2689 | { | ||||||||||||
2690 | nIndex = i; | ||||||||||||
2691 | nRowCol = aRowColumnsWindowData[i].nRowColumn; | ||||||||||||
2692 | rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos ); | ||||||||||||
2693 | aWindowRect = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName ); | ||||||||||||
2694 | aRowColumnRect = aRect; | ||||||||||||
2695 | break; | ||||||||||||
2696 | } | ||||||||||||
2697 | } | ||||||||||||
2698 | |||||||||||||
2699 | OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" )do { if (true && (!(( nIndex >= 0 ) && ( nRowCol >= 0 )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/framework/source/layoutmanager/toolbarlayoutmanager.cxx" ":" "2699" ": "), "%s", "Impossible case - no row/column found but mouse pointer is inside our docking area" ); } } while (false); | ||||||||||||
2700 | if (( nIndex
| ||||||||||||
2701 | { | ||||||||||||
2702 | if ( rDockingOperation
| ||||||||||||
2703 | { | ||||||||||||
2704 | if ( !aWindowRect.IsEmpty()) | ||||||||||||
2705 | { | ||||||||||||
2706 | // Tracking rect is on a row/column and mouse is over a docked toolbar. | ||||||||||||
2707 | // Determine if the tracking rect must be located before/after the docked toolbar. | ||||||||||||
2708 | |||||||||||||
2709 | ::tools::Rectangle aUIElementRect( aWindowRect ); | ||||||||||||
2710 | sal_Int32 nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) : | ||||||||||||
2711 | ( aWindowRect.Top() + aWindowRect.getHeight() / 2 )); | ||||||||||||
2712 | bool bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle )); | ||||||||||||
2713 | if ( bInsertBefore ) | ||||||||||||
2714 | { | ||||||||||||
2715 | if ( bHorizontalDockArea ) | ||||||||||||
2716 | { | ||||||||||||
2717 | sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() - aWindowRect.Left() ), | ||||||||||||
2718 | sal_Int32( aTrackingRect.getWidth() ))); | ||||||||||||
2719 | if ( nSize == 0 ) | ||||||||||||
2720 | nSize = aWindowRect.getWidth(); | ||||||||||||
2721 | |||||||||||||
2722 | aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); | ||||||||||||
2723 | aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect ); | ||||||||||||
2724 | |||||||||||||
2725 | // Set virtual position | ||||||||||||
2726 | rUIElement.m_aDockedData.m_aPos.X = aWindowRect.Left(); | ||||||||||||
2727 | rUIElement.m_aDockedData.m_aPos.Y = nRowCol; | ||||||||||||
2728 | } | ||||||||||||
2729 | else | ||||||||||||
2730 | { | ||||||||||||
2731 | sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( | ||||||||||||
2732 | nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ), | ||||||||||||
2733 | sal_Int32( aTrackingRect.getHeight() ))); | ||||||||||||
2734 | if ( nSize == 0 ) | ||||||||||||
2735 | nSize = aWindowRect.getHeight(); | ||||||||||||
2736 | |||||||||||||
2737 | aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); | ||||||||||||
2738 | aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect ); | ||||||||||||
2739 | |||||||||||||
2740 | // Set virtual position | ||||||||||||
2741 | sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel( | ||||||||||||
2742 | pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y(); | ||||||||||||
2743 | rUIElement.m_aDockedData.m_aPos.X = nRowCol; | ||||||||||||
2744 | rUIElement.m_aDockedData.m_aPos.Y = nPosY; | ||||||||||||
2745 | } | ||||||||||||
2746 | |||||||||||||
2747 | rTrackingRect = aWindowRect; | ||||||||||||
2748 | return; | ||||||||||||
2749 | } | ||||||||||||
2750 | else | ||||||||||||
2751 | { | ||||||||||||
2752 | if ( bHorizontalDockArea ) | ||||||||||||
2753 | { | ||||||||||||
2754 | sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ), | ||||||||||||
2755 | sal_Int32( aTrackingRect.getWidth() ))); | ||||||||||||
2756 | if ( nSize == 0 ) | ||||||||||||
2757 | { | ||||||||||||
2758 | aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() )); | ||||||||||||
2759 | aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() )); | ||||||||||||
2760 | rUIElement.m_aDockedData.m_aPos.X = aUIElementRect.Left(); | ||||||||||||
2761 | |||||||||||||
2762 | } | ||||||||||||
2763 | else | ||||||||||||
2764 | { | ||||||||||||
2765 | aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() )); | ||||||||||||
2766 | aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); | ||||||||||||
2767 | rUIElement.m_aDockedData.m_aPos.X = aWindowRect.Right(); | ||||||||||||
2768 | } | ||||||||||||
2769 | |||||||||||||
2770 | // Set virtual position | ||||||||||||
2771 | rUIElement.m_aDockedData.m_aPos.Y = nRowCol; | ||||||||||||
2772 | } | ||||||||||||
2773 | else | ||||||||||||
2774 | { | ||||||||||||
2775 | sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ), | ||||||||||||
2776 | sal_Int32( aTrackingRect.getHeight() ))); | ||||||||||||
2777 | aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() )); | ||||||||||||
2778 | aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); | ||||||||||||
2779 | |||||||||||||
2780 | // Set virtual position | ||||||||||||
2781 | sal_Int32 nPosY( 0 ); | ||||||||||||
2782 | { | ||||||||||||
2783 | SolarMutexGuard aGuard; | ||||||||||||
2784 | nPosY = pDockingAreaWindow->ScreenToOutputPixel( | ||||||||||||
2785 | pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y(); | ||||||||||||
2786 | } | ||||||||||||
2787 | rUIElement.m_aDockedData.m_aPos.X = nRowCol; | ||||||||||||
2788 | rUIElement.m_aDockedData.m_aPos.Y = nPosY; | ||||||||||||
2789 | } | ||||||||||||
2790 | |||||||||||||
2791 | rTrackingRect = aUIElementRect; | ||||||||||||
2792 | return; | ||||||||||||
2793 | } | ||||||||||||
2794 | } | ||||||||||||
2795 | else | ||||||||||||
2796 | { | ||||||||||||
2797 | implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); | ||||||||||||
2798 | rTrackingRect = implts_calcTrackingAndElementRect( | ||||||||||||
2799 | eDockedArea, nRowCol, rUIElement, | ||||||||||||
2800 | aTrackingRect, aRowColumnRect, aContainerWinSize ); | ||||||||||||
2801 | return; | ||||||||||||
2802 | } | ||||||||||||
2803 | } | ||||||||||||
2804 | else | ||||||||||||
2805 | { | ||||||||||||
2806 | if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) || | ||||||||||||
2807 | (( nRowCol
| ||||||||||||
2808 | bOpOutsideOfDockingArea = true; | ||||||||||||
2809 | else | ||||||||||||
2810 | { | ||||||||||||
2811 | // handle docking before/after a row | ||||||||||||
2812 | implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); | ||||||||||||
2813 | rTrackingRect = implts_calcTrackingAndElementRect( | ||||||||||||
2814 | eDockedArea, nRowCol, rUIElement, | ||||||||||||
2815 | aTrackingRect, aRowColumnRect, aContainerWinSize ); | ||||||||||||
2816 | |||||||||||||
2817 | sal_Int32 nOffsetX( 0 ); | ||||||||||||
2818 | sal_Int32 nOffsetY( 0 ); | ||||||||||||
2819 | if ( bHorizontalDockArea ) | ||||||||||||
2820 | nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2.0 + 0.5 )); | ||||||||||||
2821 | else | ||||||||||||
2822 | nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2.0 + 0.5 )); | ||||||||||||
2823 | |||||||||||||
2824 | if ( rDockingOperation == DOCKOP_BEFORE_COLROW ) | ||||||||||||
2825 | { | ||||||||||||
2826 | if (( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )) | ||||||||||||
2827 | { | ||||||||||||
2828 | // Docking before/after means move track rectangle half column/row. | ||||||||||||
2829 | // As left and top are ordered 0...n instead of right and bottom | ||||||||||||
2830 | // which uses n...0, we have to use negative values for top/left. | ||||||||||||
2831 | nOffsetX *= -1; | ||||||||||||
2832 | nOffsetY *= -1; | ||||||||||||
2833 | } | ||||||||||||
2834 | } | ||||||||||||
2835 | else | ||||||||||||
2836 | { | ||||||||||||
2837 | if (( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT )) | ||||||||||||
2838 | { | ||||||||||||
2839 | // Docking before/after means move track rectangle half column/row. | ||||||||||||
2840 | // As left and top are ordered 0...n instead of right and bottom | ||||||||||||
2841 | // which uses n...0, we have to use negative values for top/left. | ||||||||||||
2842 | nOffsetX *= -1; | ||||||||||||
2843 | nOffsetY *= -1; | ||||||||||||
2844 | } | ||||||||||||
2845 | nRowCol++; | ||||||||||||
2846 | } | ||||||||||||
2847 | |||||||||||||
2848 | if ( bHorizontalDockArea ) | ||||||||||||
2849 | rUIElement.m_aDockedData.m_aPos.Y = nRowCol; | ||||||||||||
2850 | else | ||||||||||||
2851 | rUIElement.m_aDockedData.m_aPos.X = nRowCol; | ||||||||||||
2852 | |||||||||||||
2853 | rTrackingRect.Move( nOffsetX, nOffsetY ); | ||||||||||||
2854 | rTrackingRect.SetSize( aTrackingRect.GetSize() ); | ||||||||||||
2855 | } | ||||||||||||
2856 | } | ||||||||||||
2857 | } | ||||||||||||
2858 | } | ||||||||||||
2859 | |||||||||||||
2860 | // Docking outside of our docking window area => | ||||||||||||
2861 | // Users want to dock before/after first/last docked element or to an empty docking area | ||||||||||||
2862 | if ( !bOpOutsideOfDockingArea ) | ||||||||||||
2863 | return; | ||||||||||||
2864 | |||||||||||||
2865 | // set correct size for docking | ||||||||||||
2866 | implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); | ||||||||||||
2867 | rTrackingRect = aTrackingRect; | ||||||||||||
2868 | |||||||||||||
2869 | if ( bHorizontalDockArea ) | ||||||||||||
2870 | { | ||||||||||||
2871 | sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); | ||||||||||||
2872 | if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() ) | ||||||||||||
2873 | nPosX = std::min( nPosX, | ||||||||||||
2874 | std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ), | ||||||||||||
2875 | sal_Int32( 0 ))); | ||||||||||||
2876 | |||||||||||||
2877 | sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() ); | ||||||||||||
2878 | sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 )); | ||||||||||||
2879 | if ( nDockHeight == 0 ) | ||||||||||||
2880 | { | ||||||||||||
2881 | sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() )); | ||||||||||||
2882 | if ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) | ||||||||||||
2883 | nPosY -= rTrackingRect.getHeight(); | ||||||||||||
2884 | rTrackingRect.SetPos( Point( nPosX, nPosY )); | ||||||||||||
2885 | rUIElement.m_aDockedData.m_aPos.Y = 0; | ||||||||||||
2886 | } | ||||||||||||
2887 | else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 ))) | ||||||||||||
2888 | { | ||||||||||||
2889 | rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() )); | ||||||||||||
2890 | if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
2891 | rUIElement.m_aDockedData.m_aPos.Y = 0; | ||||||||||||
2892 | else | ||||||||||||
2893 | rUIElement.m_aDockedData.m_aPos.Y = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; | ||||||||||||
2894 | rDockingOperation = DOCKOP_BEFORE_COLROW; | ||||||||||||
2895 | } | ||||||||||||
2896 | else | ||||||||||||
2897 | { | ||||||||||||
2898 | rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() )); | ||||||||||||
2899 | if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
2900 | rUIElement.m_aDockedData.m_aPos.Y = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; | ||||||||||||
2901 | else | ||||||||||||
2902 | rUIElement.m_aDockedData.m_aPos.Y = 0; | ||||||||||||
2903 | rDockingOperation = DOCKOP_AFTER_COLROW; | ||||||||||||
2904 | } | ||||||||||||
2905 | rTrackingRect.setWidth( nSize ); | ||||||||||||
2906 | |||||||||||||
2907 | { | ||||||||||||
2908 | SolarMutexGuard aGuard; | ||||||||||||
2909 | nPosX = pDockingAreaWindow->ScreenToOutputPixel( | ||||||||||||
2910 | pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X(); | ||||||||||||
2911 | } | ||||||||||||
2912 | rUIElement.m_aDockedData.m_aPos.X = nPosX; | ||||||||||||
2913 | } | ||||||||||||
2914 | else | ||||||||||||
2915 | { | ||||||||||||
2916 | sal_Int32 nMaxDockingAreaHeight = std::max<sal_Int32>( 0, nMaxLeftRightDockAreaSize ); | ||||||||||||
2917 | sal_Int32 nPosY( std::max<sal_Int32>( aTrackingRect.Top(), nTopDockingAreaSize )); | ||||||||||||
2918 | if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) | ||||||||||||
2919 | nPosY = std::min( nPosY, | ||||||||||||
2920 | std::max<sal_Int32>( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() ), | ||||||||||||
2921 | nTopDockingAreaSize )); | ||||||||||||
2922 | |||||||||||||
2923 | sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); | ||||||||||||
2924 | sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 )); | ||||||||||||
2925 | if ( nDockWidth == 0 ) | ||||||||||||
2926 | { | ||||||||||||
2927 | sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() )); | ||||||||||||
2928 | if ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT ) | ||||||||||||
2929 | nPosX -= rTrackingRect.getWidth(); | ||||||||||||
2930 | rTrackingRect.SetPos( Point( nPosX, nPosY )); | ||||||||||||
2931 | rUIElement.m_aDockedData.m_aPos.X = 0; | ||||||||||||
2932 | } | ||||||||||||
2933 | else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 ))) | ||||||||||||
2934 | { | ||||||||||||
2935 | rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY )); | ||||||||||||
2936 | if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
2937 | rUIElement.m_aDockedData.m_aPos.X = 0; | ||||||||||||
2938 | else | ||||||||||||
2939 | rUIElement.m_aDockedData.m_aPos.X = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; | ||||||||||||
2940 | rDockingOperation = DOCKOP_BEFORE_COLROW; | ||||||||||||
2941 | } | ||||||||||||
2942 | else | ||||||||||||
2943 | { | ||||||||||||
2944 | rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY )); | ||||||||||||
2945 | if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
2946 | rUIElement.m_aDockedData.m_aPos.X = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; | ||||||||||||
2947 | else | ||||||||||||
2948 | rUIElement.m_aDockedData.m_aPos.X = 0; | ||||||||||||
2949 | rDockingOperation = DOCKOP_AFTER_COLROW; | ||||||||||||
2950 | } | ||||||||||||
2951 | rTrackingRect.setHeight( nSize ); | ||||||||||||
2952 | |||||||||||||
2953 | { | ||||||||||||
2954 | SolarMutexGuard aGuard; | ||||||||||||
2955 | nPosY = pDockingAreaWindow->ScreenToOutputPixel( | ||||||||||||
2956 | pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y(); | ||||||||||||
2957 | } | ||||||||||||
2958 | rUIElement.m_aDockedData.m_aPos.Y = nPosY; | ||||||||||||
2959 | } | ||||||||||||
2960 | } | ||||||||||||
2961 | |||||||||||||
2962 | framework::ToolbarLayoutManager::DockingOperation ToolbarLayoutManager::implts_determineDockingOperation( | ||||||||||||
2963 | ui::DockingArea DockingArea, | ||||||||||||
2964 | const ::tools::Rectangle& rRowColRect, | ||||||||||||
2965 | const Point& rMousePos ) | ||||||||||||
2966 | { | ||||||||||||
2967 | constexpr sal_Int32 nHorzVerticalRegionSize = 6; | ||||||||||||
2968 | constexpr sal_Int32 nHorzVerticalMoveRegion = 4; | ||||||||||||
2969 | |||||||||||||
2970 | if ( rRowColRect.IsInside( rMousePos )) | ||||||||||||
2971 | { | ||||||||||||
2972 | if ( isHorizontalDockingArea( DockingArea )) | ||||||||||||
2973 | { | ||||||||||||
2974 | sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize; | ||||||||||||
2975 | sal_Int32 nPosY = rRowColRect.Top() + nRegion; | ||||||||||||
2976 | |||||||||||||
2977 | if ( rMousePos.Y() < nPosY ) | ||||||||||||
2978 | return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; | ||||||||||||
2979 | else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion )) | ||||||||||||
2980 | return DOCKOP_ON_COLROW; | ||||||||||||
2981 | else | ||||||||||||
2982 | return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; | ||||||||||||
2983 | } | ||||||||||||
2984 | else | ||||||||||||
2985 | { | ||||||||||||
2986 | sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize; | ||||||||||||
2987 | sal_Int32 nPosX = rRowColRect.Left() + nRegion; | ||||||||||||
2988 | |||||||||||||
2989 | if ( rMousePos.X() < nPosX ) | ||||||||||||
2990 | return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; | ||||||||||||
2991 | else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion )) | ||||||||||||
2992 | return DOCKOP_ON_COLROW; | ||||||||||||
2993 | else | ||||||||||||
2994 | return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; | ||||||||||||
2995 | } | ||||||||||||
2996 | } | ||||||||||||
2997 | else | ||||||||||||
2998 | return DOCKOP_ON_COLROW; | ||||||||||||
2999 | } | ||||||||||||
3000 | |||||||||||||
3001 | ::tools::Rectangle ToolbarLayoutManager::implts_calcTrackingAndElementRect( | ||||||||||||
3002 | ui::DockingArea eDockingArea, | ||||||||||||
3003 | sal_Int32 nRowCol, | ||||||||||||
3004 | UIElement& rUIElement, | ||||||||||||
3005 | const ::tools::Rectangle& rTrackingRect, | ||||||||||||
3006 | const ::tools::Rectangle& rRowColumnRect, | ||||||||||||
3007 | const ::Size& rContainerWinSize ) | ||||||||||||
3008 | { | ||||||||||||
3009 | SolarMutexResettableGuard aReadGuard; | ||||||||||||
3010 | ::tools::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets ); | ||||||||||||
3011 | aReadGuard.clear(); | ||||||||||||
3012 | |||||||||||||
3013 | bool bHorizontalDockArea( isHorizontalDockingArea( eDockingArea )); | ||||||||||||
3014 | |||||||||||||
3015 | sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); | ||||||||||||
3016 | sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); | ||||||||||||
3017 | |||||||||||||
3018 | sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() - | ||||||||||||
3019 | nTopDockingAreaSize - | ||||||||||||
3020 | nBottomDockingAreaSize - | ||||||||||||
3021 | aDockingAreaOffsets.Top() - | ||||||||||||
3022 | aDockingAreaOffsets.Bottom(); | ||||||||||||
3023 | |||||||||||||
3024 | ::tools::Rectangle aTrackingRect( rTrackingRect ); | ||||||||||||
3025 | if ( bHorizontalDockArea ) | ||||||||||||
3026 | { | ||||||||||||
3027 | sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); | ||||||||||||
3028 | if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() ) | ||||||||||||
3029 | nPosX = std::min( nPosX, | ||||||||||||
3030 | std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ), | ||||||||||||
3031 | sal_Int32( 0 ))); | ||||||||||||
3032 | |||||||||||||
3033 | sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() ); | ||||||||||||
3034 | |||||||||||||
3035 | aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() )); | ||||||||||||
3036 | aTrackingRect.setWidth( nSize ); | ||||||||||||
3037 | aTrackingRect.setHeight( rRowColumnRect.getHeight() ); | ||||||||||||
3038 | |||||||||||||
3039 | // Set virtual position | ||||||||||||
3040 | rUIElement.m_aDockedData.m_aPos.X = nPosX; | ||||||||||||
3041 | rUIElement.m_aDockedData.m_aPos.Y = nRowCol; | ||||||||||||
3042 | } | ||||||||||||
3043 | else | ||||||||||||
3044 | { | ||||||||||||
3045 | sal_Int32 nMaxDockingAreaHeight = std::max<sal_Int32>( 0, nMaxLeftRightDockAreaSize ); | ||||||||||||
3046 | |||||||||||||
3047 | sal_Int32 nPosY( std::max<sal_Int32>( aTrackingRect.Top(), nTopDockingAreaSize )); | ||||||||||||
3048 | if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) | ||||||||||||
3049 | nPosY = std::min( nPosY, | ||||||||||||
3050 | std::max<sal_Int32>( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() ), | ||||||||||||
3051 | nTopDockingAreaSize )); | ||||||||||||
3052 | |||||||||||||
3053 | sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); | ||||||||||||
3054 | |||||||||||||
3055 | aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY )); | ||||||||||||
3056 | aTrackingRect.setWidth( rRowColumnRect.getWidth() ); | ||||||||||||
3057 | aTrackingRect.setHeight( nSize ); | ||||||||||||
3058 | |||||||||||||
3059 | aReadGuard.reset(); | ||||||||||||
3060 | uno::Reference< awt::XWindow > xDockingAreaWindow( m_xDockAreaWindows[static_cast<int>(eDockingArea)] ); | ||||||||||||
3061 | uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); | ||||||||||||
3062 | aReadGuard.clear(); | ||||||||||||
3063 | |||||||||||||
3064 | sal_Int32 nDockPosY( 0 ); | ||||||||||||
3065 | { | ||||||||||||
3066 | SolarMutexGuard aGuard; | ||||||||||||
3067 | vcl::Window* pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ).get(); | ||||||||||||
3068 | VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); | ||||||||||||
3069 | nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y(); | ||||||||||||
| |||||||||||||
3070 | } | ||||||||||||
3071 | |||||||||||||
3072 | // Set virtual position | ||||||||||||
3073 | rUIElement.m_aDockedData.m_aPos.X = nRowCol; | ||||||||||||
3074 | rUIElement.m_aDockedData.m_aPos.Y = nDockPosY; | ||||||||||||
3075 | } | ||||||||||||
3076 | |||||||||||||
3077 | return aTrackingRect; | ||||||||||||
3078 | } | ||||||||||||
3079 | |||||||||||||
3080 | void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea, const ::Point& rMousePos, ::tools::Rectangle& rTrackingRect ) | ||||||||||||
3081 | { | ||||||||||||
3082 | ::Point aPoint( rTrackingRect.TopLeft()); | ||||||||||||
3083 | if ( isHorizontalDockingArea( eDockingArea )) | ||||||||||||
3084 | aPoint.setX( rMousePos.X() ); | ||||||||||||
3085 | else | ||||||||||||
3086 | aPoint.setY( rMousePos.Y() ); | ||||||||||||
3087 | rTrackingRect.SetPos( aPoint ); | ||||||||||||
3088 | } | ||||||||||||
3089 | |||||||||||||
3090 | void ToolbarLayoutManager::implts_renumberRowColumnData( | ||||||||||||
3091 | ui::DockingArea eDockingArea, | ||||||||||||
3092 | const UIElement& rUIElement ) | ||||||||||||
3093 | { | ||||||||||||
3094 | SolarMutexClearableGuard aReadLock; | ||||||||||||
3095 | uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); | ||||||||||||
3096 | aReadLock.clear(); | ||||||||||||
3097 | |||||||||||||
3098 | bool bHorzDockingArea( isHorizontalDockingArea( eDockingArea )); | ||||||||||||
3099 | sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y : rUIElement.m_aDockedData.m_aPos.X ); | ||||||||||||
3100 | |||||||||||||
3101 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
3102 | { | ||||||||||||
3103 | SolarMutexGuard aWriteLock; | ||||||||||||
3104 | for (auto& elem : m_aUIElements) | ||||||||||||
3105 | { | ||||||||||||
3106 | if ((elem.m_aDockedData.m_nDockedArea == eDockingArea) | ||||||||||||
3107 | && (elem.m_aName != rUIElement.m_aName)) | ||||||||||||
3108 | { | ||||||||||||
3109 | // Don't change toolbars without a valid docking position! | ||||||||||||
3110 | if (isDefaultPos(elem.m_aDockedData.m_aPos)) | ||||||||||||
3111 | continue; | ||||||||||||
3112 | |||||||||||||
3113 | sal_Int32 nWindowRowCol | ||||||||||||
3114 | = bHorzDockingArea ? elem.m_aDockedData.m_aPos.Y : elem.m_aDockedData.m_aPos.X; | ||||||||||||
3115 | if (nWindowRowCol >= nRowCol) | ||||||||||||
3116 | { | ||||||||||||
3117 | if (bHorzDockingArea) | ||||||||||||
3118 | elem.m_aDockedData.m_aPos.Y += 1; | ||||||||||||
3119 | else | ||||||||||||
3120 | elem.m_aDockedData.m_aPos.X += 1; | ||||||||||||
3121 | } | ||||||||||||
3122 | } | ||||||||||||
3123 | } | ||||||||||||
3124 | } | ||||||||||||
3125 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
3126 | |||||||||||||
3127 | // We have to change the persistent window state part | ||||||||||||
3128 | if ( !xPersistentWindowState.is() ) | ||||||||||||
3129 | return; | ||||||||||||
3130 | |||||||||||||
3131 | try | ||||||||||||
3132 | { | ||||||||||||
3133 | const uno::Sequence< OUString > aWindowElements = xPersistentWindowState->getElementNames(); | ||||||||||||
3134 | for ( OUString const & rWindowElementName : aWindowElements ) | ||||||||||||
3135 | { | ||||||||||||
3136 | if ( rUIElement.m_aName != rWindowElementName ) | ||||||||||||
3137 | { | ||||||||||||
3138 | try | ||||||||||||
3139 | { | ||||||||||||
3140 | uno::Sequence< beans::PropertyValue > aPropValueSeq; | ||||||||||||
3141 | awt::Point aDockedPos; | ||||||||||||
3142 | ui::DockingArea nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT ); | ||||||||||||
3143 | |||||||||||||
3144 | xPersistentWindowState->getByName( rWindowElementName ) >>= aPropValueSeq; | ||||||||||||
3145 | for ( beans::PropertyValue const & rProp : std::as_const(aPropValueSeq) ) | ||||||||||||
3146 | { | ||||||||||||
3147 | if ( rProp.Name == WINDOWSTATE_PROPERTY_DOCKINGAREA"DockingArea" ) | ||||||||||||
3148 | rProp.Value >>= nDockedArea; | ||||||||||||
3149 | else if ( rProp.Name == WINDOWSTATE_PROPERTY_DOCKPOS"DockPos" ) | ||||||||||||
3150 | rProp.Value >>= aDockedPos; | ||||||||||||
3151 | } | ||||||||||||
3152 | |||||||||||||
3153 | // Don't change toolbars without a valid docking position! | ||||||||||||
3154 | if ( isDefaultPos( aDockedPos )) | ||||||||||||
3155 | continue; | ||||||||||||
3156 | |||||||||||||
3157 | sal_Int32 nWindowRowCol = bHorzDockingArea ? aDockedPos.Y : aDockedPos.X; | ||||||||||||
3158 | if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol )) | ||||||||||||
3159 | { | ||||||||||||
3160 | if ( bHorzDockingArea ) | ||||||||||||
3161 | aDockedPos.Y += 1; | ||||||||||||
3162 | else | ||||||||||||
3163 | aDockedPos.X += 1; | ||||||||||||
3164 | |||||||||||||
3165 | uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY ); | ||||||||||||
3166 | xReplace->replaceByName( rWindowElementName, makeAny( aPropValueSeq )); | ||||||||||||
3167 | } | ||||||||||||
3168 | } | ||||||||||||
3169 | catch (const uno::Exception&) | ||||||||||||
3170 | { | ||||||||||||
3171 | } | ||||||||||||
3172 | } | ||||||||||||
3173 | } | ||||||||||||
3174 | } | ||||||||||||
3175 | catch (const uno::Exception&) | ||||||||||||
3176 | { | ||||||||||||
3177 | } | ||||||||||||
3178 | } | ||||||||||||
3179 | |||||||||||||
3180 | // XWindowListener | ||||||||||||
3181 | |||||||||||||
3182 | void SAL_CALL ToolbarLayoutManager::windowResized( const awt::WindowEvent& aEvent ) | ||||||||||||
3183 | { | ||||||||||||
3184 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
3185 | bool bLocked( m_bDockingInProgress ); | ||||||||||||
3186 | bool bLayoutInProgress( m_bLayoutInProgress ); | ||||||||||||
3187 | aWriteLock.clear(); | ||||||||||||
3188 | |||||||||||||
3189 | // Do not do anything if we are in the middle of a docking process. This would interfere all other | ||||||||||||
3190 | // operations. We will store the new position and size in the docking handlers. | ||||||||||||
3191 | // Do not do anything if we are in the middle of our layouting process. We will adapt the position | ||||||||||||
3192 | // and size of the user interface elements. | ||||||||||||
3193 | if ( bLocked || bLayoutInProgress ) | ||||||||||||
3194 | return; | ||||||||||||
3195 | |||||||||||||
3196 | bool bNotify( false ); | ||||||||||||
3197 | uno::Reference< awt::XWindow > xWindow( aEvent.Source, uno::UNO_QUERY ); | ||||||||||||
3198 | |||||||||||||
3199 | UIElement aUIElement = implts_findToolbar( aEvent.Source ); | ||||||||||||
3200 | if ( aUIElement.m_xUIElement.is() ) | ||||||||||||
3201 | { | ||||||||||||
3202 | if ( aUIElement.m_bFloating ) | ||||||||||||
3203 | { | ||||||||||||
3204 | uno::Reference< awt::XWindow2 > xWindow2( xWindow, uno::UNO_QUERY ); | ||||||||||||
3205 | |||||||||||||
3206 | if( xWindow2.is() ) | ||||||||||||
3207 | { | ||||||||||||
3208 | awt::Rectangle aPos = xWindow2->getPosSize(); | ||||||||||||
3209 | awt::Size aSize = xWindow2->getOutputSize(); // always use output size for consistency | ||||||||||||
3210 | bool bVisible = xWindow2->isVisible(); | ||||||||||||
3211 | |||||||||||||
3212 | // update element data | ||||||||||||
3213 | aUIElement.m_aFloatingData.m_aPos = awt::Point(aPos.X, aPos.Y); | ||||||||||||
3214 | aUIElement.m_aFloatingData.m_aSize = aSize; | ||||||||||||
3215 | aUIElement.m_bVisible = bVisible; | ||||||||||||
3216 | } | ||||||||||||
3217 | |||||||||||||
3218 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
3219 | } | ||||||||||||
3220 | else | ||||||||||||
3221 | { | ||||||||||||
3222 | implts_setLayoutDirty(); | ||||||||||||
3223 | bNotify = true; | ||||||||||||
3224 | } | ||||||||||||
3225 | } | ||||||||||||
3226 | |||||||||||||
3227 | if ( bNotify ) | ||||||||||||
3228 | m_pParentLayouter->requestLayout(); | ||||||||||||
3229 | } | ||||||||||||
3230 | |||||||||||||
3231 | void SAL_CALL ToolbarLayoutManager::windowMoved( const awt::WindowEvent& /*aEvent*/ ) | ||||||||||||
3232 | { | ||||||||||||
3233 | } | ||||||||||||
3234 | |||||||||||||
3235 | void SAL_CALL ToolbarLayoutManager::windowShown( const lang::EventObject& /*aEvent*/ ) | ||||||||||||
3236 | { | ||||||||||||
3237 | } | ||||||||||||
3238 | |||||||||||||
3239 | void SAL_CALL ToolbarLayoutManager::windowHidden( const lang::EventObject& /*aEvent*/ ) | ||||||||||||
3240 | { | ||||||||||||
3241 | } | ||||||||||||
3242 | |||||||||||||
3243 | // XDockableWindowListener | ||||||||||||
3244 | |||||||||||||
3245 | void SAL_CALL ToolbarLayoutManager::startDocking( const awt::DockingEvent& e ) | ||||||||||||
3246 | { | ||||||||||||
3247 | bool bWinFound( false ); | ||||||||||||
3248 | |||||||||||||
3249 | SolarMutexClearableGuard aReadGuard; | ||||||||||||
3250 | uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); | ||||||||||||
3251 | uno::Reference< awt::XWindow2 > xWindow( e.Source, uno::UNO_QUERY ); | ||||||||||||
3252 | aReadGuard.clear(); | ||||||||||||
3253 | |||||||||||||
3254 | UIElement aUIElement = implts_findToolbar( e.Source ); | ||||||||||||
3255 | |||||||||||||
3256 | if ( aUIElement.m_xUIElement.is() && xWindow.is() ) | ||||||||||||
3257 | { | ||||||||||||
3258 | bWinFound = true; | ||||||||||||
3259 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
3260 | if ( xDockWindow->isFloating() ) | ||||||||||||
3261 | { | ||||||||||||
3262 | awt::Rectangle aPos = xWindow->getPosSize(); | ||||||||||||
3263 | awt::Size aSize = xWindow->getOutputSize(); | ||||||||||||
3264 | |||||||||||||
3265 | aUIElement.m_aFloatingData.m_aPos = awt::Point(aPos.X, aPos.Y); | ||||||||||||
3266 | aUIElement.m_aFloatingData.m_aSize = aSize; | ||||||||||||
3267 | |||||||||||||
3268 | SolarMutexGuard aGuard; | ||||||||||||
3269 | |||||||||||||
3270 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
3271 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
3272 | { | ||||||||||||
3273 | ToolBox* pToolBox = static_cast<ToolBox *>(pWindow.get()); | ||||||||||||
3274 | aUIElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); | ||||||||||||
3275 | aUIElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox ); | ||||||||||||
3276 | } | ||||||||||||
3277 | } | ||||||||||||
3278 | } | ||||||||||||
3279 | |||||||||||||
3280 | SolarMutexGuard g; | ||||||||||||
3281 | m_bDockingInProgress = bWinFound; | ||||||||||||
3282 | m_aDockUIElement = aUIElement; | ||||||||||||
3283 | m_aDockUIElement.m_bUserActive = true; | ||||||||||||
3284 | } | ||||||||||||
3285 | |||||||||||||
3286 | awt::DockingData SAL_CALL ToolbarLayoutManager::docking( const awt::DockingEvent& e ) | ||||||||||||
3287 | { | ||||||||||||
3288 | constexpr sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25; | ||||||||||||
3289 | constexpr sal_Int32 MAGNETIC_DISTANCE_DOCK = 20; | ||||||||||||
3290 | |||||||||||||
3291 | SolarMutexClearableGuard aReadLock; | ||||||||||||
3292 | awt::DockingData aDockingData; | ||||||||||||
3293 | uno::Reference< awt::XDockableWindow > xDockWindow( e.Source, uno::UNO_QUERY ); | ||||||||||||
3294 | uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY ); | ||||||||||||
3295 | uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_TOP)] ); | ||||||||||||
3296 | uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_LEFT)] ); | ||||||||||||
3297 | uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_RIGHT)] ); | ||||||||||||
3298 | uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[int(ui::DockingArea_DOCKINGAREA_BOTTOM)] ); | ||||||||||||
3299 | uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); | ||||||||||||
3300 | UIElement aUIDockingElement( m_aDockUIElement ); | ||||||||||||
3301 | |||||||||||||
3302 | bool bDockingInProgress( m_bDockingInProgress ); | ||||||||||||
3303 | aReadLock.clear(); | ||||||||||||
3304 | |||||||||||||
3305 | if ( bDockingInProgress ) | ||||||||||||
3306 | aDockingData.TrackingRectangle = e.TrackingRectangle; | ||||||||||||
3307 | |||||||||||||
3308 | if ( bDockingInProgress && xDockWindow.is() && xWindow.is() ) | ||||||||||||
3309 | { | ||||||||||||
3310 | try | ||||||||||||
3311 | { | ||||||||||||
3312 | SolarMutexGuard aGuard; | ||||||||||||
3313 | |||||||||||||
3314 | DockingOperation eDockingOperation( DOCKOP_ON_COLROW ); | ||||||||||||
3315 | ui::DockingArea eDockingArea( ui::DockingArea(-1) ); // none | ||||||||||||
3316 | sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK ); | ||||||||||||
3317 | ::tools::Rectangle aTrackingRect( e.TrackingRectangle.X, e.TrackingRectangle.Y, | ||||||||||||
3318 | ( e.TrackingRectangle.X + e.TrackingRectangle.Width ), | ||||||||||||
3319 | ( e.TrackingRectangle.Y + e.TrackingRectangle.Height )); | ||||||||||||
3320 | |||||||||||||
3321 | awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize(); | ||||||||||||
3322 | ::tools::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height ); | ||||||||||||
3323 | ::tools::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone )); | ||||||||||||
3324 | |||||||||||||
3325 | aTmpRect = xBottomDockingWindow->getPosSize(); | ||||||||||||
3326 | ::tools::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height )); | ||||||||||||
3327 | ::tools::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone )); | ||||||||||||
3328 | |||||||||||||
3329 | aTmpRect = xLeftDockingWindow->getPosSize(); | ||||||||||||
3330 | ::tools::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); | ||||||||||||
3331 | ::tools::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone )); | ||||||||||||
3332 | |||||||||||||
3333 | aTmpRect = xRightDockingWindow->getPosSize(); | ||||||||||||
3334 | ::tools::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); | ||||||||||||
3335 | ::tools::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone )); | ||||||||||||
3336 | |||||||||||||
3337 | VclPtr<vcl::Window> pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) ); | ||||||||||||
3338 | ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ))); | ||||||||||||
3339 | |||||||||||||
3340 | if ( aHotZoneTopDockRect.IsInside( aMousePos )) | ||||||||||||
3341 | eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
3342 | else if ( aHotZoneBottomDockRect.IsInside( aMousePos )) | ||||||||||||
3343 | eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM; | ||||||||||||
3344 | else if ( aHotZoneLeftDockRect.IsInside( aMousePos )) | ||||||||||||
3345 | eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT; | ||||||||||||
3346 | else if ( aHotZoneRightDockRect.IsInside( aMousePos )) | ||||||||||||
3347 | eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT; | ||||||||||||
3348 | |||||||||||||
3349 | // Higher priority for movements inside the real docking area | ||||||||||||
3350 | if ( aTopDockRect.IsInside( aMousePos )) | ||||||||||||
3351 | eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
3352 | else if ( aBottomDockRect.IsInside( aMousePos )) | ||||||||||||
3353 | eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM; | ||||||||||||
3354 | else if ( aLeftDockRect.IsInside( aMousePos )) | ||||||||||||
3355 | eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT; | ||||||||||||
3356 | else if ( aRightDockRect.IsInside( aMousePos )) | ||||||||||||
3357 | eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT; | ||||||||||||
3358 | |||||||||||||
3359 | // Determine if we have a toolbar and set alignment according to the docking area! | ||||||||||||
3360 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
3361 | ToolBox* pToolBox = nullptr; | ||||||||||||
3362 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
3363 | pToolBox = static_cast<ToolBox *>(pWindow.get()); | ||||||||||||
3364 | |||||||||||||
3365 | if ( eDockingArea != ui::DockingArea(-1) ) | ||||||||||||
3366 | { | ||||||||||||
3367 | if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) | ||||||||||||
3368 | { | ||||||||||||
3369 | aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_TOP; | ||||||||||||
3370 | aUIDockingElement.m_bFloating = false; | ||||||||||||
3371 | } | ||||||||||||
3372 | else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) | ||||||||||||
3373 | { | ||||||||||||
3374 | aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_BOTTOM; | ||||||||||||
3375 | aUIDockingElement.m_bFloating = false; | ||||||||||||
3376 | } | ||||||||||||
3377 | else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) | ||||||||||||
3378 | { | ||||||||||||
3379 | aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_LEFT; | ||||||||||||
3380 | aUIDockingElement.m_bFloating = false; | ||||||||||||
3381 | } | ||||||||||||
3382 | else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ) | ||||||||||||
3383 | { | ||||||||||||
3384 | aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_RIGHT; | ||||||||||||
3385 | aUIDockingElement.m_bFloating = false; | ||||||||||||
3386 | } | ||||||||||||
3387 | |||||||||||||
3388 | ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() ); | ||||||||||||
3389 | aTrackingRect.SetPos( aOutputPos ); | ||||||||||||
3390 | |||||||||||||
3391 | ::tools::Rectangle aNewDockingRect( aTrackingRect ); | ||||||||||||
3392 | |||||||||||||
3393 | implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos ); | ||||||||||||
3394 | |||||||||||||
3395 | ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() ); | ||||||||||||
3396 | aDockingData.TrackingRectangle = awt::Rectangle( aScreenPos.X(), aScreenPos.Y(), | ||||||||||||
3397 | aNewDockingRect.getWidth(), aNewDockingRect.getHeight() ); | ||||||||||||
3398 | } | ||||||||||||
3399 | else if (pToolBox) | ||||||||||||
3400 | { | ||||||||||||
3401 | bool bIsHorizontal = isToolboxHorizontalAligned( pToolBox ); | ||||||||||||
3402 | awt::Size aFloatSize = aUIDockingElement.m_aFloatingData.m_aSize; | ||||||||||||
3403 | if ( aFloatSize.Width > 0 && aFloatSize.Height > 0 ) | ||||||||||||
3404 | { | ||||||||||||
3405 | aUIDockingElement.m_aFloatingData.m_aPos = AWTPoint(pContainerWindow->ScreenToOutputPixel(VCLPoint(e.MousePos))); | ||||||||||||
3406 | aDockingData.TrackingRectangle.Height = aFloatSize.Height; | ||||||||||||
3407 | aDockingData.TrackingRectangle.Width = aFloatSize.Width; | ||||||||||||
3408 | } | ||||||||||||
3409 | else | ||||||||||||
3410 | { | ||||||||||||
3411 | aFloatSize = AWTSize(pToolBox->CalcWindowSizePixel()); | ||||||||||||
3412 | if ( !bIsHorizontal ) | ||||||||||||
3413 | { | ||||||||||||
3414 | // Floating toolbars are always horizontal aligned! We have to swap | ||||||||||||
3415 | // width/height if we have a vertical aligned toolbar. | ||||||||||||
3416 | sal_Int32 nTemp = aFloatSize.Height; | ||||||||||||
3417 | aFloatSize.Height = aFloatSize.Width; | ||||||||||||
3418 | aFloatSize.Width = nTemp; | ||||||||||||
3419 | } | ||||||||||||
3420 | |||||||||||||
3421 | aDockingData.TrackingRectangle.Height = aFloatSize.Height; | ||||||||||||
3422 | aDockingData.TrackingRectangle.Width = aFloatSize.Width; | ||||||||||||
3423 | |||||||||||||
3424 | // For the first time we don't have any data about the floating size of a toolbar. | ||||||||||||
3425 | // We calculate it and store it for later use. | ||||||||||||
3426 | aUIDockingElement.m_aFloatingData.m_aPos = AWTPoint(pContainerWindow->ScreenToOutputPixel(VCLPoint(e.MousePos))); | ||||||||||||
3427 | aUIDockingElement.m_aFloatingData.m_aSize = aFloatSize; | ||||||||||||
3428 | aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); | ||||||||||||
3429 | aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox ); | ||||||||||||
3430 | } | ||||||||||||
3431 | aDockingData.TrackingRectangle.X = e.MousePos.X; | ||||||||||||
3432 | aDockingData.TrackingRectangle.Y = e.MousePos.Y; | ||||||||||||
3433 | } | ||||||||||||
3434 | |||||||||||||
3435 | aDockingData.bFloating = ( eDockingArea == ui::DockingArea(-1) ); | ||||||||||||
3436 | |||||||||||||
3437 | // Write current data to the member docking progress data | ||||||||||||
3438 | SolarMutexGuard g; | ||||||||||||
3439 | m_aDockUIElement.m_bFloating = aDockingData.bFloating; | ||||||||||||
3440 | if ( !aDockingData.bFloating ) | ||||||||||||
3441 | { | ||||||||||||
3442 | m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; | ||||||||||||
3443 | |||||||||||||
3444 | m_eDockOperation = eDockingOperation; | ||||||||||||
3445 | } | ||||||||||||
3446 | else | ||||||||||||
3447 | m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; | ||||||||||||
3448 | } | ||||||||||||
3449 | catch (const uno::Exception&) | ||||||||||||
3450 | { | ||||||||||||
3451 | } | ||||||||||||
3452 | } | ||||||||||||
3453 | |||||||||||||
3454 | return aDockingData; | ||||||||||||
3455 | } | ||||||||||||
3456 | |||||||||||||
3457 | void SAL_CALL ToolbarLayoutManager::endDocking( const awt::EndDockingEvent& e ) | ||||||||||||
3458 | { | ||||||||||||
3459 | if (e.bCancelled) | ||||||||||||
3460 | return; | ||||||||||||
3461 | |||||||||||||
3462 | bool bDockingInProgress( false ); | ||||||||||||
3463 | bool bStartDockFloated( false ); | ||||||||||||
3464 | bool bFloating( false ); | ||||||||||||
3465 | UIElement aUIDockingElement; | ||||||||||||
3466 | |||||||||||||
3467 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
3468 | SolarMutexResettableGuard aWriteLock; | ||||||||||||
3469 | bDockingInProgress = m_bDockingInProgress; | ||||||||||||
3470 | aUIDockingElement = m_aDockUIElement; | ||||||||||||
3471 | bFloating = aUIDockingElement.m_bFloating; | ||||||||||||
3472 | |||||||||||||
3473 | UIElement& rUIElement = impl_findToolbar( aUIDockingElement.m_aName ); | ||||||||||||
3474 | if ( rUIElement.m_aName == aUIDockingElement.m_aName ) | ||||||||||||
3475 | { | ||||||||||||
3476 | if ( aUIDockingElement.m_bFloating ) | ||||||||||||
3477 | { | ||||||||||||
3478 | // Write last position into position data | ||||||||||||
3479 | uno::Reference< awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
3480 | rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; | ||||||||||||
3481 | awt::Rectangle aTmpRect = xWindow->getPosSize(); | ||||||||||||
3482 | rUIElement.m_aFloatingData.m_aPos = awt::Point(aTmpRect.X, aTmpRect.Y); | ||||||||||||
3483 | // make changes also for our local data as we use it to make data persistent | ||||||||||||
3484 | aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData; | ||||||||||||
3485 | } | ||||||||||||
3486 | else | ||||||||||||
3487 | { | ||||||||||||
3488 | rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; | ||||||||||||
3489 | rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize; | ||||||||||||
3490 | |||||||||||||
3491 | if ( m_eDockOperation != DOCKOP_ON_COLROW ) | ||||||||||||
3492 | { | ||||||||||||
3493 | // we have to renumber our row/column data to insert a new row/column | ||||||||||||
3494 | implts_renumberRowColumnData(aUIDockingElement.m_aDockedData.m_nDockedArea, aUIDockingElement ); | ||||||||||||
3495 | } | ||||||||||||
3496 | } | ||||||||||||
3497 | |||||||||||||
3498 | bStartDockFloated = rUIElement.m_bFloating; | ||||||||||||
3499 | rUIElement.m_bFloating = m_aDockUIElement.m_bFloating; | ||||||||||||
3500 | rUIElement.m_bUserActive = true; | ||||||||||||
3501 | } | ||||||||||||
3502 | |||||||||||||
3503 | // reset member for next docking operation | ||||||||||||
3504 | m_aDockUIElement.m_xUIElement.clear(); | ||||||||||||
3505 | m_eDockOperation = DOCKOP_ON_COLROW; | ||||||||||||
3506 | aWriteLock.clear(); | ||||||||||||
3507 | /* SAFE AREA ----------------------------------------------------------------------------------------------- */ | ||||||||||||
3508 | |||||||||||||
3509 | implts_writeWindowStateData( aUIDockingElement ); | ||||||||||||
3510 | |||||||||||||
3511 | if ( bDockingInProgress ) | ||||||||||||
3512 | { | ||||||||||||
3513 | SolarMutexGuard aGuard; | ||||||||||||
3514 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( uno::Reference< awt::XWindow >( e.Source, uno::UNO_QUERY )); | ||||||||||||
3515 | ToolBox* pToolBox = nullptr; | ||||||||||||
3516 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
3517 | pToolBox = static_cast<ToolBox *>(pWindow.get()); | ||||||||||||
3518 | |||||||||||||
3519 | if ( pToolBox ) | ||||||||||||
3520 | { | ||||||||||||
3521 | if( e.bFloating ) | ||||||||||||
3522 | { | ||||||||||||
3523 | if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) | ||||||||||||
3524 | pToolBox->SetAlign(); | ||||||||||||
3525 | else | ||||||||||||
3526 | pToolBox->SetAlign( WindowAlign::Left ); | ||||||||||||
3527 | } | ||||||||||||
3528 | else | ||||||||||||
3529 | { | ||||||||||||
3530 | ::Size aSize; | ||||||||||||
3531 | |||||||||||||
3532 | pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); | ||||||||||||
3533 | |||||||||||||
3534 | // Docked toolbars have always one line | ||||||||||||
3535 | aSize = pToolBox->CalcWindowSizePixel( 1 ); | ||||||||||||
3536 | |||||||||||||
3537 | // Lock layouting updates as our listener would be called due to SetSizePixel | ||||||||||||
3538 | pToolBox->SetOutputSizePixel( aSize ); | ||||||||||||
3539 | } | ||||||||||||
3540 | } | ||||||||||||
3541 | } | ||||||||||||
3542 | |||||||||||||
3543 | implts_sortUIElements(); | ||||||||||||
3544 | |||||||||||||
3545 | aWriteLock.reset(); | ||||||||||||
3546 | m_bDockingInProgress = false; | ||||||||||||
3547 | m_bLayoutDirty = !bStartDockFloated || !bFloating; | ||||||||||||
3548 | bool bNotify = m_bLayoutDirty; | ||||||||||||
3549 | aWriteLock.clear(); | ||||||||||||
3550 | |||||||||||||
3551 | if ( bNotify ) | ||||||||||||
3552 | m_pParentLayouter->requestLayout(); | ||||||||||||
3553 | } | ||||||||||||
3554 | |||||||||||||
3555 | sal_Bool SAL_CALL ToolbarLayoutManager::prepareToggleFloatingMode( const lang::EventObject& e ) | ||||||||||||
3556 | { | ||||||||||||
3557 | SolarMutexClearableGuard aReadLock; | ||||||||||||
3558 | bool bDockingInProgress = m_bDockingInProgress; | ||||||||||||
3559 | aReadLock.clear(); | ||||||||||||
3560 | |||||||||||||
3561 | UIElement aUIDockingElement = implts_findToolbar( e.Source ); | ||||||||||||
3562 | bool bWinFound( !aUIDockingElement.m_aName.isEmpty() ); | ||||||||||||
3563 | uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY ); | ||||||||||||
3564 | |||||||||||||
3565 | if ( bWinFound && xWindow.is() ) | ||||||||||||
3566 | { | ||||||||||||
3567 | if ( !bDockingInProgress ) | ||||||||||||
3568 | { | ||||||||||||
3569 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
3570 | if ( xDockWindow->isFloating() ) | ||||||||||||
3571 | { | ||||||||||||
3572 | { | ||||||||||||
3573 | SolarMutexGuard aGuard; | ||||||||||||
3574 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||||||||
3575 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
3576 | { | ||||||||||||
3577 | ToolBox* pToolBox = static_cast< ToolBox *>( pWindow.get() ); | ||||||||||||
3578 | aUIDockingElement.m_aFloatingData.m_aPos = AWTPoint(pToolBox->GetPosPixel()); | ||||||||||||
3579 | aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pToolBox->GetOutputSizePixel()); | ||||||||||||
3580 | aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); | ||||||||||||
3581 | aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox ); | ||||||||||||
3582 | } | ||||||||||||
3583 | } | ||||||||||||
3584 | |||||||||||||
3585 | UIElement aUIElement = implts_findToolbar( aUIDockingElement.m_aName ); | ||||||||||||
3586 | if ( aUIElement.m_aName == aUIDockingElement.m_aName ) | ||||||||||||
3587 | implts_setToolbar( aUIDockingElement ); | ||||||||||||
3588 | } | ||||||||||||
3589 | } | ||||||||||||
3590 | } | ||||||||||||
3591 | |||||||||||||
3592 | return true; | ||||||||||||
3593 | } | ||||||||||||
3594 | |||||||||||||
3595 | void SAL_CALL ToolbarLayoutManager::toggleFloatingMode( const lang::EventObject& e ) | ||||||||||||
3596 | { | ||||||||||||
3597 | UIElement aUIDockingElement; | ||||||||||||
3598 | |||||||||||||
3599 | SolarMutexResettableGuard aReadLock; | ||||||||||||
3600 | bool bDockingInProgress( m_bDockingInProgress ); | ||||||||||||
3601 | if ( bDockingInProgress ) | ||||||||||||
3602 | aUIDockingElement = m_aDockUIElement; | ||||||||||||
3603 | aReadLock.clear(); | ||||||||||||
3604 | |||||||||||||
3605 | vcl::Window* pWindow( nullptr ); | ||||||||||||
3606 | ToolBox* pToolBox( nullptr ); | ||||||||||||
3607 | uno::Reference< awt::XWindow2 > xWindow; | ||||||||||||
3608 | |||||||||||||
3609 | { | ||||||||||||
3610 | SolarMutexGuard aGuard; | ||||||||||||
3611 | xWindow.set( e.Source, uno::UNO_QUERY ); | ||||||||||||
3612 | pWindow = VCLUnoHelper::GetWindow( xWindow ).get(); | ||||||||||||
3613 | |||||||||||||
3614 | if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX ) | ||||||||||||
3615 | pToolBox = static_cast<ToolBox *>(pWindow); | ||||||||||||
3616 | } | ||||||||||||
3617 | |||||||||||||
3618 | if ( !bDockingInProgress ) | ||||||||||||
3619 | { | ||||||||||||
3620 | aUIDockingElement = implts_findToolbar( e.Source ); | ||||||||||||
3621 | bool bWinFound = !aUIDockingElement.m_aName.isEmpty(); | ||||||||||||
3622 | |||||||||||||
3623 | if ( bWinFound && xWindow.is() ) | ||||||||||||
3624 | { | ||||||||||||
3625 | aUIDockingElement.m_bFloating = !aUIDockingElement.m_bFloating; | ||||||||||||
3626 | aUIDockingElement.m_bUserActive = true; | ||||||||||||
3627 | |||||||||||||
3628 | implts_setLayoutInProgress(); | ||||||||||||
3629 | if ( aUIDockingElement.m_bFloating ) | ||||||||||||
3630 | { | ||||||||||||
3631 | SolarMutexGuard aGuard; | ||||||||||||
3632 | if ( pToolBox ) | ||||||||||||
3633 | { | ||||||||||||
3634 | pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines ); | ||||||||||||
3635 | if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) | ||||||||||||
3636 | pToolBox->SetAlign(); | ||||||||||||
3637 | else | ||||||||||||
3638 | pToolBox->SetAlign( WindowAlign::Left ); | ||||||||||||
3639 | } | ||||||||||||
3640 | |||||||||||||
3641 | bool bUndefPos = hasDefaultPosValue( aUIDockingElement.m_aFloatingData.m_aPos ); | ||||||||||||
3642 | bool bSetSize = !hasEmptySize( aUIDockingElement.m_aFloatingData.m_aSize ); | ||||||||||||
3643 | |||||||||||||
3644 | if ( bUndefPos ) | ||||||||||||
3645 | aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos(); | ||||||||||||
3646 | |||||||||||||
3647 | if ( !bSetSize ) | ||||||||||||
3648 | { | ||||||||||||
3649 | if ( pToolBox ) | ||||||||||||
3650 | aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pToolBox->CalcFloatingWindowSizePixel()); | ||||||||||||
3651 | else if ( pWindow ) | ||||||||||||
3652 | aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pWindow->GetOutputSizePixel()); | ||||||||||||
3653 | } | ||||||||||||
3654 | |||||||||||||
3655 | xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X, | ||||||||||||
3656 | aUIDockingElement.m_aFloatingData.m_aPos.Y, | ||||||||||||
3657 | 0, 0, awt::PosSize::POS ); | ||||||||||||
3658 | xWindow->setOutputSize(aUIDockingElement.m_aFloatingData.m_aSize); | ||||||||||||
3659 | } | ||||||||||||
3660 | else | ||||||||||||
3661 | { | ||||||||||||
3662 | if ( isDefaultPos( aUIDockingElement.m_aDockedData.m_aPos )) | ||||||||||||
3663 | { | ||||||||||||
3664 | // Docking on its default position without a preset position - | ||||||||||||
3665 | // we have to find a good place for it. | ||||||||||||
3666 | ::Point aPixelPos; | ||||||||||||
3667 | awt::Point aDockPos; | ||||||||||||
3668 | ::Size aSize; | ||||||||||||
3669 | |||||||||||||
3670 | { | ||||||||||||
3671 | SolarMutexGuard aGuard; | ||||||||||||
3672 | if ( pToolBox ) | ||||||||||||
3673 | aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) ); | ||||||||||||
3674 | else if ( pWindow ) | ||||||||||||
3675 | aSize = pWindow->GetSizePixel(); | ||||||||||||
3676 | } | ||||||||||||
3677 | |||||||||||||
3678 | implts_findNextDockingPos(aUIDockingElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos ); | ||||||||||||
3679 | aUIDockingElement.m_aDockedData.m_aPos = aDockPos; | ||||||||||||
3680 | } | ||||||||||||
3681 | |||||||||||||
3682 | SolarMutexGuard aGuard; | ||||||||||||
3683 | if ( pToolBox ) | ||||||||||||
3684 | { | ||||||||||||
3685 | pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); | ||||||||||||
3686 | ::Size aSize = pToolBox->CalcWindowSizePixel( 1 ); | ||||||||||||
3687 | awt::Rectangle aRect = xWindow->getPosSize(); | ||||||||||||
3688 | xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, awt::PosSize::POS ); | ||||||||||||
3689 | xWindow->setOutputSize( AWTSize( aSize ) ); | ||||||||||||
3690 | } | ||||||||||||
3691 | } | ||||||||||||
3692 | |||||||||||||
3693 | implts_setLayoutInProgress( false ); | ||||||||||||
3694 | implts_setToolbar( aUIDockingElement ); | ||||||||||||
3695 | implts_writeWindowStateData( aUIDockingElement ); | ||||||||||||
3696 | implts_sortUIElements(); | ||||||||||||
3697 | implts_setLayoutDirty(); | ||||||||||||
3698 | |||||||||||||
3699 | aReadLock.reset(); | ||||||||||||
3700 | LayoutManager* pParentLayouter( m_pParentLayouter ); | ||||||||||||
3701 | aReadLock.clear(); | ||||||||||||
3702 | |||||||||||||
3703 | if ( pParentLayouter ) | ||||||||||||
3704 | pParentLayouter->requestLayout(); | ||||||||||||
3705 | } | ||||||||||||
3706 | } | ||||||||||||
3707 | else | ||||||||||||
3708 | { | ||||||||||||
3709 | SolarMutexGuard aGuard; | ||||||||||||
3710 | if ( pToolBox ) | ||||||||||||
3711 | { | ||||||||||||
3712 | if ( aUIDockingElement.m_bFloating ) | ||||||||||||
3713 | { | ||||||||||||
3714 | if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) | ||||||||||||
3715 | pToolBox->SetAlign(); | ||||||||||||
3716 | else | ||||||||||||
3717 | pToolBox->SetAlign( WindowAlign::Left ); | ||||||||||||
3718 | } | ||||||||||||
3719 | else | ||||||||||||
3720 | pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); | ||||||||||||
3721 | } | ||||||||||||
3722 | } | ||||||||||||
3723 | } | ||||||||||||
3724 | |||||||||||||
3725 | void SAL_CALL ToolbarLayoutManager::closed( const lang::EventObject& e ) | ||||||||||||
3726 | { | ||||||||||||
3727 | OUString aName; | ||||||||||||
3728 | UIElement aUIElement; | ||||||||||||
3729 | |||||||||||||
3730 | { | ||||||||||||
3731 | SolarMutexGuard aWriteLock; | ||||||||||||
3732 | for (auto& elem : m_aUIElements) | ||||||||||||
3733 | { | ||||||||||||
3734 | uno::Reference<ui::XUIElement> xUIElement(elem.m_xUIElement); | ||||||||||||
3735 | if (xUIElement.is()) | ||||||||||||
3736 | { | ||||||||||||
3737 | uno::Reference<uno::XInterface> xIfac(xUIElement->getRealInterface(), | ||||||||||||
3738 | uno::UNO_QUERY); | ||||||||||||
3739 | if (xIfac == e.Source) | ||||||||||||
3740 | { | ||||||||||||
3741 | aName = elem.m_aName; | ||||||||||||
3742 | |||||||||||||
3743 | // user closes a toolbar => | ||||||||||||
3744 | // context sensitive toolbar: only destroy toolbar and store state. | ||||||||||||
3745 | // non context sensitive toolbar: make it invisible, store state and destroy it. | ||||||||||||
3746 | if (!elem.m_bContextSensitive) | ||||||||||||
3747 | elem.m_bVisible = false; | ||||||||||||
3748 | |||||||||||||
3749 | aUIElement = elem; | ||||||||||||
3750 | break; | ||||||||||||
3751 | } | ||||||||||||
3752 | } | ||||||||||||
3753 | } | ||||||||||||
3754 | } | ||||||||||||
3755 | |||||||||||||
3756 | // destroy element | ||||||||||||
3757 | if ( aName.isEmpty() ) | ||||||||||||
3758 | return; | ||||||||||||
3759 | |||||||||||||
3760 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
3761 | destroyToolbar( aName ); | ||||||||||||
3762 | |||||||||||||
3763 | SolarMutexClearableGuard aReadLock; | ||||||||||||
3764 | bool bLayoutDirty = m_bLayoutDirty; | ||||||||||||
3765 | LayoutManager* pParentLayouter( m_pParentLayouter ); | ||||||||||||
3766 | aReadLock.clear(); | ||||||||||||
3767 | |||||||||||||
3768 | if ( bLayoutDirty && pParentLayouter ) | ||||||||||||
3769 | pParentLayouter->requestLayout(); | ||||||||||||
3770 | } | ||||||||||||
3771 | |||||||||||||
3772 | void SAL_CALL ToolbarLayoutManager::endPopupMode( const awt::EndPopupModeEvent& /*e*/ ) | ||||||||||||
3773 | { | ||||||||||||
3774 | } | ||||||||||||
3775 | |||||||||||||
3776 | // XUIConfigurationListener | ||||||||||||
3777 | |||||||||||||
3778 | void SAL_CALL ToolbarLayoutManager::elementInserted( const ui::ConfigurationEvent& rEvent ) | ||||||||||||
3779 | { | ||||||||||||
3780 | UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL ); | ||||||||||||
3781 | |||||||||||||
3782 | uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY ); | ||||||||||||
3783 | if ( xElementSettings.is() ) | ||||||||||||
3784 | { | ||||||||||||
3785 | uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY ); | ||||||||||||
3786 | if ( xPropSet.is() ) | ||||||||||||
3787 | { | ||||||||||||
3788 | if ( rEvent.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY )) | ||||||||||||
3789 | xPropSet->setPropertyValue( "ConfigurationSource", makeAny( m_xDocCfgMgr )); | ||||||||||||
3790 | } | ||||||||||||
3791 | xElementSettings->updateSettings(); | ||||||||||||
3792 | } | ||||||||||||
3793 | else | ||||||||||||
3794 | { | ||||||||||||
3795 | OUString aElementType; | ||||||||||||
3796 | OUString aElementName; | ||||||||||||
3797 | parseResourceURL( rEvent.ResourceURL, aElementType, aElementName ); | ||||||||||||
3798 | if ( aElementName.indexOf( "custom_" ) != -1 ) | ||||||||||||
3799 | { | ||||||||||||
3800 | // custom toolbar must be directly created, shown and layouted! | ||||||||||||
3801 | createToolbar( rEvent.ResourceURL ); | ||||||||||||
3802 | uno::Reference< ui::XUIElement > xUIElement = getToolbar( rEvent.ResourceURL ); | ||||||||||||
3803 | if ( xUIElement.is() ) | ||||||||||||
3804 | { | ||||||||||||
3805 | OUString aUIName; | ||||||||||||
3806 | uno::Reference< ui::XUIConfigurationManager > xCfgMgr; | ||||||||||||
3807 | uno::Reference< beans::XPropertySet > xPropSet; | ||||||||||||
3808 | |||||||||||||
3809 | try | ||||||||||||
3810 | { | ||||||||||||
3811 | xCfgMgr.set( rEvent.Source, uno::UNO_QUERY ); | ||||||||||||
3812 | xPropSet.set( xCfgMgr->getSettings( rEvent.ResourceURL, false ), uno::UNO_QUERY ); | ||||||||||||
3813 | |||||||||||||
3814 | if ( xPropSet.is() ) | ||||||||||||
3815 | xPropSet->getPropertyValue("UIName") >>= aUIName; | ||||||||||||
3816 | } | ||||||||||||
3817 | catch (const container::NoSuchElementException&) | ||||||||||||
3818 | { | ||||||||||||
3819 | } | ||||||||||||
3820 | catch (const beans::UnknownPropertyException&) | ||||||||||||
3821 | { | ||||||||||||
3822 | } | ||||||||||||
3823 | catch (const lang::WrappedTargetException&) | ||||||||||||
3824 | { | ||||||||||||
3825 | } | ||||||||||||
3826 | |||||||||||||
3827 | { | ||||||||||||
3828 | SolarMutexGuard aGuard; | ||||||||||||
3829 | vcl::Window* pWindow = getWindowFromXUIElement( xUIElement ); | ||||||||||||
3830 | if ( pWindow ) | ||||||||||||
3831 | pWindow->SetText( aUIName ); | ||||||||||||
3832 | } | ||||||||||||
3833 | |||||||||||||
3834 | showToolbar( rEvent.ResourceURL ); | ||||||||||||
3835 | } | ||||||||||||
3836 | } | ||||||||||||
3837 | } | ||||||||||||
3838 | } | ||||||||||||
3839 | |||||||||||||
3840 | void SAL_CALL ToolbarLayoutManager::elementRemoved( const ui::ConfigurationEvent& rEvent ) | ||||||||||||
3841 | { | ||||||||||||
3842 | SolarMutexClearableGuard aReadLock; | ||||||||||||
3843 | uno::Reference< awt::XWindow > xContainerWindow = m_xContainerWindow; | ||||||||||||
3844 | uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr ); | ||||||||||||
3845 | uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr ); | ||||||||||||
3846 | aReadLock.clear(); | ||||||||||||
3847 | |||||||||||||
3848 | UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL ); | ||||||||||||
3849 | uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY ); | ||||||||||||
3850 | if ( !xElementSettings.is() ) | ||||||||||||
3851 | return; | ||||||||||||
3852 | |||||||||||||
3853 | bool bNoSettings( false ); | ||||||||||||
3854 | OUString aConfigSourcePropName( "ConfigurationSource" ); | ||||||||||||
3855 | uno::Reference< uno::XInterface > xElementCfgMgr; | ||||||||||||
3856 | uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY ); | ||||||||||||
3857 | |||||||||||||
3858 | if ( xPropSet.is() ) | ||||||||||||
3859 | xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr; | ||||||||||||
3860 | |||||||||||||
3861 | if ( !xElementCfgMgr.is() ) | ||||||||||||
3862 | return; | ||||||||||||
3863 | |||||||||||||
3864 | // Check if the same UI configuration manager has changed => check further | ||||||||||||
3865 | if ( rEvent.Source == xElementCfgMgr ) | ||||||||||||
3866 | { | ||||||||||||
3867 | // Same UI configuration manager where our element has its settings | ||||||||||||
3868 | if ( rEvent.Source == uno::Reference< uno::XInterface >( xDocCfgMgr, uno::UNO_QUERY )) | ||||||||||||
3869 | { | ||||||||||||
3870 | // document settings removed | ||||||||||||
3871 | if ( xModuleCfgMgr->hasSettings( rEvent.ResourceURL )) | ||||||||||||
3872 | { | ||||||||||||
3873 | xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( xModuleCfgMgr )); | ||||||||||||
3874 | xElementSettings->updateSettings(); | ||||||||||||
3875 | return; | ||||||||||||
3876 | } | ||||||||||||
3877 | } | ||||||||||||
3878 | |||||||||||||
3879 | bNoSettings = true; | ||||||||||||
3880 | } | ||||||||||||
3881 | |||||||||||||
3882 | // No settings anymore, element must be destroyed | ||||||||||||
3883 | if ( xContainerWindow.is() && bNoSettings ) | ||||||||||||
3884 | destroyToolbar( rEvent.ResourceURL ); | ||||||||||||
3885 | } | ||||||||||||
3886 | |||||||||||||
3887 | void SAL_CALL ToolbarLayoutManager::elementReplaced( const ui::ConfigurationEvent& rEvent ) | ||||||||||||
3888 | { | ||||||||||||
3889 | UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL ); | ||||||||||||
3890 | |||||||||||||
3891 | uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY ); | ||||||||||||
3892 | if ( !xElementSettings.is() ) | ||||||||||||
3893 | return; | ||||||||||||
3894 | |||||||||||||
3895 | uno::Reference< uno::XInterface > xElementCfgMgr; | ||||||||||||
3896 | uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY ); | ||||||||||||
3897 | |||||||||||||
3898 | if ( xPropSet.is() ) | ||||||||||||
3899 | xPropSet->getPropertyValue( "ConfigurationSource" ) >>= xElementCfgMgr; | ||||||||||||
3900 | |||||||||||||
3901 | if ( !xElementCfgMgr.is() ) | ||||||||||||
3902 | return; | ||||||||||||
3903 | |||||||||||||
3904 | // Check if the same UI configuration manager has changed => update settings | ||||||||||||
3905 | if ( rEvent.Source != xElementCfgMgr ) | ||||||||||||
3906 | return; | ||||||||||||
3907 | |||||||||||||
3908 | xElementSettings->updateSettings(); | ||||||||||||
3909 | |||||||||||||
3910 | SolarMutexClearableGuard aWriteLock; | ||||||||||||
3911 | bool bNotify = !aUIElement.m_bFloating; | ||||||||||||
3912 | m_bLayoutDirty = bNotify; | ||||||||||||
3913 | LayoutManager* pParentLayouter( m_pParentLayouter ); | ||||||||||||
3914 | aWriteLock.clear(); | ||||||||||||
3915 | |||||||||||||
3916 | if ( bNotify && pParentLayouter ) | ||||||||||||
3917 | pParentLayouter->requestLayout(); | ||||||||||||
3918 | } | ||||||||||||
3919 | |||||||||||||
3920 | uno::Reference< ui::XUIElement > ToolbarLayoutManager::getToolbar( const OUString& aName ) | ||||||||||||
3921 | { | ||||||||||||
3922 | return implts_findToolbar( aName ).m_xUIElement; | ||||||||||||
3923 | } | ||||||||||||
3924 | |||||||||||||
3925 | uno::Sequence< uno::Reference< ui::XUIElement > > ToolbarLayoutManager::getToolbars() | ||||||||||||
3926 | { | ||||||||||||
3927 | uno::Sequence< uno::Reference< ui::XUIElement > > aSeq; | ||||||||||||
3928 | |||||||||||||
3929 | SolarMutexGuard g; | ||||||||||||
3930 | if ( !m_aUIElements.empty() ) | ||||||||||||
3931 | { | ||||||||||||
3932 | sal_uInt32 nCount(0); | ||||||||||||
3933 | for (auto const& elem : m_aUIElements) | ||||||||||||
3934 | { | ||||||||||||
3935 | if ( elem.m_xUIElement.is() ) | ||||||||||||
3936 | { | ||||||||||||
3937 | ++nCount; | ||||||||||||
3938 | aSeq.realloc( nCount ); | ||||||||||||
3939 | aSeq[nCount-1] = elem.m_xUIElement; | ||||||||||||
3940 | } | ||||||||||||
3941 | } | ||||||||||||
3942 | } | ||||||||||||
3943 | |||||||||||||
3944 | return aSeq; | ||||||||||||
3945 | } | ||||||||||||
3946 | |||||||||||||
3947 | bool ToolbarLayoutManager::floatToolbar( const OUString& rResourceURL ) | ||||||||||||
3948 | { | ||||||||||||
3949 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
3950 | if ( aUIElement.m_xUIElement.is() ) | ||||||||||||
3951 | { | ||||||||||||
3952 | try | ||||||||||||
3953 | { | ||||||||||||
3954 | uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
3955 | if ( xDockWindow.is() && !xDockWindow->isFloating() ) | ||||||||||||
3956 | { | ||||||||||||
3957 | aUIElement.m_bFloating = true; | ||||||||||||
3958 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
3959 | xDockWindow->setFloatingMode( true ); | ||||||||||||
3960 | |||||||||||||
3961 | implts_setLayoutDirty(); | ||||||||||||
3962 | implts_setToolbar( aUIElement ); | ||||||||||||
3963 | return true; | ||||||||||||
3964 | } | ||||||||||||
3965 | } | ||||||||||||
3966 | catch (const lang::DisposedException&) | ||||||||||||
3967 | { | ||||||||||||
3968 | } | ||||||||||||
3969 | } | ||||||||||||
3970 | |||||||||||||
3971 | return false; | ||||||||||||
3972 | } | ||||||||||||
3973 | |||||||||||||
3974 | bool ToolbarLayoutManager::lockToolbar( const OUString& rResourceURL ) | ||||||||||||
3975 | { | ||||||||||||
3976 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
3977 | if ( aUIElement.m_xUIElement.is() ) | ||||||||||||
3978 | { | ||||||||||||
3979 | try | ||||||||||||
3980 | { | ||||||||||||
3981 | uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
3982 | if ( xDockWindow.is() && !xDockWindow->isFloating() && !xDockWindow->isLocked() ) | ||||||||||||
3983 | { | ||||||||||||
3984 | aUIElement.m_aDockedData.m_bLocked = true; | ||||||||||||
3985 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
3986 | xDockWindow->lock(); | ||||||||||||
3987 | |||||||||||||
3988 | implts_setLayoutDirty(); | ||||||||||||
3989 | implts_setToolbar( aUIElement ); | ||||||||||||
3990 | return true; | ||||||||||||
3991 | } | ||||||||||||
3992 | } | ||||||||||||
3993 | catch (const lang::DisposedException&) | ||||||||||||
3994 | { | ||||||||||||
3995 | } | ||||||||||||
3996 | } | ||||||||||||
3997 | |||||||||||||
3998 | return false; | ||||||||||||
3999 | } | ||||||||||||
4000 | |||||||||||||
4001 | bool ToolbarLayoutManager::unlockToolbar( const OUString& rResourceURL ) | ||||||||||||
4002 | { | ||||||||||||
4003 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
4004 | if ( aUIElement.m_xUIElement.is() ) | ||||||||||||
4005 | { | ||||||||||||
4006 | try | ||||||||||||
4007 | { | ||||||||||||
4008 | uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); | ||||||||||||
4009 | if ( xDockWindow.is() && !xDockWindow->isFloating() && xDockWindow->isLocked() ) | ||||||||||||
4010 | { | ||||||||||||
4011 | aUIElement.m_aDockedData.m_bLocked = false; | ||||||||||||
4012 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
4013 | xDockWindow->unlock(); | ||||||||||||
4014 | |||||||||||||
4015 | implts_setLayoutDirty(); | ||||||||||||
4016 | implts_setToolbar( aUIElement ); | ||||||||||||
4017 | return true; | ||||||||||||
4018 | } | ||||||||||||
4019 | } | ||||||||||||
4020 | catch (const lang::DisposedException&) | ||||||||||||
4021 | { | ||||||||||||
4022 | } | ||||||||||||
4023 | } | ||||||||||||
4024 | |||||||||||||
4025 | return false; | ||||||||||||
4026 | } | ||||||||||||
4027 | |||||||||||||
4028 | bool ToolbarLayoutManager::isToolbarVisible( const OUString& rResourceURL ) | ||||||||||||
4029 | { | ||||||||||||
4030 | uno::Reference< awt::XWindow2 > xWindow2( implts_getXWindow( rResourceURL ), uno::UNO_QUERY ); | ||||||||||||
4031 | return ( xWindow2.is() && xWindow2->isVisible() ); | ||||||||||||
4032 | } | ||||||||||||
4033 | |||||||||||||
4034 | bool ToolbarLayoutManager::isToolbarFloating( const OUString& rResourceURL ) | ||||||||||||
4035 | { | ||||||||||||
4036 | uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY ); | ||||||||||||
4037 | return ( xDockWindow.is() && xDockWindow->isFloating() ); | ||||||||||||
4038 | } | ||||||||||||
4039 | |||||||||||||
4040 | bool ToolbarLayoutManager::isToolbarDocked( const OUString& rResourceURL ) | ||||||||||||
4041 | { | ||||||||||||
4042 | return !isToolbarFloating( rResourceURL ); | ||||||||||||
4043 | } | ||||||||||||
4044 | |||||||||||||
4045 | bool ToolbarLayoutManager::isToolbarLocked( const OUString& rResourceURL ) | ||||||||||||
4046 | { | ||||||||||||
4047 | uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY ); | ||||||||||||
4048 | return ( xDockWindow.is() && xDockWindow->isLocked() ); | ||||||||||||
4049 | } | ||||||||||||
4050 | |||||||||||||
4051 | awt::Size ToolbarLayoutManager::getToolbarSize( const OUString& rResourceURL ) | ||||||||||||
4052 | { | ||||||||||||
4053 | vcl::Window* pWindow = implts_getWindow( rResourceURL ); | ||||||||||||
4054 | |||||||||||||
4055 | SolarMutexGuard aGuard; | ||||||||||||
4056 | if ( pWindow ) | ||||||||||||
4057 | { | ||||||||||||
4058 | ::Size aSize = pWindow->GetSizePixel(); | ||||||||||||
4059 | awt::Size aWinSize; | ||||||||||||
4060 | aWinSize.Width = aSize.Width(); | ||||||||||||
4061 | aWinSize.Height = aSize.Height(); | ||||||||||||
4062 | return aWinSize; | ||||||||||||
4063 | } | ||||||||||||
4064 | |||||||||||||
4065 | return awt::Size(); | ||||||||||||
4066 | } | ||||||||||||
4067 | |||||||||||||
4068 | awt::Point ToolbarLayoutManager::getToolbarPos( const OUString& rResourceURL ) | ||||||||||||
4069 | { | ||||||||||||
4070 | awt::Point aPos; | ||||||||||||
4071 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
4072 | |||||||||||||
4073 | uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL )); | ||||||||||||
4074 | if ( xWindow.is() ) | ||||||||||||
4075 | { | ||||||||||||
4076 | if ( aUIElement.m_bFloating ) | ||||||||||||
4077 | { | ||||||||||||
4078 | awt::Rectangle aRect = xWindow->getPosSize(); | ||||||||||||
4079 | aPos.X = aRect.X; | ||||||||||||
4080 | aPos.Y = aRect.Y; | ||||||||||||
4081 | } | ||||||||||||
4082 | else | ||||||||||||
4083 | aPos = aUIElement.m_aDockedData.m_aPos; | ||||||||||||
4084 | } | ||||||||||||
4085 | |||||||||||||
4086 | return aPos; | ||||||||||||
4087 | } | ||||||||||||
4088 | |||||||||||||
4089 | void ToolbarLayoutManager::setToolbarSize( const OUString& rResourceURL, const awt::Size& aSize ) | ||||||||||||
4090 | { | ||||||||||||
4091 | uno::Reference< awt::XWindow2 > xWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY ); | ||||||||||||
4092 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
4093 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
4094 | |||||||||||||
4095 | if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() ) | ||||||||||||
4096 | { | ||||||||||||
4097 | xWindow->setOutputSize( aSize ); | ||||||||||||
4098 | aUIElement.m_aFloatingData.m_aSize = aSize; | ||||||||||||
4099 | implts_setToolbar( aUIElement ); | ||||||||||||
4100 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
4101 | implts_sortUIElements(); | ||||||||||||
4102 | } | ||||||||||||
4103 | } | ||||||||||||
4104 | |||||||||||||
4105 | void ToolbarLayoutManager::setToolbarPos( const OUString& rResourceURL, const awt::Point& aPos ) | ||||||||||||
4106 | { | ||||||||||||
4107 | uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL )); | ||||||||||||
4108 | uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); | ||||||||||||
4109 | UIElement aUIElement = implts_findToolbar( rResourceURL ); | ||||||||||||
4110 | |||||||||||||
4111 | if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() ) | ||||||||||||
4112 | { | ||||||||||||
4113 | xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS ); | ||||||||||||
4114 | aUIElement.m_aFloatingData.m_aPos = aPos; | ||||||||||||
4115 | implts_setToolbar( aUIElement ); | ||||||||||||
4116 | implts_writeWindowStateData( aUIElement ); | ||||||||||||
4117 | implts_sortUIElements(); | ||||||||||||
4118 | } | ||||||||||||
4119 | } | ||||||||||||
4120 | |||||||||||||
4121 | void ToolbarLayoutManager::setToolbarPosSize( const OUString& rResourceURL, const awt::Point& aPos, const awt::Size& aSize ) | ||||||||||||
4122 | { | ||||||||||||
4123 | setToolbarPos( rResourceURL, aPos ); | ||||||||||||
4124 | setToolbarSize( rResourceURL, aSize ); | ||||||||||||
4125 | } | ||||||||||||
4126 | |||||||||||||
4127 | } // namespace framework | ||||||||||||
4128 | |||||||||||||
4129 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | |
20 | #ifndef INCLUDED_RTL_REF_HXX |
21 | #define INCLUDED_RTL_REF_HXX |
22 | |
23 | #include "sal/config.h" |
24 | |
25 | #include <cassert> |
26 | #include <cstddef> |
27 | #include <functional> |
28 | #ifdef LIBO_INTERNAL_ONLY1 |
29 | #include <type_traits> |
30 | #endif |
31 | |
32 | #include "sal/types.h" |
33 | |
34 | namespace rtl |
35 | { |
36 | |
37 | /** Template reference class for reference type. |
38 | */ |
39 | template <class reference_type> |
40 | class Reference |
41 | { |
42 | /** The <b>reference_type</b> body pointer. |
43 | */ |
44 | reference_type * m_pBody; |
45 | |
46 | |
47 | public: |
48 | /** Constructor... |
49 | */ |
50 | Reference() |
51 | : m_pBody (NULL__null) |
52 | {} |
53 | |
54 | |
55 | /** Constructor... |
56 | */ |
57 | Reference (reference_type * pBody, __sal_NoAcquire) |
58 | : m_pBody (pBody) |
59 | { |
60 | } |
61 | |
62 | /** Constructor... |
63 | */ |
64 | Reference (reference_type * pBody) |
65 | : m_pBody (pBody) |
66 | { |
67 | if (m_pBody) |
68 | m_pBody->acquire(); |
69 | } |
70 | |
71 | /** Copy constructor... |
72 | */ |
73 | Reference (const Reference<reference_type> & handle) |
74 | : m_pBody (handle.m_pBody) |
75 | { |
76 | if (m_pBody) |
77 | m_pBody->acquire(); |
78 | } |
79 | |
80 | #ifdef LIBO_INTERNAL_ONLY1 |
81 | /** Move constructor... |
82 | */ |
83 | Reference (Reference<reference_type> && handle) noexcept |
84 | : m_pBody (handle.m_pBody) |
85 | { |
86 | handle.m_pBody = nullptr; |
87 | } |
88 | #endif |
89 | |
90 | #if defined LIBO_INTERNAL_ONLY1 |
91 | /** Up-casting conversion constructor: Copies interface reference. |
92 | |
93 | Does not work for up-casts to ambiguous bases. |
94 | |
95 | @param rRef another reference |
96 | */ |
97 | template< class derived_type > |
98 | inline Reference( |
99 | const Reference< derived_type > & rRef, |
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) |
101 | : m_pBody (rRef.get()) |
102 | { |
103 | if (m_pBody) |
104 | m_pBody->acquire(); |
105 | } |
106 | #endif |
107 | |
108 | /** Destructor... |
109 | */ |
110 | ~Reference() COVERITY_NOEXCEPT_FALSE |
111 | { |
112 | if (m_pBody) |
113 | m_pBody->release(); |
114 | } |
115 | |
116 | /** Set... |
117 | Similar to assignment. |
118 | */ |
119 | Reference<reference_type> & |
120 | SAL_CALL set (reference_type * pBody) |
121 | { |
122 | if (pBody) |
123 | pBody->acquire(); |
124 | reference_type * const pOld = m_pBody; |
125 | m_pBody = pBody; |
126 | if (pOld) |
127 | pOld->release(); |
128 | return *this; |
129 | } |
130 | |
131 | /** Assignment. |
132 | Unbinds this instance from its body (if bound) and |
133 | bind it to the body represented by the handle. |
134 | */ |
135 | Reference<reference_type> & |
136 | SAL_CALL operator= (const Reference<reference_type> & handle) |
137 | { |
138 | return set( handle.m_pBody ); |
139 | } |
140 | |
141 | #ifdef LIBO_INTERNAL_ONLY1 |
142 | /** Assignment. |
143 | * Unbinds this instance from its body (if bound), |
144 | * bind it to the body represented by the handle, and |
145 | * set the body represented by the handle to nullptr. |
146 | */ |
147 | Reference<reference_type> & |
148 | operator= (Reference<reference_type> && handle) |
149 | { |
150 | // self-movement guts ourself |
151 | if (m_pBody) |
152 | m_pBody->release(); |
153 | m_pBody = handle.m_pBody; |
154 | handle.m_pBody = nullptr; |
155 | return *this; |
156 | } |
157 | #endif |
158 | |
159 | /** Assignment... |
160 | */ |
161 | Reference<reference_type> & |
162 | SAL_CALL operator= (reference_type * pBody) |
163 | { |
164 | return set( pBody ); |
165 | } |
166 | |
167 | /** Unbind the body from this handle. |
168 | Note that for a handle representing a large body, |
169 | "handle.clear().set(new body());" _might_ |
170 | perform a little bit better than "handle.set(new body());", |
171 | since in the second case two large objects exist in memory |
172 | (the old body and the new body). |
173 | */ |
174 | Reference<reference_type> & SAL_CALL clear() |
175 | { |
176 | if (m_pBody) |
177 | { |
178 | reference_type * const pOld = m_pBody; |
179 | m_pBody = NULL__null; |
180 | pOld->release(); |
181 | } |
182 | return *this; |
183 | } |
184 | |
185 | |
186 | /** Get the body. Can be used instead of operator->(). |
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
188 | are the same. |
189 | */ |
190 | reference_type * SAL_CALL get() const |
191 | { |
192 | return m_pBody; |
193 | } |
194 | |
195 | |
196 | /** Probably most common used: handle->someBodyOp(). |
197 | */ |
198 | reference_type * SAL_CALL operator->() const |
199 | { |
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); |
201 | return m_pBody; |
202 | } |
203 | |
204 | |
205 | /** Allows (*handle).someBodyOp(). |
206 | */ |
207 | reference_type & SAL_CALL operator*() const |
208 | { |
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); |
210 | return *m_pBody; |
211 | } |
212 | |
213 | |
214 | /** Returns True if the handle does point to a valid body. |
215 | */ |
216 | bool SAL_CALL is() const |
217 | { |
218 | return (m_pBody != NULL__null); |
219 | } |
220 | |
221 | #if defined LIBO_INTERNAL_ONLY1 |
222 | /** Returns True if the handle does point to a valid body. |
223 | */ |
224 | explicit operator bool() const |
225 | { |
226 | return is(); |
227 | } |
228 | #endif |
229 | |
230 | /** Returns True if this points to pBody. |
231 | */ |
232 | bool SAL_CALL operator== (const reference_type * pBody) const |
233 | { |
234 | return (m_pBody == pBody); |
235 | } |
236 | |
237 | |
238 | /** Returns True if handle points to the same body. |
239 | */ |
240 | bool |
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const |
242 | { |
243 | return (m_pBody == handle.m_pBody); |
244 | } |
245 | |
246 | |
247 | /** Needed to place References into STL collection. |
248 | */ |
249 | bool |
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const |
251 | { |
252 | return (m_pBody != handle.m_pBody); |
253 | } |
254 | |
255 | |
256 | /** Needed to place References into STL collection. |
257 | */ |
258 | bool |
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const |
260 | { |
261 | return (m_pBody < handle.m_pBody); |
262 | } |
263 | |
264 | |
265 | /** Needed to place References into STL collection. |
266 | */ |
267 | bool |
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const |
269 | { |
270 | return (m_pBody > handle.m_pBody); |
271 | } |
272 | }; |
273 | |
274 | } // namespace rtl |
275 | |
276 | #if defined LIBO_INTERNAL_ONLY1 |
277 | namespace std |
278 | { |
279 | |
280 | /// @cond INTERNAL |
281 | /** |
282 | Make rtl::Reference hashable by default for use in STL containers. |
283 | |
284 | @since LibreOffice 6.3 |
285 | */ |
286 | template<typename T> |
287 | struct hash<::rtl::Reference<T>> |
288 | { |
289 | std::size_t operator()(::rtl::Reference<T> const & s) const |
290 | { return std::size_t(s.get()); } |
291 | }; |
292 | /// @endcond |
293 | |
294 | } |
295 | |
296 | #endif |
297 | |
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ |
299 | |
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |