Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "svdata.hxx"
31 : :
32 : : #include "vcl/arrange.hxx"
33 : : #include "vcl/edit.hxx"
34 : : #include "vcl/svapp.hxx"
35 : :
36 : : #include "com/sun/star/beans/PropertyValue.hpp"
37 : : #include "com/sun/star/awt/Rectangle.hpp"
38 : :
39 : : #include "osl/diagnose.h"
40 : :
41 : : using namespace vcl;
42 : : using namespace com::sun::star;
43 : :
44 : : // ----------------------------------------
45 : : // vcl::WindowArranger
46 : : //-----------------------------------------
47 : :
48 : 0 : long WindowArranger::getDefaultBorder()
49 : : {
50 : 0 : ImplSVData* pSVData = ImplGetSVData();
51 : 0 : long nResult = pSVData->maAppData.mnDefaultLayoutBorder;
52 [ # # ]: 0 : if( nResult < 0 )
53 : : {
54 : 0 : OutputDevice* pDefDev = Application::GetDefaultDevice();
55 [ # # ]: 0 : if( pDefDev )
56 : : {
57 [ # # ][ # # ]: 0 : Size aBorder( pDefDev->LogicToPixel( Size( 3, 3 ), MapMode( MAP_APPFONT ) ) );
[ # # ]
58 : 0 : nResult = pSVData->maAppData.mnDefaultLayoutBorder = aBorder.Height();
59 : : }
60 : : }
61 : 0 : return nResult > 0 ? nResult : 0;
62 : : }
63 : :
64 : 0 : WindowArranger::~WindowArranger()
65 [ # # ]: 0 : {}
66 : :
67 : 0 : void WindowArranger::setParent( WindowArranger* i_pParent )
68 : : {
69 [ # # ]: 0 : OSL_VERIFY( i_pParent->m_pParentWindow == m_pParentWindow || m_pParentWindow == NULL );
70 : :
71 : 0 : m_pParentArranger = i_pParent;
72 : 0 : m_pParentWindow = i_pParent->m_pParentWindow;
73 : 0 : setParentWindow( m_pParentWindow );
74 : 0 : }
75 : :
76 : 0 : void WindowArranger::setParentWindow( Window* i_pNewParent )
77 : : {
78 : 0 : m_pParentWindow = i_pNewParent;
79 : :
80 : 0 : size_t nEle = countElements();
81 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
82 : : {
83 : 0 : Element* pEle = getElement( i );
84 [ # # ]: 0 : if( pEle ) // sanity check
85 : : {
86 : : #if OSL_DEBUG_LEVEL > 0
87 : : if( pEle->m_pElement )
88 : : {
89 : : OSL_VERIFY( pEle->m_pElement->GetParent() == i_pNewParent );
90 : : }
91 : : #endif
92 [ # # ]: 0 : if( pEle->m_pChild )
93 : 0 : pEle->m_pChild->setParentWindow( i_pNewParent );
94 : : }
95 : : }
96 : 0 : }
97 : :
98 : 0 : void WindowArranger::show( bool i_bShow, bool i_bImmediateUpdate )
99 : : {
100 : 0 : size_t nEle = countElements();
101 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
102 : : {
103 : 0 : Element* pEle = getElement( i );
104 [ # # ]: 0 : if( pEle ) // sanity check
105 : : {
106 : 0 : pEle->m_bHidden = ! i_bShow;
107 [ # # ]: 0 : if( pEle->m_pElement )
108 : 0 : pEle->m_pElement->Show( i_bShow );
109 [ # # ]: 0 : if( pEle->m_pChild.get() )
110 : 0 : pEle->m_pChild->show( i_bShow, false );
111 : : }
112 : : }
113 [ # # ]: 0 : if( m_pParentArranger )
114 : : {
115 : 0 : nEle = m_pParentArranger->countElements();
116 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
117 : : {
118 : 0 : Element* pEle = m_pParentArranger->getElement( i );
119 [ # # ][ # # ]: 0 : if( pEle && pEle->m_pChild.get() == this )
[ # # ]
120 : : {
121 : 0 : pEle->m_bHidden = ! i_bShow;
122 : 0 : break;
123 : : }
124 : : }
125 : : }
126 [ # # ]: 0 : if( i_bImmediateUpdate )
127 : : {
128 : : // find the topmost parent
129 : 0 : WindowArranger* pResize = this;
130 [ # # ]: 0 : while( pResize->m_pParentArranger )
131 : 0 : pResize = pResize->m_pParentArranger;
132 : 0 : pResize->resize();
133 : : }
134 : 0 : }
135 : :
136 : 0 : bool WindowArranger::isVisible() const
137 : : {
138 : 0 : size_t nEle = countElements();
139 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
140 : : {
141 : 0 : const Element* pEle = getConstElement( i );
142 [ # # ]: 0 : if( pEle->isVisible() )
143 : 0 : return true;
144 : : }
145 : 0 : return false;
146 : : }
147 : :
148 : 0 : bool WindowArranger::Element::isVisible() const
149 : : {
150 : 0 : bool bVisible = false;
151 [ # # ]: 0 : if( ! m_bHidden )
152 : : {
153 [ # # ]: 0 : if( m_pElement )
154 : 0 : bVisible = m_pElement->IsVisible();
155 [ # # ]: 0 : else if( m_pChild )
156 : 0 : bVisible = m_pChild->isVisible();
157 : : }
158 : 0 : return bVisible;
159 : : }
160 : :
161 : 0 : sal_Int32 WindowArranger::Element::getExpandPriority() const
162 : : {
163 : 0 : sal_Int32 nPrio = m_nExpandPriority;
164 [ # # ][ # # ]: 0 : if( m_pChild && m_nExpandPriority >= 0 )
[ # # ]
165 : : {
166 : 0 : size_t nElements = m_pChild->countElements();
167 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
168 : : {
169 : 0 : sal_Int32 nCPrio = m_pChild->getExpandPriority( i );
170 [ # # ]: 0 : if( nCPrio > nPrio )
171 : 0 : nPrio = nCPrio;
172 : : }
173 : : }
174 : 0 : return nPrio;
175 : : }
176 : :
177 : 0 : Size WindowArranger::Element::getOptimalSize( WindowSizeType i_eType ) const
178 : : {
179 : 0 : Size aResult;
180 [ # # ]: 0 : if( ! m_bHidden )
181 : : {
182 : 0 : bool bVisible = false;
183 [ # # ][ # # ]: 0 : if( m_pElement && m_pElement->IsVisible() )
[ # # ]
184 : : {
185 : 0 : aResult = m_pElement->GetOptimalSize( i_eType );
186 : 0 : bVisible = true;
187 : : }
188 [ # # ][ # # ]: 0 : else if( m_pChild && m_pChild->isVisible() )
[ # # ]
189 : : {
190 : 0 : aResult = m_pChild->getOptimalSize( i_eType );
191 : 0 : bVisible = true;
192 : : }
193 [ # # ]: 0 : if( bVisible )
194 : : {
195 [ # # ]: 0 : if( aResult.Width() < m_aMinSize.Width() )
196 : 0 : aResult.Width() = m_aMinSize.Width();
197 [ # # ]: 0 : if( aResult.Height() < m_aMinSize.Height() )
198 : 0 : aResult.Height() = m_aMinSize.Height();
199 : 0 : aResult.Width() += getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder );
200 : 0 : aResult.Height() += getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder );
201 : : }
202 : : }
203 : :
204 : 0 : return aResult;
205 : : }
206 : :
207 : 0 : void WindowArranger::Element::setPosSize( const Point& i_rPos, const Size& i_rSize )
208 : : {
209 : 0 : Point aPoint( i_rPos );
210 : 0 : Size aSize( i_rSize );
211 [ # # ]: 0 : aPoint.X() += getBorderValue( m_nLeftBorder );
212 [ # # ]: 0 : aPoint.Y() += getBorderValue( m_nTopBorder );
213 [ # # ][ # # ]: 0 : aSize.Width() -= getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder );
214 [ # # ][ # # ]: 0 : aSize.Height() -= getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder );
215 [ # # ]: 0 : if( m_pElement )
216 [ # # ]: 0 : m_pElement->SetPosSizePixel( aPoint, aSize );
217 [ # # ]: 0 : else if( m_pChild )
218 [ # # ][ # # ]: 0 : m_pChild->setManagedArea( Rectangle( aPoint, aSize ) );
219 : 0 : }
220 : :
221 : 0 : uno::Sequence< beans::PropertyValue > WindowArranger::getProperties() const
222 : : {
223 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aRet( 3 );
224 [ # # ][ # # ]: 0 : aRet[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OuterBorder" ) );
225 [ # # ][ # # ]: 0 : aRet[0].Value = uno::makeAny( sal_Int32( getBorderValue( m_nOuterBorder ) ) );
[ # # ]
226 [ # # ][ # # ]: 0 : aRet[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ManagedArea" ) );
227 : 0 : awt::Rectangle aArea( m_aManagedArea.getX(), m_aManagedArea.getY(), m_aManagedArea.getWidth(), m_aManagedArea.getHeight() );
228 [ # # ][ # # ]: 0 : aRet[1].Value = uno::makeAny( aArea );
229 [ # # ][ # # ]: 0 : aRet[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) );
230 [ # # ][ # # ]: 0 : aRet[2].Value = uno::makeAny( sal_Bool( isVisible() ) );
[ # # ]
231 : 0 : return aRet;
232 : : }
233 : :
234 : 0 : void WindowArranger::setProperties( const uno::Sequence< beans::PropertyValue >& i_rProps )
235 : : {
236 : 0 : const beans::PropertyValue* pProps = i_rProps.getConstArray();
237 : 0 : bool bResize = false;
238 [ # # ]: 0 : for( sal_Int32 i = 0; i < i_rProps.getLength(); i++ )
239 : : {
240 [ # # ]: 0 : if ( pProps[i].Name == "OuterBorder" )
241 : : {
242 : 0 : sal_Int32 nVal = 0;
243 [ # # ]: 0 : if( pProps[i].Value >>= nVal )
244 : : {
245 [ # # ][ # # ]: 0 : if( getBorderValue( m_nOuterBorder ) != nVal )
246 : : {
247 : 0 : m_nOuterBorder = nVal;
248 : 0 : bResize = true;
249 : : }
250 : : }
251 : : }
252 [ # # ]: 0 : else if ( pProps[i].Name == "ManagedArea" )
253 : : {
254 : 0 : awt::Rectangle aArea( 0, 0, 0, 0 );
255 [ # # ][ # # ]: 0 : if( pProps[i].Value >>= aArea )
256 : : {
257 : 0 : m_aManagedArea.setX( aArea.X );
258 : 0 : m_aManagedArea.setY( aArea.Y );
259 : 0 : m_aManagedArea.setWidth( aArea.Width );
260 : 0 : m_aManagedArea.setHeight( aArea.Height );
261 : 0 : bResize = true;
262 : : }
263 : : }
264 [ # # ]: 0 : else if ( pProps[i].Name == "Visible" )
265 : : {
266 : 0 : sal_Bool bVal = sal_False;
267 [ # # ]: 0 : if( pProps[i].Value >>= bVal )
268 : : {
269 [ # # ]: 0 : show( bVal, false );
270 : 0 : bResize = true;
271 : : }
272 : : }
273 : : }
274 [ # # ]: 0 : if( bResize )
275 : 0 : resize();
276 : 0 : }
277 : :
278 : :
279 : : // ----------------------------------------
280 : : // vcl::RowOrColumn
281 : : //-----------------------------------------
282 : :
283 : 0 : RowOrColumn::~RowOrColumn()
284 : : {
285 [ # # # # ]: 0 : for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
[ # # ]
286 : 0 : it != m_aElements.end(); ++it )
287 : : {
288 [ # # ][ # # ]: 0 : it->deleteChild();
289 : : }
290 [ # # ]: 0 : }
291 : :
292 : 0 : Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const
293 : : {
294 : 0 : Size aRet( 0, 0 );
295 : 0 : long nDistance = getBorderValue( m_nBorderWidth );
296 [ # # # # ]: 0 : for( std::vector< WindowArranger::Element >::const_iterator it = m_aElements.begin();
[ # # ]
297 : 0 : it != m_aElements.end(); ++it )
298 : : {
299 [ # # ][ # # ]: 0 : if( it->isVisible() )
[ # # ]
300 : : {
301 : : // get the size of type of the managed element
302 [ # # ][ # # ]: 0 : Size aElementSize( it->getOptimalSize( i_eType ) );
303 [ # # ]: 0 : if( m_bColumn )
304 : : {
305 : : // add the distance between elements
306 : 0 : aRet.Height() += nDistance;
307 : : // check if the width needs adjustment
308 [ # # ]: 0 : if( aRet.Width() < aElementSize.Width() )
309 : 0 : aRet.Width() = aElementSize.Width();
310 : 0 : aRet.Height() += aElementSize.Height();
311 : : }
312 : : else
313 : : {
314 : : // add the distance between elements
315 : 0 : aRet.Width() += nDistance;
316 : : // check if the height needs adjustment
317 [ # # ]: 0 : if( aRet.Height() < aElementSize.Height() )
318 : 0 : aRet.Height() = aElementSize.Height();
319 : 0 : aRet.Width() += aElementSize.Width();
320 : : }
321 : : }
322 : : }
323 : :
324 [ # # ][ # # ]: 0 : if( aRet.Width() != 0 || aRet.Height() != 0 )
[ # # ]
325 : : {
326 : : // subtract the border for the first element
327 [ # # ]: 0 : if( m_bColumn )
328 : 0 : aRet.Height() -= nDistance;
329 : : else
330 : 0 : aRet.Width() -= nDistance;
331 : :
332 : : // add the outer border
333 : 0 : long nOuterBorder = getBorderValue( m_nOuterBorder );
334 : 0 : aRet.Width() += 2*nOuterBorder;
335 : 0 : aRet.Height() += 2*nOuterBorder;
336 : : }
337 : :
338 : 0 : return aRet;
339 : : }
340 : :
341 : 0 : void RowOrColumn::distributeRowWidth( std::vector<Size>& io_rSizes, long /*i_nUsedWidth*/, long i_nExtraWidth )
342 : : {
343 [ # # ][ # # ]: 0 : if( ! io_rSizes.empty() && io_rSizes.size() == m_aElements.size() )
[ # # ]
344 : : {
345 : : // find all elements with the highest expand priority
346 : 0 : size_t nElements = m_aElements.size();
347 [ # # ]: 0 : std::vector< size_t > aIndices;
348 : 0 : sal_Int32 nHighPrio = 0;
349 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
350 : : {
351 [ # # ][ # # ]: 0 : if( m_aElements[ i ].isVisible() )
[ # # ]
352 : : {
353 [ # # ][ # # ]: 0 : sal_Int32 nCurPrio = m_aElements[ i ].getExpandPriority();
354 [ # # ]: 0 : if( nCurPrio > nHighPrio )
355 : : {
356 : 0 : aIndices.clear();
357 : 0 : nHighPrio = nCurPrio;
358 : : }
359 [ # # ]: 0 : if( nCurPrio == nHighPrio )
360 [ # # ]: 0 : aIndices.push_back( i );
361 : : }
362 : : }
363 : :
364 : : // distribute extra space evenly among collected elements
365 : 0 : nElements = aIndices.size();
366 [ # # ]: 0 : if( nElements > 0 )
367 : : {
368 : 0 : long nDelta = i_nExtraWidth / nElements;
369 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
370 : : {
371 [ # # ]: 0 : io_rSizes[ aIndices[i] ].Width() += nDelta;
372 : 0 : i_nExtraWidth -= nDelta;
373 : : }
374 : : // add the last pixels to the last row element
375 [ # # ][ # # ]: 0 : if( i_nExtraWidth > 0 && nElements > 0 )
376 [ # # ]: 0 : io_rSizes[aIndices.back()].Width() += i_nExtraWidth;
377 : 0 : }
378 : : }
379 : 0 : }
380 : :
381 : 0 : void RowOrColumn::distributeColumnHeight( std::vector<Size>& io_rSizes, long /*i_nUsedHeight*/, long i_nExtraHeight )
382 : : {
383 [ # # ][ # # ]: 0 : if( ! io_rSizes.empty() && io_rSizes.size() == m_aElements.size() )
[ # # ]
384 : : {
385 : : // find all elements with the highest expand priority
386 : 0 : size_t nElements = m_aElements.size();
387 [ # # ]: 0 : std::vector< size_t > aIndices;
388 : 0 : sal_Int32 nHighPrio = 3;
389 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
390 : : {
391 [ # # ][ # # ]: 0 : if( m_aElements[ i ].isVisible() )
[ # # ]
392 : : {
393 [ # # ][ # # ]: 0 : sal_Int32 nCurPrio = m_aElements[ i ].getExpandPriority();
394 [ # # ]: 0 : if( nCurPrio > nHighPrio )
395 : : {
396 : 0 : aIndices.clear();
397 : 0 : nHighPrio = nCurPrio;
398 : : }
399 [ # # ]: 0 : if( nCurPrio == nHighPrio )
400 [ # # ]: 0 : aIndices.push_back( i );
401 : : }
402 : : }
403 : :
404 : : // distribute extra space evenly among collected elements
405 : 0 : nElements = aIndices.size();
406 [ # # ]: 0 : if( nElements > 0 )
407 : : {
408 : 0 : long nDelta = i_nExtraHeight / nElements;
409 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
410 : : {
411 [ # # ]: 0 : io_rSizes[ aIndices[i] ].Height() += nDelta;
412 : 0 : i_nExtraHeight -= nDelta;
413 : : }
414 : : // add the last pixels to the last row element
415 [ # # ][ # # ]: 0 : if( i_nExtraHeight > 0 && nElements > 0 )
416 [ # # ]: 0 : io_rSizes[aIndices.back()].Height() += i_nExtraHeight;
417 : 0 : }
418 : : }
419 : 0 : }
420 : :
421 : 0 : void RowOrColumn::resize()
422 : : {
423 : : // check if we can get optimal size, else fallback to minimal size
424 [ # # ]: 0 : Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED ) );
425 : 0 : WindowSizeType eType = WINDOWSIZE_PREFERRED;
426 [ # # ]: 0 : if( m_bColumn )
427 : : {
428 [ # # ][ # # ]: 0 : if( aOptSize.Height() > m_aManagedArea.GetHeight() )
429 : 0 : eType = WINDOWSIZE_MINIMUM;
430 : : }
431 : : else
432 : : {
433 [ # # ][ # # ]: 0 : if( aOptSize.Width() > m_aManagedArea.GetWidth() )
434 : 0 : eType = WINDOWSIZE_MINIMUM;
435 : : }
436 : :
437 : 0 : size_t nElements = m_aElements.size();
438 : : // get all element sizes for sizing
439 [ # # ]: 0 : std::vector<Size> aElementSizes( nElements );
440 [ # # ]: 0 : long nDistance = getBorderValue( m_nBorderWidth );
441 [ # # ]: 0 : long nOuterBorder = getBorderValue( m_nOuterBorder );
442 [ # # ]: 0 : long nUsedWidth = 2*nOuterBorder - (nElements ? nDistance : 0);
443 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
444 : : {
445 [ # # ][ # # ]: 0 : if( m_aElements[i].isVisible() )
[ # # ]
446 : : {
447 [ # # ][ # # ]: 0 : aElementSizes[i] = m_aElements[i].getOptimalSize( eType );
448 [ # # ]: 0 : if( m_bColumn )
449 : : {
450 [ # # ]: 0 : aElementSizes[i].Width() = m_aManagedArea.GetWidth() - 2 * nOuterBorder;
451 : 0 : nUsedWidth += aElementSizes[i].Height() + nDistance;
452 : : }
453 : : else
454 : : {
455 [ # # ]: 0 : aElementSizes[i].Height() = m_aManagedArea.GetHeight() - 2 * nOuterBorder;
456 : 0 : nUsedWidth += aElementSizes[i].Width() + nDistance;
457 : : }
458 : : }
459 : : }
460 : :
461 [ # # ][ # # ]: 0 : long nExtraWidth = (m_bColumn ? m_aManagedArea.GetHeight() : m_aManagedArea.GetWidth()) - nUsedWidth;
[ # # ]
462 [ # # ]: 0 : if( nExtraWidth > 0 )
463 : : {
464 [ # # ]: 0 : if( m_bColumn )
465 [ # # ]: 0 : distributeColumnHeight( aElementSizes, nUsedWidth, nExtraWidth );
466 : : else
467 [ # # ]: 0 : distributeRowWidth( aElementSizes, nUsedWidth, nExtraWidth );
468 : : }
469 : :
470 : : // get starting position
471 : 0 : Point aElementPos( m_aManagedArea.TopLeft() );
472 : : // outer border
473 : 0 : aElementPos.X() += nOuterBorder;
474 : 0 : aElementPos.Y() += nOuterBorder;
475 : :
476 : : // position managed windows
477 [ # # ]: 0 : for( size_t i = 0; i < nElements; i++ )
478 : : {
479 : : // get the size of type of the managed element
480 [ # # ][ # # ]: 0 : if( m_aElements[i].isVisible() )
[ # # ]
481 : : {
482 [ # # ][ # # ]: 0 : m_aElements[i].setPosSize( aElementPos, aElementSizes[i] );
483 [ # # ]: 0 : if( m_bColumn )
484 : 0 : aElementPos.Y() += nDistance + aElementSizes[i].Height();
485 : : else
486 : 0 : aElementPos.X() += nDistance + aElementSizes[i].Width();
487 : : }
488 : 0 : }
489 : 0 : }
490 : :
491 : 0 : size_t RowOrColumn::addWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio, const Size& i_rMinSize, size_t i_nIndex )
492 : : {
493 : 0 : size_t nIndex = i_nIndex;
494 [ # # ]: 0 : if( i_nIndex >= m_aElements.size() )
495 : : {
496 : 0 : nIndex = m_aElements.size();
497 [ # # ][ # # ]: 0 : m_aElements.push_back( WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) );
[ # # ]
498 : : }
499 : : else
500 : : {
501 : 0 : std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
502 [ # # ]: 0 : while( i_nIndex-- )
503 [ # # ]: 0 : ++it;
504 [ # # ][ # # ]: 0 : m_aElements.insert( it, WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) );
[ # # ][ # # ]
[ # # ]
505 : : }
506 : 0 : return nIndex;
507 : : }
508 : :
509 : 0 : size_t RowOrColumn::addChild( boost::shared_ptr<WindowArranger> const & i_pChild, sal_Int32 i_nExpandPrio, size_t i_nIndex )
510 : : {
511 : 0 : size_t nIndex = i_nIndex;
512 [ # # ]: 0 : if( i_nIndex >= m_aElements.size() )
513 : : {
514 : 0 : nIndex = m_aElements.size();
515 [ # # ][ # # ]: 0 : m_aElements.push_back( WindowArranger::Element( NULL, i_pChild, i_nExpandPrio ) );
[ # # ]
516 : : }
517 : : else
518 : : {
519 : 0 : std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
520 [ # # ]: 0 : while( i_nIndex-- )
521 [ # # ]: 0 : ++it;
522 [ # # ][ # # ]: 0 : m_aElements.insert( it, WindowArranger::Element( NULL, i_pChild, i_nExpandPrio ) );
[ # # ]
523 : : }
524 : 0 : return nIndex;
525 : : }
526 : :
527 : : // ----------------------------------------
528 : : // vcl::LabeledElement
529 : : //-----------------------------------------
530 : :
531 [ # # ][ # # ]: 0 : LabeledElement::~LabeledElement()
532 : : {
533 [ # # ]: 0 : m_aLabel.deleteChild();
534 [ # # ]: 0 : m_aElement.deleteChild();
535 [ # # ]: 0 : }
536 : :
537 : 0 : Size LabeledElement::getOptimalSize( WindowSizeType i_eType ) const
538 : : {
539 [ # # ]: 0 : Size aRet( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) );
540 [ # # ]: 0 : if( aRet.Width() != 0 )
541 : : {
542 [ # # ]: 0 : if( m_nLabelColumnWidth != 0 )
543 : 0 : aRet.Width() = m_nLabelColumnWidth;
544 : : else
545 [ # # ]: 0 : aRet.Width() += getBorderValue( m_nDistance );
546 : : }
547 [ # # ]: 0 : Size aElementSize( m_aElement.getOptimalSize( i_eType ) );
548 : 0 : aRet.Width() += aElementSize.Width();
549 [ # # ]: 0 : if( aElementSize.Height() > aRet.Height() )
550 : 0 : aRet.Height() = aElementSize.Height();
551 [ # # ]: 0 : if( aRet.Height() != 0 )
552 [ # # ]: 0 : aRet.Height() += 2 * getBorderValue( m_nOuterBorder );
553 : :
554 : 0 : return aRet;
555 : : }
556 : :
557 : 0 : void LabeledElement::resize()
558 : : {
559 [ # # ]: 0 : Size aLabelSize( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) );
560 [ # # ]: 0 : Size aElementSize( m_aElement.getOptimalSize( WINDOWSIZE_PREFERRED ) );
561 [ # # ]: 0 : long nDistance = getBorderValue( m_nDistance );
562 [ # # ]: 0 : long nOuterBorder = getBorderValue( m_nOuterBorder );
563 [ # # ][ # # ]: 0 : if( nDistance + aLabelSize.Width() + aElementSize.Width() > m_aManagedArea.GetWidth() )
564 [ # # ]: 0 : aElementSize = m_aElement.getOptimalSize( WINDOWSIZE_MINIMUM );
565 : :
566 : : // align label and element vertically in LabeledElement
567 [ # # ]: 0 : long nYOff = (m_aManagedArea.GetHeight() - 2*nOuterBorder - aLabelSize.Height()) / 2;
568 : 0 : Point aPos( m_aManagedArea.Left(),
569 : 0 : m_aManagedArea.Top() + nOuterBorder + nYOff );
570 : 0 : Size aSize( aLabelSize );
571 [ # # ]: 0 : if( m_nLabelColumnWidth != 0 )
572 : 0 : aSize.Width() = m_nLabelColumnWidth;
573 [ # # ]: 0 : m_aLabel.setPosSize( aPos, aSize );
574 : :
575 : 0 : aPos.X() += aSize.Width() + nDistance;
576 [ # # ]: 0 : nYOff = (m_aManagedArea.GetHeight() - 2*nOuterBorder - aElementSize.Height()) / 2;
577 : 0 : aPos.Y() = m_aManagedArea.Top() + nOuterBorder + nYOff;
578 : 0 : aSize.Width() = aElementSize.Width();
579 [ # # ]: 0 : aSize.Height() = m_aManagedArea.GetHeight() - 2*nOuterBorder;
580 : :
581 : : // label style
582 : : // 0: position left and right
583 : : // 1: keep the element close to label and grow it
584 : : // 2: keep the element close and don't grow it
585 [ # # ]: 0 : if( m_nLabelStyle == 0)
586 : : {
587 [ # # ]: 0 : if( aPos.X() + aSize.Width() < m_aManagedArea.Right() )
588 : 0 : aPos.X() = m_aManagedArea.Right() - aSize.Width();
589 : : }
590 [ # # ]: 0 : else if( m_nLabelStyle == 1 )
591 : : {
592 [ # # ]: 0 : if( aPos.X() + aSize.Width() < m_aManagedArea.Right() )
593 : 0 : aSize.Width() = m_aManagedArea.Right() - aPos.X();
594 : : }
595 [ # # ]: 0 : m_aElement.setPosSize( aPos, aSize );
596 : 0 : }
597 : :
598 : 0 : void LabeledElement::setLabel( Window* i_pLabel )
599 : : {
600 : 0 : m_aLabel.m_pElement = i_pLabel;
601 : 0 : m_aLabel.m_pChild.reset();
602 : 0 : }
603 : :
604 : 0 : void LabeledElement::setElement( Window* i_pElement )
605 : : {
606 : 0 : m_aElement.m_pElement = i_pElement;
607 : 0 : m_aElement.m_pChild.reset();
608 : 0 : }
609 : :
610 : 0 : void LabeledElement::setElement( boost::shared_ptr<WindowArranger> const & i_pElement )
611 : : {
612 : 0 : m_aElement.m_pElement = NULL;
613 : 0 : m_aElement.m_pChild = i_pElement;
614 : 0 : }
615 : :
616 : : // ----------------------------------------
617 : : // vcl::LabelColumn
618 : : //-----------------------------------------
619 : 0 : LabelColumn::~LabelColumn()
620 : : {
621 [ # # ]: 0 : }
622 : :
623 : 0 : long LabelColumn::getLabelWidth() const
624 : : {
625 : 0 : long nWidth = 0;
626 : :
627 : 0 : size_t nEle = countElements();
628 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
629 : : {
630 : 0 : const Element* pEle = getConstElement( i );
631 [ # # ][ # # ]: 0 : if( pEle && pEle->m_pChild.get() )
[ # # ]
632 : : {
633 [ # # ]: 0 : const LabeledElement* pLabel = dynamic_cast< const LabeledElement* >(pEle->m_pChild.get());
634 [ # # ]: 0 : if( pLabel )
635 : : {
636 : 0 : Window* pLW = pLabel->getWindow( 0 );
637 [ # # ]: 0 : if( pLW )
638 : : {
639 [ # # ]: 0 : Size aLabSize( pLW->GetOptimalSize( WINDOWSIZE_MINIMUM ) );
640 : 0 : long nLB = 0;
641 [ # # ]: 0 : pLabel->getBorders(0, &nLB);
642 [ # # ]: 0 : aLabSize.Width() += getBorderValue( nLB );
643 [ # # ]: 0 : if( aLabSize.Width() > nWidth )
644 : 0 : nWidth = aLabSize.Width();
645 : : }
646 : : }
647 : : }
648 : : }
649 : 0 : return nWidth + getBorderValue( getBorderWidth() );
650 : : }
651 : :
652 : 0 : Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const
653 : : {
654 : 0 : long nWidth = getLabelWidth();
655 : 0 : long nOuterBorder = getBorderValue( m_nOuterBorder );
656 : 0 : Size aColumnSize;
657 : :
658 : : // every child is a LabeledElement
659 : 0 : size_t nEle = countElements();
660 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
661 : : {
662 : 0 : Size aElementSize;
663 [ # # ]: 0 : const Element* pEle = getConstElement( i );
664 [ # # ][ # # ]: 0 : if( pEle && pEle->m_pChild.get() )
[ # # ]
665 : : {
666 [ # # ]: 0 : const LabeledElement* pLabel = dynamic_cast< const LabeledElement* >(pEle->m_pChild.get());
667 [ # # ]: 0 : if( pLabel ) // we have a label
668 : : {
669 [ # # ]: 0 : aElementSize = pLabel->getLabelSize( WINDOWSIZE_MINIMUM );
670 [ # # ]: 0 : if( aElementSize.Width() )
671 : 0 : aElementSize.Width() = nWidth;
672 [ # # ]: 0 : Size aSize( pLabel->getElementSize( i_eType ) );
673 : 0 : aElementSize.Width() += aSize.Width();
674 [ # # ]: 0 : if( aSize.Height() > aElementSize.Height() )
675 : 0 : aElementSize.Height() = aSize.Height();
676 : : }
677 : : else // a non label, just treat it as a row
678 : : {
679 [ # # ]: 0 : aElementSize = pEle->getOptimalSize( i_eType );
680 : : }
681 : : }
682 [ # # ][ # # ]: 0 : else if( pEle && pEle->m_pElement ) // a general window, treat is as a row
683 : : {
684 [ # # ]: 0 : aElementSize = pEle->getOptimalSize( i_eType );
685 : : }
686 [ # # ]: 0 : if( aElementSize.Width() )
687 : : {
688 : 0 : aElementSize.Width() += 2*nOuterBorder;
689 [ # # ]: 0 : if( aElementSize.Width() > aColumnSize.Width() )
690 : 0 : aColumnSize.Width() = aElementSize.Width();
691 : : }
692 [ # # ]: 0 : if( aElementSize.Height() )
693 : : {
694 [ # # ]: 0 : aColumnSize.Height() += getBorderValue( getBorderWidth() ) + aElementSize.Height();
695 : : }
696 : : }
697 [ # # ][ # # ]: 0 : if( nEle > 0 && aColumnSize.Height() )
[ # # ]
698 : : {
699 : 0 : aColumnSize.Height() -= getBorderValue( getBorderWidth() ); // for the first element
700 : 0 : aColumnSize.Height() += 2*nOuterBorder;
701 : : }
702 : 0 : return aColumnSize;
703 : : }
704 : :
705 : 0 : void LabelColumn::resize()
706 : : {
707 : 0 : long nWidth = getLabelWidth();
708 : 0 : size_t nEle = countElements();
709 [ # # ]: 0 : for( size_t i = 0; i < nEle; i++ )
710 : : {
711 : 0 : Element* pEle = getElement( i );
712 [ # # ][ # # ]: 0 : if( pEle && pEle->m_pChild.get() )
[ # # ]
713 : : {
714 [ # # ]: 0 : LabeledElement* pLabel = dynamic_cast< LabeledElement* >(pEle->m_pChild.get());
715 [ # # ]: 0 : if( pLabel )
716 : 0 : pLabel->setLabelColumnWidth( nWidth );
717 : : }
718 : : }
719 : 0 : RowOrColumn::resize();
720 : 0 : }
721 : :
722 : 0 : size_t LabelColumn::addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> const& i_rElement, long i_nIndent )
723 : : {
724 [ # # ][ # # ]: 0 : boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) );
[ # # ]
725 [ # # ]: 0 : xLabel->setLabel( i_pLabel );
726 [ # # ]: 0 : xLabel->setBorders( 0, i_nIndent, 0, 0, 0 );
727 [ # # ]: 0 : xLabel->setElement( i_rElement );
728 [ # # ][ # # ]: 0 : size_t nIndex = addChild( xLabel );
[ # # ]
729 [ # # ]: 0 : resize();
730 [ # # ]: 0 : return nIndex;
731 : : }
732 : :
733 : 0 : size_t LabelColumn::addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent, const Size& i_rElementMinSize )
734 : : {
735 [ # # ][ # # ]: 0 : boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) );
[ # # ]
736 [ # # ]: 0 : xLabel->setLabel( i_pLabel );
737 [ # # ]: 0 : xLabel->setBorders( 0, i_nIndent, 0, 0, 0 );
738 [ # # ]: 0 : xLabel->setElement( i_pElement );
739 [ # # ]: 0 : xLabel->setMinimumSize( 1, i_rElementMinSize );
740 [ # # ][ # # ]: 0 : size_t nIndex = addChild( xLabel );
[ # # ]
741 [ # # ]: 0 : resize();
742 [ # # ]: 0 : return nIndex;
743 : : }
744 : :
745 : : // ----------------------------------------
746 : : // vcl::Indenter
747 : : //-----------------------------------------
748 : :
749 [ # # ]: 0 : Indenter::~Indenter()
750 : : {
751 [ # # ]: 0 : m_aElement.deleteChild();
752 [ # # ]: 0 : }
753 : :
754 : 0 : Size Indenter::getOptimalSize( WindowSizeType i_eType ) const
755 : : {
756 : 0 : Size aSize( m_aElement.getOptimalSize( i_eType ) );
757 : 0 : long nOuterBorder = getBorderValue( m_nOuterBorder );
758 : 0 : long nIndent = getBorderValue( m_nIndent );
759 : 0 : aSize.Width() += 2*nOuterBorder + nIndent;
760 : 0 : aSize.Height() += 2*nOuterBorder;
761 : 0 : return aSize;
762 : : }
763 : :
764 : 0 : void Indenter::resize()
765 : : {
766 [ # # ]: 0 : long nOuterBorder = getBorderValue( m_nOuterBorder );
767 [ # # ]: 0 : long nIndent = getBorderValue( m_nIndent );
768 : 0 : Point aPt( m_aManagedArea.TopLeft() );
769 : 0 : aPt.X() += nOuterBorder + nIndent;
770 : 0 : aPt.Y() += nOuterBorder;
771 [ # # ]: 0 : Size aSz( m_aManagedArea.GetSize() );
772 : 0 : aSz.Width() -= 2*nOuterBorder + nIndent;
773 : 0 : aSz.Height() -= 2*nOuterBorder;
774 [ # # ]: 0 : m_aElement.setPosSize( aPt, aSz );
775 : 0 : }
776 : :
777 : 0 : void Indenter::setWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio )
778 : : {
779 [ # # ][ # # ]: 0 : OSL_VERIFY( (m_aElement.m_pElement == 0 && m_aElement.m_pChild == 0) || i_pWindow == 0 );
[ # # ]
780 [ # # ][ # # ]: 0 : OSL_VERIFY( i_pWindow == 0 || i_pWindow->GetParent() == m_pParentWindow );
781 : 0 : m_aElement.m_pElement = i_pWindow;
782 : 0 : m_aElement.m_nExpandPriority = i_nExpandPrio;
783 : 0 : }
784 : :
785 : 0 : void Indenter::setChild( boost::shared_ptr<WindowArranger> const & i_pChild, sal_Int32 i_nExpandPrio )
786 : : {
787 [ # # ][ # # ]: 0 : OSL_VERIFY( (m_aElement.m_pElement == 0 && m_aElement.m_pChild == 0 ) || i_pChild == 0 );
[ # # ]
788 : 0 : m_aElement.m_pChild = i_pChild;
789 : 0 : m_aElement.m_nExpandPriority = i_nExpandPrio;
790 : 0 : }
791 : :
792 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|