149 lines
4.6 KiB
C++
149 lines
4.6 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include "timer.hxx"
|
|
|
|
#include <vector>
|
|
#include <list>
|
|
#include <vcl/timer.hxx>
|
|
#include <com/sun/star/awt/XLayoutContainer.hpp>
|
|
|
|
namespace layoutimpl
|
|
{
|
|
using namespace ::com::sun::star;
|
|
|
|
class AllocateTimer : public Timer
|
|
{
|
|
typedef std::list< uno::Reference< awt::XLayoutContainer > > ContainerList;
|
|
ContainerList mxContainers;
|
|
uno::Reference< awt::XLayoutContainer > mxLastAdded;
|
|
|
|
public:
|
|
AllocateTimer()
|
|
{
|
|
// timer set to 0 -- just process it as soon as it gets idle
|
|
SetTimeout( 0 );
|
|
}
|
|
|
|
static inline bool isParentOf( uno::Reference< awt::XLayoutContainer > xParent,
|
|
uno::Reference< awt::XLayoutContainer > xWidget )
|
|
{
|
|
while ( xWidget.is() )
|
|
{
|
|
if ( xWidget == xParent )
|
|
return true;
|
|
xWidget = uno::Reference< awt::XLayoutContainer >( xWidget->getParent(), uno::UNO_QUERY );
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static inline void eraseChildren( ContainerList::iterator &it, ContainerList &list )
|
|
{
|
|
ContainerList::iterator jt = list.begin();
|
|
while ( jt != list.end() )
|
|
{
|
|
if ( it != jt && isParentOf( *it, *jt ) )
|
|
jt = list.erase( jt );
|
|
else
|
|
jt++;
|
|
}
|
|
}
|
|
|
|
static inline bool isContainerDamaged( uno::Reference< awt::XLayoutContainer > xContainer )
|
|
{
|
|
uno::Reference< awt::XLayoutConstrains > xConstrains( xContainer, uno::UNO_QUERY );
|
|
awt::Size lastReq( xContainer->getRequestedSize() );
|
|
awt::Size curReq( xConstrains->getMinimumSize() );
|
|
return lastReq.Width != curReq.Width || lastReq.Height != curReq.Height;
|
|
}
|
|
|
|
void add( const uno::Reference< awt::XLayoutContainer > &xContainer )
|
|
{
|
|
// small optimization
|
|
if ( mxLastAdded == xContainer )
|
|
return;
|
|
mxLastAdded = xContainer;
|
|
|
|
mxContainers.push_back( xContainer );
|
|
}
|
|
|
|
virtual void Timeout()
|
|
{
|
|
mxLastAdded = uno::Reference< awt::XLayoutContainer >();
|
|
|
|
// 1. remove duplications and children
|
|
for ( ContainerList::iterator it = mxContainers.begin();
|
|
it != mxContainers.end(); it++ )
|
|
eraseChildren( it, mxContainers );
|
|
|
|
// 2. check damage extent
|
|
for ( ContainerList::iterator it = mxContainers.begin();
|
|
it != mxContainers.end(); it++ )
|
|
{
|
|
uno::Reference< awt::XLayoutContainer > xContainer = *it;
|
|
while ( xContainer->getParent().is() && isContainerDamaged( xContainer ) )
|
|
{
|
|
xContainer = uno::Reference< awt::XLayoutContainer >(
|
|
xContainer->getParent(), uno::UNO_QUERY );
|
|
}
|
|
|
|
if ( *it != xContainer )
|
|
{
|
|
// 2.2 replace it with parent
|
|
*it = xContainer;
|
|
|
|
// 2.3 remove children of new parent
|
|
eraseChildren( it, mxContainers );
|
|
}
|
|
}
|
|
|
|
// 3. force re-calculations
|
|
for ( ContainerList::iterator it = mxContainers.begin();
|
|
it != mxContainers.end(); it++ )
|
|
(*it)->allocateArea( (*it)->getAllocatedArea() );
|
|
}
|
|
};
|
|
|
|
static void AddResizeTimeout( const uno::Reference< awt::XLayoutContainer > &xCont )
|
|
{
|
|
static AllocateTimer timer;
|
|
timer.add( xCont );
|
|
timer.Start();
|
|
}
|
|
|
|
LayoutUnit::LayoutUnit() : LayoutUnit_Base()
|
|
{
|
|
}
|
|
|
|
void SAL_CALL LayoutUnit::queueResize( const uno::Reference< awt::XLayoutContainer > &xContainer )
|
|
throw( uno::RuntimeException )
|
|
{
|
|
AddResizeTimeout( xContainer );
|
|
}
|
|
|
|
}
|