diff options
Diffstat (limited to 'toolkit/source/layout/core')
35 files changed, 5788 insertions, 0 deletions
diff --git a/toolkit/source/layout/core/bin.cxx b/toolkit/source/layout/core/bin.cxx new file mode 100644 index 000000000000..8a72d88cf2e5 --- /dev/null +++ b/toolkit/source/layout/core/bin.cxx @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "bin.hxx" + +#include <sal/macros.h> + +namespace layoutimpl +{ + +using namespace css; + +/* Bin */ + +Bin::Bin() : Container() +{ +} + +void SAL_CALL +Bin::addChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw (uno::RuntimeException, awt::MaxChildrenException) +{ + if ( mxChild.is() ) + throw awt::MaxChildrenException(); + if ( xChild.is() ) + { + mxChild = xChild; + setChildParent( xChild ); + queueResize(); + } +} + +void SAL_CALL +Bin::removeChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw (uno::RuntimeException) +{ + if ( xChild == mxChild ) + { + mxChild = uno::Reference< awt::XLayoutConstrains >(); + unsetChildParent( xChild ); + queueResize(); + } +} + +uno::Sequence< uno::Reference< awt::XLayoutConstrains > > SAL_CALL +Bin::getChildren() + throw (uno::RuntimeException) +{ + return getSingleChild (mxChild); +} + +void SAL_CALL +Bin::allocateArea( const awt::Rectangle &rArea ) + throw (uno::RuntimeException) +{ + maAllocation = rArea; + if ( mxChild.is() ) + allocateChildAt( mxChild, rArea ); +} + +awt::Size SAL_CALL +Bin::getMinimumSize() + throw(uno::RuntimeException) +{ + if ( mxChild.is() ) + return maRequisition = maChildRequisition = mxChild->getMinimumSize(); + return maRequisition = awt::Size( 0, 0 ); +} + +uno::Reference< beans::XPropertySet > SAL_CALL +Bin::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& ) + throw (uno::RuntimeException) +{ + return uno::Reference< beans::XPropertySet >(); +} + +sal_Bool SAL_CALL +Bin::hasHeightForWidth() + throw(uno::RuntimeException) +{ + uno::Reference< awt::XLayoutContainer > xChildCont( mxChild, uno::UNO_QUERY ); + if ( xChildCont.is() ) + return xChildCont->hasHeightForWidth(); + return false; +} + +sal_Int32 SAL_CALL +Bin::getHeightForWidth( sal_Int32 nWidth ) + throw(uno::RuntimeException) +{ + uno::Reference< awt::XLayoutContainer > xChildCont( mxChild, uno::UNO_QUERY ); + if ( xChildCont.is() ) + return xChildCont->getHeightForWidth( nWidth ); + return maRequisition.Height; +} + +/* Align */ + +Align::Align() : Bin() +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Halign" ), + ::getCppuType( static_cast< const float* >( NULL ) ), + &fHorAlign ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Valign" ), + ::getCppuType( static_cast< const float* >( NULL ) ), + &fVerAlign ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Hfill" ), + ::getCppuType( static_cast< const float* >( NULL ) ), + &fHorFill ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Vfill" ), + ::getCppuType( static_cast< const float* >( NULL ) ), + &fVerFill ); + + fHorAlign = fVerAlign = 0.5; + fHorFill = fVerFill = 0; +} + +void SAL_CALL +Align::allocateArea( const awt::Rectangle &rArea ) + throw (uno::RuntimeException) +{ + maAllocation = rArea; + if ( !mxChild.is() ) + return; + + awt::Rectangle aChildArea; + aChildArea.Width = SAL_MIN( rArea.Width, maChildRequisition.Width ); + aChildArea.Width += (sal_Int32) SAL_MAX( + 0, (rArea.Width - maChildRequisition.Width) * fHorFill ); + aChildArea.Height = SAL_MIN( rArea.Height, maChildRequisition.Height ); + aChildArea.Height += (sal_Int32) SAL_MAX( + 0, (rArea.Height - maChildRequisition.Height) * fVerFill ); + + aChildArea.X = rArea.X + (sal_Int32)( (rArea.Width - aChildArea.Width) * fHorAlign ); + aChildArea.Y = rArea.Y + (sal_Int32)( (rArea.Height - aChildArea.Height) * fVerAlign ); + + allocateChildAt( mxChild, aChildArea ); +} + +bool +Align::emptyVisible () +{ + return true; +} + +/* MinSize */ + +MinSize::MinSize() : Bin() +{ + mnMinWidth = mnMinHeight = 0; + addProp( RTL_CONSTASCII_USTRINGPARAM( "MinWidth" ), + ::getCppuType( static_cast< const long* >( NULL ) ), + &mnMinWidth ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "MinHeight" ), + ::getCppuType( static_cast< const long* >( NULL ) ), + &mnMinHeight ); +} + +bool +MinSize::emptyVisible () +{ + return true; +} + +awt::Size SAL_CALL MinSize::getMinimumSize() + throw(uno::RuntimeException) +{ + Bin::getMinimumSize(); + maRequisition.Width = SAL_MAX( maRequisition.Width, mnMinWidth ); + maRequisition.Height = SAL_MAX( maRequisition.Height, mnMinHeight ); + return maRequisition; +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/bin.hxx b/toolkit/source/layout/core/bin.hxx new file mode 100644 index 000000000000..4e03d56949fd --- /dev/null +++ b/toolkit/source/layout/core/bin.hxx @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +/* A few simple binary containers */ + +#ifndef LAYOUT_CORE_BIN_HXX +#define LAYOUT_CORE_BIN_HXX + +#include <layout/core/container.hxx> + +namespace layoutimpl +{ + +class Bin : public Container +{ +protected: + // Child + css::awt::Size maChildRequisition; + css::uno::Reference< css::awt::XLayoutConstrains > mxChild; + +public: + Bin(); + virtual ~Bin() {} + + // css::awt::XLayoutContainer + virtual void SAL_CALL addChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException, css::awt::MaxChildrenException); + virtual void SAL_CALL removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException); + + virtual css::uno::Sequence< css::uno::Reference + < css::awt::XLayoutConstrains > > SAL_CALL getChildren() + throw (css::uno::RuntimeException); + + virtual void SAL_CALL allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL getChildProperties( + const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL hasHeightForWidth() + throw(css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getHeightForWidth( sal_Int32 nWidth ) + throw(css::uno::RuntimeException); + + // css::awt::XLayoutConstrains + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException); +}; + +// Align gives control over child position on the allocated space. +class Align : public Bin +{ + friend class AlignChildProps; +protected: + // properties + float fHorAlign, fVerAlign; + float fHorFill, fVerFill; + +public: + Align(); + + bool emptyVisible (); + + // css::awt::XLayoutContainer + virtual void SAL_CALL allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException); +}; + +// Makes child request its or a specified size, whatever is larger. +class MinSize : public Bin +{ +protected: + // properties + long mnMinWidth, mnMinHeight; + +public: + MinSize(); + + bool emptyVisible (); + // css::awt::XLayoutContainer + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException); +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_BIN_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/box-base.cxx b/toolkit/source/layout/core/box-base.cxx new file mode 100644 index 000000000000..3fd7939bfff0 --- /dev/null +++ b/toolkit/source/layout/core/box-base.cxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "box.hxx" + +#include <tools/debug.hxx> +#include <sal/macros.h> + +#include <com/sun/star/awt/XWindow2.hpp> + +// fixed point precision for distributing error +#define FIXED_PT 16 + +namespace layoutimpl +{ + +using namespace css; + +Box_Base::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild ) + : mxChild( xChild ) + , mxProps() + , maRequisition() +{ +} + +static bool isVisible( uno::Reference< awt::XLayoutConstrains > xWidget ) +{ + if ( !xWidget.is() ) + { + DBG_ERROR( "FIXME: invalid child !" ); + return true; + } + + uno::Reference< awt::XWindow2 > xWindow( xWidget, uno::UNO_QUERY ); + if ( xWindow.is() && !xWindow->isVisible() ) + return false; + + uno::Reference< awt::XLayoutContainer > xContainer( xWidget, uno::UNO_QUERY ); + if ( xContainer.is() ) + { + uno::Sequence< uno::Reference< awt::XLayoutConstrains > > aChildren + = xContainer->getChildren(); + + if (!aChildren.getLength ()) + if (Container *c = dynamic_cast <Container*> (xWidget.get ())) + return c->emptyVisible (); + + for ( int i = 0; i < aChildren.getLength(); i++ ) + if ( isVisible( aChildren[i] ) ) + return true; + return false; // this would kill flow without workaround above + } + + return true; +} + +bool Box_Base::ChildData::isVisible() +{ + // FIXME: call the 'isVisible' method on it ? + return layoutimpl::isVisible( mxChild ); +} + +void +Box_Base::AddChild (uno::Reference <awt::XLayoutConstrains> const& xChild) +{ + ChildData *pData = createChild (xChild); + maChildren.push_back (pData); + queueResize (); +} + +void SAL_CALL +Box_Base::addChild (uno::Reference <awt::XLayoutConstrains> const& xChild) + throw (uno::RuntimeException, awt::MaxChildrenException) +{ + if (xChild.is ()) + { + AddChild (xChild); + setChildParent (xChild); + } +} + +Box_Base::ChildData* +Box_Base::removeChildData( std::list< ChildData* >& lst, css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) +{ + for ( std::list< ChildData* >::iterator it = lst.begin(); + it != lst.end(); it++ ) + { + if ( (*it)->mxChild == xChild ) + { + ChildData* pRet = *it; + lst.erase( it ); + return pRet; + } + } + return 0; +} + +void SAL_CALL +Box_Base::removeChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw (uno::RuntimeException) +{ + if ( ChildData* p = removeChildData( maChildren, xChild ) ) + { + delete p; + unsetChildParent( xChild ); + queueResize(); + } + else + { + DBG_ERROR( "Box_Base: removeChild: no such child" ); + } +} + +uno::Sequence< uno::Reference < awt::XLayoutConstrains > > SAL_CALL +Box_Base::getChildren() + throw (uno::RuntimeException) +{ + uno::Sequence< uno::Reference< awt::XLayoutConstrains > > children( maChildren.size() ); + unsigned int index = 0; + for ( std::list< ChildData* >::iterator it = maChildren.begin(); + it != maChildren.end(); it++, index++ ) + children[index] = ( *it )->mxChild; + + return children; +} + +uno::Reference< beans::XPropertySet > SAL_CALL +Box_Base::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw (uno::RuntimeException) +{ + + for ( std::list< ChildData * >::iterator it = maChildren.begin(); + it != maChildren.end(); it++) + { + if ( ( *it )->mxChild == xChild ) + { + if ( !( *it )->mxProps.is() ) + { + PropHelper *pProps = createChildProps( *it ); + pProps->setChangeListener( this ); + ( *it )->mxProps = pProps; + } + return (*it)->mxProps; + } + } + return uno::Reference< beans::XPropertySet >(); +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/box-base.hxx b/toolkit/source/layout/core/box-base.hxx new file mode 100644 index 000000000000..faeddf91f8e9 --- /dev/null +++ b/toolkit/source/layout/core/box-base.hxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_BOX_BASE_HXX +#define LAYOUT_CORE_BOX_BASE_HXX + +#include <layout/core/container.hxx> + +#include <list> + +namespace layoutimpl +{ + +class Box_Base : public Container +{ +public: + // Children properties + struct ChildData + { + css::uno::Reference< css::awt::XLayoutConstrains > mxChild; + css::uno::Reference< css::beans::XPropertySet > mxProps; + css::awt::Size maRequisition; + virtual bool isVisible(); + + ChildData( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ); + virtual ~ChildData() { }; + }; + + struct ChildProps: public PropHelper + { + //ChildProps( ChildProps* ); + }; + +protected: + std::list< ChildData* > maChildren; + + + virtual ChildData *createChild( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) = 0; + virtual ChildProps *createChildProps( ChildData* pData ) = 0; + + ChildData *removeChildData( std::list< ChildData *>&, css::uno::Reference< css::awt::XLayoutConstrains > const& Child ); + +public: + void AddChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child); + + // css::awt::XLayoutContainer + virtual void SAL_CALL addChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child) + throw (css::uno::RuntimeException, css::awt::MaxChildrenException); + virtual void SAL_CALL removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException); + + virtual css::uno::Sequence< css::uno::Reference + < css::awt::XLayoutConstrains > > SAL_CALL getChildren() + throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL getChildProperties( + const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException); +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_BOX_BASE HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/box.cxx b/toolkit/source/layout/core/box.cxx new file mode 100644 index 000000000000..180706486477 --- /dev/null +++ b/toolkit/source/layout/core/box.cxx @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "box.hxx" + +#include <tools/debug.hxx> +#include <sal/macros.h> + +// fixed point precision for distributing error +#define FIXED_PT 16 + +namespace layoutimpl +{ + +using namespace css; + +Box::ChildProps::ChildProps( Box::ChildData *pData ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Expand" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &(pData->mbExpand) ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Fill" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &(pData->mbFill) ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Padding" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &(pData->mnPadding) ); +} + +Box::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild ) + : Box_Base::ChildData( xChild ) + , mnPadding( 0 ) + , mbExpand( true ) + , mbFill( true ) +{ +} + +Box::ChildData* +Box::createChild( uno::Reference< awt::XLayoutConstrains > const& xChild ) + { + return new ChildData( xChild ); + } + +Box::ChildProps* +Box::createChildProps( Box_Base::ChildData *pData ) +{ + return new ChildProps( static_cast<Box::ChildData*> ( pData ) ); +} + +Box::Box( bool horizontal ) + : Box_Base() + , mnSpacing( 0 ) + , mbHomogeneous( false ) + , mbHorizontal( horizontal ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Homogeneous" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &mbHomogeneous ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Spacing" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &mnSpacing ); + mbHasFlowChildren = false; +} + +awt::Size +Box::calculateSize( long nWidth ) +{ + int nVisibleChildren = 0; + // primary vs secundary axis (instead of a X and Y) + int nPrimSize = 0; + int nSecSize = 0; + int nFlowMinWidth = 0; // in case the box only has flow children + + mbHasFlowChildren = false; + + for ( std::list<Box_Base::ChildData *>::const_iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Box::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + + uno::Reference< awt::XLayoutContainer > xChildCont( child->mxChild, uno::UNO_QUERY ); + bool bFlow = xChildCont.is() && xChildCont->hasHeightForWidth(); + + awt::Size aChildSize = child->maRequisition = child->mxChild->getMinimumSize(); + + if ( !mbHorizontal /*vertical*/ && bFlow ) + { + if ( nFlowMinWidth == 0 || nFlowMinWidth > aChildSize.Width ) + nFlowMinWidth = aChildSize.Width; + mbHasFlowChildren = true; + } + else + { + int size = primDim( aChildSize ) + child->mnPadding * 2; + if ( mbHomogeneous ) + nPrimSize = SAL_MAX( nPrimSize, size ); + else + nPrimSize += size; + + nSecSize = SAL_MAX( nSecSize, secDim( aChildSize ) ); + } + nVisibleChildren++; + } + + if ( nVisibleChildren ) + { + if ( mbHomogeneous ) + nPrimSize *= nVisibleChildren; + nPrimSize += (nVisibleChildren - 1) * mnSpacing; + } + + if ( mbHasFlowChildren ) + { + if ( nWidth == 0 ) + nWidth = nSecSize ? nSecSize : nFlowMinWidth; + for ( std::list<Box_Base::ChildData *>::const_iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Box::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + + uno::Reference< awt::XLayoutContainer > xChildCont( child->mxChild, uno::UNO_QUERY ); + bool bFlow = xChildCont.is() && xChildCont->hasHeightForWidth(); + + if ( bFlow ) + nPrimSize += xChildCont->getHeightForWidth( nWidth ); + } + } + + nPrimSize += mnBorderWidth * 2; + nSecSize += mnBorderWidth * 2; + return awt::Size( mbHorizontal ? nPrimSize : nSecSize, + mbHorizontal ? nSecSize : nPrimSize ); +} + +awt::Size SAL_CALL +Box::getMinimumSize() throw(uno::RuntimeException) +{ + maRequisition = calculateSize(); + return maRequisition; +} + +sal_Bool SAL_CALL +Box::hasHeightForWidth() + throw(uno::RuntimeException) +{ + return mbHasFlowChildren; +} + +sal_Int32 SAL_CALL +Box::getHeightForWidth( sal_Int32 nWidth ) + throw(uno::RuntimeException) +{ + if ( hasHeightForWidth() ) + return calculateSize( nWidth ).Height; + return maRequisition.Height; +} + +void SAL_CALL +Box::allocateArea( const awt::Rectangle &newArea ) + throw (uno::RuntimeException) +{ + maAllocation = newArea; + int nVisibleChildren = 0, nExpandChildren = 0; + + for ( std::list<Box_Base::ChildData *>::const_iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Box::ChildData*> ( *it ); + if ( child->isVisible() ) + { + nVisibleChildren++; + if ( child->mbExpand ) + nExpandChildren++; + } + } + if ( !nVisibleChildren ) + return; + + // split rectangle for dimension helpers + awt::Point newPoint( newArea.X, newArea.Y ); + awt::Size newSize( newArea.Width, newArea.Height ); + + int nExtraSpace; + if ( mbHomogeneous ) + nExtraSpace = ( ( primDim( newSize ) - mnBorderWidth * 2 - + ( nVisibleChildren - 1 ) * mnSpacing )) / nVisibleChildren; + else if ( nExpandChildren ) + { + int reqSize = primDim( maRequisition ); + if ( !mbHorizontal && hasHeightForWidth() ) + reqSize = getHeightForWidth( newArea.Width ); + nExtraSpace = ( primDim( newSize ) - reqSize ) / nExpandChildren; + } + else + nExtraSpace = 0; + + int nChildPrimPoint, nChildSecPoint, nChildPrimSize, nChildSecSize; + + int nStartPoint = primDim( newPoint ) + mnBorderWidth; + int nBoxSecSize = SAL_MAX( 1, secDim( newSize ) - mnBorderWidth * 2 ); + + for ( std::list<Box_Base::ChildData *>::const_iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Box::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + + awt::Point aChildPos; + int nBoxPrimSize; // of the available box space + + if ( mbHomogeneous ) + nBoxPrimSize = nExtraSpace; + else + { + uno::Reference< awt::XLayoutContainer > xChildCont( child->mxChild, uno::UNO_QUERY ); + bool bFlow = xChildCont.is() && xChildCont->hasHeightForWidth(); + if ( !mbHorizontal && bFlow ) + nBoxPrimSize = xChildCont->getHeightForWidth( newArea.Width ); + else + nBoxPrimSize = primDim( child->maRequisition ); + nBoxPrimSize += child->mnPadding; + if ( child->mbExpand ) + nBoxPrimSize += nExtraSpace; + } + + nChildPrimPoint = nStartPoint + child->mnPadding; + nChildSecPoint = secDim( newPoint ) + mnBorderWidth; + + nChildSecSize = nBoxSecSize; + if ( child->mbFill ) + nChildPrimSize = SAL_MAX( 1, nBoxPrimSize - child->mnPadding); + else + { + nChildPrimSize = primDim( child->maRequisition ); + nChildPrimPoint += (nBoxPrimSize - nChildPrimSize) / 2; + + nChildSecPoint += (nBoxSecSize - nChildSecSize) / 2; + } + + awt::Rectangle area; + area.X = mbHorizontal ? nChildPrimPoint : nChildSecPoint; + area.Y = mbHorizontal ? nChildSecPoint : nChildPrimPoint; + area.Width = mbHorizontal ? nChildPrimSize : nChildSecSize; + area.Height = mbHorizontal ? nChildSecSize : nChildPrimSize; + + allocateChildAt( child->mxChild, area ); + + nStartPoint += nBoxPrimSize + mnSpacing + child->mnPadding; + } +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/box.hxx b/toolkit/source/layout/core/box.hxx new file mode 100644 index 000000000000..936b99ea771e --- /dev/null +++ b/toolkit/source/layout/core/box.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_BOX_HXX +#define LAYOUT_CORE_BOX_HXX + +#include <layout/core/box-base.hxx> + +#include <com/sun/star/awt/Point.hpp> + +namespace layoutimpl +{ + +class Box : public Box_Base +{ +protected: + // Box properties (i.e. affect all children) + sal_Int32 mnSpacing; + sal_Bool mbHomogeneous; + sal_Bool mbHorizontal; // false for Vertical + bool mbHasFlowChildren; + +public: + // Children properties + struct ChildData : public Box_Base::ChildData + { + sal_Int32 mnPadding; + sal_Bool mbExpand; + sal_Bool mbFill; + ChildData( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ); + }; + + struct ChildProps : public Box_Base::ChildProps + { + ChildProps( ChildData *pData ); + }; + +protected: + ChildData *createChild( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ); + ChildProps *createChildProps( Box_Base::ChildData* pData ); + +public: + Box( bool horizontal ); + + virtual void SAL_CALL allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException); + + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasHeightForWidth() + throw(css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getHeightForWidth( sal_Int32 nWidth ) + throw(css::uno::RuntimeException); + + // helper: mix of getMinimumSize() and getHeightForWidth() + css::awt::Size calculateSize( long nWidth = 0 ); + +private: + /* Helpers to deal with the joint Box directions. */ + inline int primDim (const css::awt::Size &size) + { if (mbHorizontal) return size.Width; else return size.Height; } + inline int secDim (const css::awt::Size &size) + { if (mbHorizontal) return size.Height; else return size.Width; } + inline int primDim (const css::awt::Point &point) + { if (mbHorizontal) return point.X; else return point.Y; } + inline int secDim (const css::awt::Point &point) + { if (mbHorizontal) return point.Y; else return point.X; } +}; + +struct VBox : public Box +{ VBox() : Box (false) {} }; + +struct HBox : public Box +{ HBox() : Box (true) {} }; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_BOX_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/byteseq.cxx b/toolkit/source/layout/core/byteseq.cxx new file mode 100644 index 000000000000..4330754cf7be --- /dev/null +++ b/toolkit/source/layout/core/byteseq.cxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <com/sun/star/io/XInputStream.hpp> +#include <osl/file.hxx> +#include <comphelper/oslfile2streamwrap.hxx> + +using osl::File; +using osl::FileBase; +using namespace ::com::sun::star; + +namespace layoutimpl +{ + +uno::Reference< io::XInputStream > getFileAsStream( const rtl::OUString &rName ) +{ + rtl::OUString sFileURL; + if( FileBase::E_None != FileBase::getFileURLFromSystemPath( rName, sFileURL ) ) + sFileURL = rName; // maybe it already was a file url + + File * blobFile = new File(sFileURL); + File::RC errorCode = blobFile->open(OpenFlag_Read); + + uno::Reference<io::XInputStream> xResult; + switch (errorCode) + { + case osl::File::E_None: // got it + xResult.set( new comphelper::OSLInputStreamWrapper(blobFile,true) ); + break; + + case osl::File::E_NOENT: // no file => no stream + delete blobFile; + break; + + default: + delete blobFile; +/* { + rtl::OUStringBuffer sMsg; + sMsg.appendAscii("Cannot open output file \""); + sMsg.append(aURL); + sMsg.appendAscii("\" : "); + sMsg.append(configmgr::FileHelper::createOSLErrorString(errorCode)); + + throw io::IOException(sMsg.makeStringAndClear(),NULL); + } +*/ + } + + return xResult; +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/container.cxx b/toolkit/source/layout/core/container.cxx new file mode 100644 index 000000000000..80f8dfc1b9fa --- /dev/null +++ b/toolkit/source/layout/core/container.cxx @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "container.hxx" + +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <tools/debug.hxx> + +namespace layoutimpl { + +using namespace css; + +Container::Container() + : Container_Base() + , PropHelper() + , mnBorderWidth( 0 ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Border" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &mnBorderWidth ); + setChangeListener( this ); +} + +bool +Container::emptyVisible () +{ + return false; +} + +uno::Any +Container::queryInterface( const uno::Type & rType ) throw (uno::RuntimeException) +{ + uno::Any aRet = Container_Base::queryInterface( rType ); + return aRet.hasValue() ? aRet : PropHelper::queryInterface( rType ); +} + +void +Container::allocateChildAt( const uno::Reference< awt::XLayoutConstrains > &xChild, + const awt::Rectangle &rArea ) + throw( uno::RuntimeException ) +{ + uno::Reference< awt::XLayoutContainer > xCont( xChild, uno::UNO_QUERY ); + if ( xCont.is() ) + xCont->allocateArea( rArea ); + else + { + uno::Reference< awt::XWindow > xWindow( xChild, uno::UNO_QUERY ); + if ( xWindow.is() ) + xWindow->setPosSize( rArea.X, rArea.Y, rArea.Width, rArea.Height, + awt::PosSize::POSSIZE ); + else + { + DBG_ERROR( "Error: non-sizeable child" ); + } + } +} + +uno::Sequence< uno::Reference< awt::XLayoutConstrains > > +Container::getSingleChild ( uno::Reference< awt::XLayoutConstrains >const &xChildOrNil ) +{ + uno::Sequence< uno::Reference< awt::XLayoutConstrains > > aSeq( ( xChildOrNil.is() ? 1 : 0 ) ); + if ( xChildOrNil.is() ) + aSeq[0] = xChildOrNil; + return aSeq; +} + +void +Container::queueResize() +{ + if ( mxLayoutUnit.is() ) + mxLayoutUnit->queueResize( uno::Reference< awt::XLayoutContainer >( this ) ); +} + +void +Container::setChildParent( const uno::Reference< awt::XLayoutConstrains >& xChild ) +{ + uno::Reference< awt::XLayoutContainer > xContChild( xChild, uno::UNO_QUERY ); + if ( xContChild.is() ) + { + xContChild->setParent( uno::Reference< awt::XLayoutContainer >( this ) ); + } +} + +void +Container::unsetChildParent( const uno::Reference< awt::XLayoutConstrains >& xChild ) +{ + uno::Reference< awt::XLayoutContainer > xContChild( xChild, uno::UNO_QUERY ); + if ( xContChild.is() ) + { + xContChild->setParent( uno::Reference< awt::XLayoutContainer >() ); + } +} + +void Container::propertiesChanged() +{ + // cl: why this assertion? This is also called to set properties at the top level widget which has no parent!? + // DBG_ASSERT( mxParent.is(), "Properties listener: error container doesn't have parent" ); + + if ( mxLayoutUnit.is() && mxParent.is() ) + mxLayoutUnit->queueResize( mxParent ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/container.hxx b/toolkit/source/layout/core/container.hxx new file mode 100644 index 000000000000..3c15efaaaeb7 --- /dev/null +++ b/toolkit/source/layout/core/container.hxx @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_CONTAINER_HXX +#define LAYOUT_CORE_CONTAINER_HXX + +#include <layout/core/helper.hxx> + +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/awt/MaxChildrenException.hpp> + +namespace layoutimpl +{ +namespace css = ::com::sun::star; + +typedef ::cppu::WeakImplHelper2< css::awt::XLayoutContainer, + css::awt::XLayoutConstrains > Container_Base; + +class TOOLKIT_DLLPUBLIC Container : public Container_Base, public PropHelper, public PropHelper::Listener +{ + friend class ChildProps; +protected: + // Widget properties + css::uno::Reference< css::awt::XLayoutContainer > mxParent; + css::uno::Reference< css::awt::XLayoutUnit > mxLayoutUnit; + css::awt::Size maRequisition; + css::awt::Rectangle maAllocation; + + // Container properties + sal_Int32 mnBorderWidth; + + // Utilities + void allocateChildAt( const css::uno::Reference< css::awt::XLayoutConstrains > &xChild, + const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException); + static css::uno::Sequence< css::uno::Reference< css::awt::XLayoutConstrains > > + getSingleChild (const css::uno::Reference< css::awt::XLayoutConstrains > &xChildOrNil); + void setChildParent( const css::uno::Reference< css::awt::XLayoutConstrains >& xChild ); + void unsetChildParent( const css::uno::Reference< css::awt::XLayoutConstrains >& xChild ); + + void queueResize(); + void forceRecalc() { allocateArea( maAllocation ); } + +public: + Container(); + virtual ~Container() {} + + virtual bool emptyVisible (); + + // XInterface + virtual void SAL_CALL acquire() throw() { PropHelper::acquire(); } + virtual void SAL_CALL release() throw() { PropHelper::release(); } + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + + // css::awt::XLayoutContainer + virtual void SAL_CALL addChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException, css::awt::MaxChildrenException) = 0; + virtual void SAL_CALL removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException) = 0; + + virtual css::uno::Sequence< css::uno::Reference + < css::awt::XLayoutConstrains > > SAL_CALL getChildren() + throw (css::uno::RuntimeException) = 0; + + virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL getChildProperties( + const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException) = 0; + + virtual void SAL_CALL allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException) = 0; + + void SAL_CALL setLayoutUnit( const css::uno::Reference< css::awt::XLayoutUnit > &xUnit ) + throw(css::uno::RuntimeException) + { mxLayoutUnit = xUnit; } + css::uno::Reference< css::awt::XLayoutUnit > SAL_CALL getLayoutUnit() + throw(css::uno::RuntimeException) + { return mxLayoutUnit; } + + css::awt::Size SAL_CALL getRequestedSize() throw(css::uno::RuntimeException) + { return maRequisition; } + com::sun::star::awt::Rectangle SAL_CALL getAllocatedArea() throw(css::uno::RuntimeException) + { return maAllocation; } + + virtual sal_Bool SAL_CALL hasHeightForWidth() + throw(css::uno::RuntimeException) = 0; + virtual sal_Int32 SAL_CALL getHeightForWidth( sal_Int32 nWidth ) + throw(css::uno::RuntimeException) = 0; + + // css::awt::XLayoutContainer: css::container::XChild + css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() + throw (css::uno::RuntimeException) + { return mxParent; } + void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface > &xParent ) + throw (css::uno::RuntimeException) + { mxParent = css::uno::Reference< css::awt::XLayoutContainer >( xParent, css::uno::UNO_QUERY ); } + + // css::awt::XLayoutConstrains + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException) = 0; + // (not properly implemented in toolkit, ignore it.) + css::awt::Size SAL_CALL getPreferredSize() + throw(css::uno::RuntimeException) { return getMinimumSize(); } // TODO: use this for flow? + css::awt::Size SAL_CALL calcAdjustedSize( const css::awt::Size& rNewSize ) + throw(css::uno::RuntimeException) { return rNewSize; } + +protected: + void propertiesChanged(); +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_CONTAINER_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/dialogbuttonhbox.cxx b/toolkit/source/layout/core/dialogbuttonhbox.cxx new file mode 100644 index 000000000000..a72700779702 --- /dev/null +++ b/toolkit/source/layout/core/dialogbuttonhbox.cxx @@ -0,0 +1,292 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <awt/vclxbutton.hxx> +#include <tools/debug.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <vcl/button.hxx> + +#include "dialogbuttonhbox.hxx" +#include "flow.hxx" +#include "proplist.hxx" + +#if TEST_LAYOUT && !defined( DBG_UTIL ) +#undef DBG_ERROR +#define DBG_ERROR OSL_TRACE +#undef DBG_ERROR1 +#define DBG_ERROR1 OSL_TRACE +#undef DBG_ERROR2 +#define DBG_ERROR2 OSL_TRACE +#endif /* TEST_LAYOUT && !DBG_UTIL */ + +namespace layoutimpl +{ + +using namespace css; + +//FIXME: how to set platform-dependant variables? +DialogButtonHBox::Ordering const DialogButtonHBox::DEFAULT_ORDERING = +#if defined( MACOSX ) + DialogButtonHBox::MACOS; +#elif defined( SAL_W32 ) +DialogButtonHBox::WINDOWS; +#elif defined( ENABLE_KDE ) +DialogButtonHBox::KDE; +#else /* !MACOSX && !SAL_W32 && !ENABLE_KDE */ +DialogButtonHBox::GNOME; +#endif /* !MACOSX && !SAL_W32 && !ENABLE_KDE */ + +DialogButtonHBox::DialogButtonHBox() + : HBox() + , mnOrdering( DEFAULT_ORDERING ) + , mFlow() + , mpAction( 0 ) + , mpAffirmative( 0 ) + , mpAlternate( 0 ) + , mpApply( 0 ) + , mpCancel( 0 ) + , mpFlow( createChild( uno::Reference< awt::XLayoutConstrains > ( &mFlow ) ) ) + , mpHelp( 0 ) + , mpReset( 0 ) +{ + mbHomogeneous = true; +} + +void +DialogButtonHBox::setOrdering( rtl::OUString const& ordering ) +{ + if ( ordering.equalsIgnoreAsciiCaseAscii( "GNOME" ) ) + mnOrdering = GNOME; + else if ( ordering.equalsIgnoreAsciiCaseAscii( "KDE" ) ) + mnOrdering = KDE; + else if ( ordering.equalsIgnoreAsciiCaseAscii( "MacOS" ) ) + mnOrdering = MACOS; + else if ( ordering.equalsIgnoreAsciiCaseAscii( "Windows" ) ) + mnOrdering = WINDOWS; + else + { + DBG_ERROR1( "DialogButtonHBox: no such ordering: %s", OUSTRING_CSTR( ordering ) ); + } +} + +void +DialogButtonHBox::addChild( uno::Reference< awt::XLayoutConstrains > const& xChild ) + throw ( uno::RuntimeException, awt::MaxChildrenException ) +{ + if ( !xChild.is() ) + return; + + ChildData *p = createChild( xChild ); + +#define IS_BUTTON(t) dynamic_cast<VCLX##t##Button *>( xChild.get () ) + + /* Sort Retry as Action */ + if ( !mpAction && IS_BUTTON( Retry ) ) + mpAction = p; + else if ( !mpAffirmative && IS_BUTTON( OK ) ) + mpAffirmative = p; + else if ( !mpAffirmative && IS_BUTTON( Yes ) ) + mpAffirmative = p; + else if ( !mpAlternate && IS_BUTTON( No ) ) + mpAlternate = p; + /* Sort Ignore as Alternate */ + else if ( !mpAlternate && IS_BUTTON( Ignore ) ) + mpAlternate = p; + else if ( !mpApply && IS_BUTTON( Apply ) ) + mpApply = p; + else if ( !mpCancel && IS_BUTTON( Cancel ) ) + mpCancel = p; + /* Let the user overwrite Flow */ + else if ( /* !mpFlow && */ dynamic_cast<Flow *>( xChild.get () ) ) + mpFlow = p; + else if ( !mpHelp && IS_BUTTON( Help ) ) + mpHelp = p; + else if ( !mpReset && IS_BUTTON( Reset ) ) + mpReset = p; + else + maOther.push_back( p ); + orderChildren(); + setChildParent( xChild ); + queueResize(); +} + +void +DialogButtonHBox::orderChildren() +{ + if ( mnOrdering == WINDOWS ) + windowsOrdering(); + else if ( mnOrdering == MACOS ) + macosOrdering(); + else if ( mnOrdering == KDE ) + kdeOrdering(); + else if ( 1 || mnOrdering == GNOME ) + gnomeOrdering(); +} + +void SAL_CALL +DialogButtonHBox::removeChild( uno::Reference< awt::XLayoutConstrains > const& xChild ) + throw ( uno::RuntimeException) +{ + if ( !xChild.is ()) + return; + + Box_Base::ChildData *p = 0; + + if ( mpAction && mpAction->mxChild == xChild ) + p = mpAction; + else if ( mpAffirmative && mpAffirmative->mxChild == xChild ) + p = mpAffirmative; + else if ( mpAlternate && mpAlternate->mxChild == xChild ) + p = mpAlternate; + else if ( mpApply && mpApply->mxChild == xChild ) + p = mpApply; + else if ( mpCancel && mpCancel->mxChild == xChild ) + p = mpCancel; + else if ( mpFlow && mpFlow->mxChild == xChild ) + p = mpFlow; + else if ( mpReset && mpReset->mxChild == xChild ) + p = mpReset; + else if ( mpHelp && mpHelp->mxChild == xChild ) + p = mpHelp; + else + p = removeChildData( maOther, xChild ); + + if ( p ) + { + delete p; + unsetChildParent( xChild ); + orderChildren(); + queueResize(); + } + else + { + DBG_ERROR( "DialogButtonHBox: removeChild: no such child" ); + } +} + +void +DialogButtonHBox::gnomeOrdering() +{ + std::list< Box_Base::ChildData * > ordered; + if ( mpHelp ) + ordered.push_back( mpHelp ); + if ( mpReset ) + ordered.push_back( mpReset ); + if ( mpFlow && ( mpHelp || mpReset ) ) + ordered.push_back( mpFlow ); + ordered.insert( ordered.end(), maOther.begin(), maOther.end() ); + if ( mpAction ) + ordered.push_back( mpAction ); + if ( mpApply ) + ordered.push_back( mpApply ); + if ( mpAlternate ) + ordered.push_back( mpAlternate ); + if ( mpCancel ) + ordered.push_back( mpCancel ); + if ( mpAffirmative ) + ordered.push_back( mpAffirmative ); + maChildren = ordered; +} + +void +DialogButtonHBox::kdeOrdering() +{ + std::list< Box_Base::ChildData * > ordered; + if ( mpHelp ) + ordered.push_back( mpHelp ); + if ( mpReset ) + ordered.push_back( mpReset ); + if ( mpFlow && ( mpHelp || mpReset ) ) + ordered.push_back( mpFlow ); + ordered.insert( ordered.end(), maOther.begin(), maOther.end() ); + if ( mpAction ) + ordered.push_back( mpAction ); + if ( mpAffirmative ) + ordered.push_back( mpAffirmative ); + if ( mpApply ) + ordered.push_back( mpApply ); + if ( mpAlternate ) + ordered.push_back( mpAlternate ); + if ( mpCancel ) + ordered.push_back( mpCancel ); + maChildren = ordered; +} + +void +DialogButtonHBox::macosOrdering() +{ + std::list< Box_Base::ChildData * > ordered; + if ( mpHelp ) + ordered.push_back( mpHelp ); + if ( mpReset ) + ordered.push_back( mpReset ); + if ( mpApply ) + ordered.push_back( mpApply ); + if ( mpAction ) + ordered.push_back( mpAction ); + ordered.insert( ordered.end(), maOther.begin(), maOther.end() ); + if ( mpFlow ) // Always flow? && ( maOther.size () || mpHelp || mpReset || mpAction ) ) + ordered.push_back( mpFlow ); + if ( mpAlternate ) + ordered.push_back( mpAlternate ); + if ( mpFlow && mpAlternate ) + ordered.push_back( mpFlow ); + if ( mpCancel ) + ordered.push_back( mpCancel ); + if ( mpAffirmative ) + ordered.push_back( mpAffirmative ); + maChildren = ordered; +} + +void +DialogButtonHBox::windowsOrdering() +{ + std::list< Box_Base::ChildData * > ordered; + if ( mpReset ) + ordered.push_back( mpReset ); + if ( mpReset && mpFlow ) + ordered.push_back( mpFlow ); + if ( mpAffirmative ) + ordered.push_back( mpAffirmative ); + if ( mpAlternate ) + ordered.push_back( mpAlternate ); + if ( mpAction ) + ordered.push_back( mpAction ); + if ( mpCancel ) + ordered.push_back( mpCancel ); + if ( mpApply ) + ordered.push_back( mpApply ); + ordered.insert( ordered.end(), maOther.begin(), maOther.end() ); + if ( mpHelp ) + ordered.push_back( mpHelp ); + maChildren = ordered; +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/dialogbuttonhbox.hxx b/toolkit/source/layout/core/dialogbuttonhbox.hxx new file mode 100644 index 000000000000..fbeca8691be1 --- /dev/null +++ b/toolkit/source/layout/core/dialogbuttonhbox.hxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_DIALOGBUTTONHBOX_HXX +#define LAYOUT_CORE_DIALOGBUTTONHBOX_HXX + +#include <layout/core/box.hxx> +#include <layout/core/flow.hxx> + +namespace layoutimpl +{ + +class DialogButtonHBox : public HBox +{ +public: + DialogButtonHBox(); + + void setOrdering( rtl::OUString const& ordering ); + void SAL_CALL addChild( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) throw ( css::uno::RuntimeException, css::awt::MaxChildrenException ); + void SAL_CALL removeChild( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) throw ( css::uno::RuntimeException ); + +private: + enum Ordering { PLATFORM, GNOME, KDE, MACOS, WINDOWS }; + + void orderChildren(); + void gnomeOrdering(); + void kdeOrdering(); + void macosOrdering(); + void windowsOrdering(); + + static Ordering const DEFAULT_ORDERING; + Ordering mnOrdering; + Flow mFlow; + + ChildData *mpAction; /* [..]?, [Retry?] */ + ChildData *mpAffirmative; /* OK, Yes, Save */ + ChildData *mpAlternate; /* NO, [Ignore?], Don't save, Quit without saving */ + ChildData *mpApply; /* Deprecated? */ + ChildData *mpCancel; /* Cancel, Close */ + ChildData *mpFlow; + ChildData *mpHelp; + ChildData *mpReset; + + std::list< Box_Base::ChildData *> maOther; +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_DIALOGBUTTONHBOX_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/factory.cxx b/toolkit/source/layout/core/factory.cxx new file mode 100644 index 000000000000..30856e27764c --- /dev/null +++ b/toolkit/source/layout/core/factory.cxx @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "factory.hxx" + +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/InvalidRegistryException.hpp> +#include <cppuhelper/factory.hxx> + +#include "root.hxx" + +using namespace ::com::sun::star; +using namespace layoutimpl; + +void * SAL_CALL comp_Layout_component_getFactory( const char * pImplName, void * pServiceManager, void * /*registryKey*/ ) + { + void * pRet = 0; + + ::rtl::OUString aImplName( ::rtl::OUString::createFromAscii( pImplName ) ); + uno::Reference< lang::XSingleServiceFactory > xFactory; + + if ( pServiceManager && aImplName.equals( LayoutFactory::impl_staticGetImplementationName() ) ) + xFactory = ::cppu::createOneInstanceFactory( reinterpret_cast< lang::XMultiServiceFactory*>( pServiceManager ), + LayoutFactory::impl_staticGetImplementationName(), + LayoutFactory::impl_staticCreateSelfInstance, + LayoutFactory::impl_staticGetSupportedServiceNames() ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; + } + +sal_Bool SAL_CALL comp_Layout_component_writeInfo( void * /*serviceManager*/, void * pRegistryKey ) + { + if ( pRegistryKey ) + { + try + { + uno::Reference< registry::XRegistryKey > xKey( reinterpret_cast< registry::XRegistryKey* >( pRegistryKey ) ); + uno::Reference< registry::XRegistryKey > xNewKey; + + xNewKey = xKey->createKey( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + + LayoutFactory::impl_staticGetImplementationName() + + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) ); + + const uno::Sequence< ::rtl::OUString > aServices = LayoutFactory::impl_staticGetSupportedServiceNames(); + for ( sal_Int32 i = 0; i < aServices.getLength(); i++ ) + xNewKey->createKey( aServices.getConstArray()[i] ); + + return sal_True; + } + catch (registry::InvalidRegistryException &) + { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; + } + +// Component registration +::rtl::OUString SAL_CALL LayoutFactory::impl_staticGetImplementationName() +{ + return ::rtl::OUString::createFromAscii( "com.sun.star.comp.awt.Layout" ); +} + +uno::Sequence< ::rtl::OUString > SAL_CALL LayoutFactory::impl_staticGetSupportedServiceNames() +{ + uno::Sequence< ::rtl::OUString > aRet(2); + aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.awt.Layout"); + aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.awt.Layout"); + return aRet; +} + +uno::Reference< uno::XInterface > SAL_CALL LayoutFactory::impl_staticCreateSelfInstance( + const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) +{ + return uno::Reference< uno::XInterface >( *new LayoutFactory( xServiceManager ) ); +} + +// XServiceInfo +::rtl::OUString SAL_CALL LayoutFactory::getImplementationName() + throw ( uno::RuntimeException ) +{ + return impl_staticGetImplementationName(); +} + +uno::Sequence< ::rtl::OUString > SAL_CALL LayoutFactory::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + return impl_staticGetSupportedServiceNames(); +} + +sal_Bool SAL_CALL LayoutFactory::supportsService( const ::rtl::OUString& ServiceName ) + throw ( uno::RuntimeException ) +{ + uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames(); + for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ ) + if ( ServiceName.compareTo( aSeq[i] ) == 0 ) + return sal_True; + + return sal_False; +} + +// XSingleServiceFactory +uno::Reference< uno::XInterface > SAL_CALL LayoutFactory::createInstance() + throw ( uno::Exception, + uno::RuntimeException ) +{ + return uno::Reference< uno::XInterface >( + static_cast< OWeakObject* >( new LayoutRoot( m_xFactory ) ), + uno::UNO_QUERY ); +} + +uno::Reference< uno::XInterface > SAL_CALL LayoutFactory::createInstanceWithArguments( + const uno::Sequence< uno::Any >& aArguments ) + throw ( uno::Exception, + uno::RuntimeException ) +{ + uno::Reference< uno::XInterface > layout = createInstance(); + uno::Reference< lang::XInitialization > xInit( layout, uno::UNO_QUERY ); + xInit->initialize( aArguments ); + return layout; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/factory.hxx b/toolkit/source/layout/core/factory.hxx new file mode 100644 index 000000000000..7d1f77a9a2df --- /dev/null +++ b/toolkit/source/layout/core/factory.hxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_FACTORY_HXX +#define LAYOUT_CORE_FACTORY_HXX + +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase2.hxx> +#include <toolkit/dllapi.h> + +namespace layoutimpl +{ +class Layout; +} + +class TOOLKIT_DLLPUBLIC LayoutFactory : public ::cppu::WeakImplHelper2< ::com::sun::star::lang::XSingleServiceFactory, + ::com::sun::star::lang::XServiceInfo > +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + +public: + LayoutFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ) + : m_xFactory( xFactory ) + { + OSL_ENSURE( xFactory.is(), "No service manager is provided!\n" ); + } + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + impl_staticGetSupportedServiceNames(); + + static ::rtl::OUString SAL_CALL impl_staticGetImplementationName(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + impl_staticCreateSelfInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ); + + + // XSingleServiceFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException); + +}; + +#endif /* LAYOUT_CORE_FACTORY_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/flow.cxx b/toolkit/source/layout/core/flow.cxx new file mode 100644 index 000000000000..d772f7c450ec --- /dev/null +++ b/toolkit/source/layout/core/flow.cxx @@ -0,0 +1,212 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "flow.hxx" + +#include <sal/macros.h> + +namespace layoutimpl +{ + +using namespace css; + +bool Flow::ChildData::isVisible() +{ + return xChild.is(); +} + +Flow::Flow() + : Container() + , mnSpacing( 0 ) + , mbHomogeneous( false ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Homogeneous" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &mbHomogeneous ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Spacing" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &mnSpacing ); +} + +bool +Flow::emptyVisible () +{ + return true; +} + +void SAL_CALL +Flow::addChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw (uno::RuntimeException, css::awt::MaxChildrenException) +{ + if ( xChild.is() ) + { + ChildData *pData = new ChildData(); + pData->xChild = xChild; + maChildren.push_back( pData ); + + setChildParent( xChild ); + queueResize(); + } +} + +void SAL_CALL +Flow::removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& xChild ) + throw (css::uno::RuntimeException) +{ + for ( std::list< ChildData * >::iterator it = maChildren.begin(); + it != maChildren.end(); it++ ) + { + if ( (*it)->xChild == xChild ) + { + delete *it; + maChildren.erase( it ); + + unsetChildParent( xChild ); + queueResize(); + break; + } + } +} + +css::uno::Sequence< css::uno::Reference < css::awt::XLayoutConstrains > > SAL_CALL +Flow::getChildren() + throw (css::uno::RuntimeException) +{ + uno::Sequence< uno::Reference< awt::XLayoutConstrains > > children( maChildren.size() ); + unsigned int i = 0; + for ( std::list< ChildData * >::iterator it = maChildren.begin(); + it != maChildren.end(); it++, i++ ) + children[i] = (*it)->xChild; + + return children; +} + +uno::Reference< beans::XPropertySet > SAL_CALL +Flow::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& /*xChild*/ ) + throw (uno::RuntimeException) +{ + return uno::Reference< beans::XPropertySet >(); +} + +css::awt::Size +Flow::calculateSize( long nMaxWidth ) +{ + long nNeedHeight = 0; + + std::list<ChildData *>::const_iterator it; + mnEachWidth = 0; + // first pass, for homogeneous property + for (it = maChildren.begin(); it != maChildren.end(); it++) + { + if ( !(*it)->isVisible() ) + continue; + (*it)->aRequisition = (*it)->xChild->getMinimumSize(); + if ( mbHomogeneous ) + mnEachWidth = SAL_MAX( mnEachWidth, (*it)->aRequisition.Width ); + } + + long nRowWidth = 0, nRowHeight = 0; + for (it = maChildren.begin(); it != maChildren.end(); it++) + { + if ( !(*it)->isVisible() ) + continue; + + awt::Size aChildSize = (*it)->aRequisition; + if ( mbHomogeneous ) + aChildSize.Width = mnEachWidth; + + if ( nMaxWidth && nRowWidth > 0 && nRowWidth + aChildSize.Width > nMaxWidth ) + { + nRowWidth = 0; + nNeedHeight += nRowHeight; + nRowHeight = 0; + } + nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); + nRowWidth += aChildSize.Width; + } + nNeedHeight += nRowHeight; + + return awt::Size( nRowWidth, nNeedHeight ); +} + +awt::Size SAL_CALL +Flow::getMinimumSize() throw(uno::RuntimeException) +{ + return maRequisition = calculateSize( 0 ); +} + +sal_Bool SAL_CALL +Flow::hasHeightForWidth() + throw(css::uno::RuntimeException) +{ + return true; +} + +sal_Int32 SAL_CALL +Flow::getHeightForWidth( sal_Int32 nWidth ) + throw(css::uno::RuntimeException) +{ + return calculateSize( nWidth ).Height; +} + +void SAL_CALL +Flow::allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException) +{ + maAllocation = rArea; + + std::list<ChildData *>::const_iterator it; + long nX = 0, nY = 0, nRowHeight = 0; + for (it = maChildren.begin(); it != maChildren.end(); it++) + { + ChildData *child = *it; + if ( !child->isVisible() ) + continue; + + awt::Size aChildSize( child->aRequisition ); + if ( mbHomogeneous ) + aChildSize.Width = mnEachWidth; + + if ( nX > 0 && nX + aChildSize.Width > rArea.Width ) + { + nX = 0; + nY += nRowHeight; + nRowHeight = 0; + } + nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); + + allocateChildAt( child->xChild, + awt::Rectangle( rArea.X + nX, rArea.Y + nY, aChildSize.Width, aChildSize.Height ) ); + + nX += aChildSize.Width; + } +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/flow.hxx b/toolkit/source/layout/core/flow.hxx new file mode 100644 index 000000000000..e6d9677db1bc --- /dev/null +++ b/toolkit/source/layout/core/flow.hxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_FLOW_HXX +#define LAYOUT_CORE_FLOW_HXX + +#include <layout/core/container.hxx> + +#include <list> + +namespace layoutimpl +{ + +class Flow : public Container +{ +protected: + // Box properties (i.e. affect all children) + sal_Int32 mnSpacing; + sal_Bool mbHomogeneous; + +public: + // Children properties + struct ChildData + { + css::awt::Size aRequisition; + css::uno::Reference< css::awt::XLayoutConstrains > xChild; + css::uno::Reference< css::beans::XPropertySet > xProps; + bool isVisible(); + }; + +protected: + std::list< ChildData * > maChildren; + long mnEachWidth; // on homogeneous, the width of every child + +public: + Flow(); + + bool emptyVisible (); + + // css::awt::XLayoutContainer + virtual void SAL_CALL addChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException, css::awt::MaxChildrenException); + virtual void SAL_CALL removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException); + + virtual css::uno::Sequence< css::uno::Reference + < css::awt::XLayoutConstrains > > SAL_CALL getChildren() + throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL getChildProperties( + const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException); + + virtual void SAL_CALL allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException); + + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasHeightForWidth() + throw(css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getHeightForWidth( sal_Int32 nWidth ) + throw(css::uno::RuntimeException); + +private: + // shared between getMinimumSize() and getHeightForWidth() + css::awt::Size calculateSize( long nMaxWidth ); +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_FLOW_CORE_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/helper.cxx b/toolkit/source/layout/core/helper.cxx new file mode 100644 index 000000000000..80013b2e503b --- /dev/null +++ b/toolkit/source/layout/core/helper.cxx @@ -0,0 +1,606 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "helper.hxx" + +#include <assert.h> +#include <list> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/VclWindowPeerAttribute.hpp> +#include <toolkit/awt/vclxwindow.hxx> +#include <tools/debug.hxx> + +#include "proplist.hxx" + +#if TEST_LAYOUT && !defined( DBG_UTIL ) +#undef DBG_ERROR +#define DBG_ERROR OSL_TRACE +#undef DBG_ERROR1 +#define DBG_ERROR1 OSL_TRACE +#undef DBG_ERROR2 +#define DBG_ERROR2 OSL_TRACE +#endif /* TEST_LAYOUT && !DBG_UTIL */ + +namespace layoutimpl +{ +using namespace com::sun::star; +using rtl::OUString; + +uno::Reference< awt::XWindowPeer > +getParent( uno::Reference< uno::XInterface > xRef ) +{ + do + { + uno::Reference< awt::XWindowPeer > xPeer( xRef, uno::UNO_QUERY ); + if ( xPeer.is() ) + return xPeer; + + uno::Reference< awt::XLayoutContainer > xCont( xRef, uno::UNO_QUERY ); + if ( xCont.is() ) + xRef = xCont->getParent(); + } + while ( xRef.is() ); + + return uno::Reference< awt::XWindowPeer >(); +} + +} + +#include "bin.hxx" +#include "box.hxx" +#include "dialogbuttonhbox.hxx" +#include "flow.hxx" +#include "localized-string.hxx" +#include "table.hxx" + +namespace layoutimpl +{ + +oslModule WidgetFactory::mSfx2Library = 0; +WindowCreator WidgetFactory::mSfx2CreateWidget = 0; + +uno::Reference <awt::XLayoutContainer> WidgetFactory::createContainer (OUString const& name) +{ + uno::Reference< awt::XLayoutContainer > xPeer; + + if ( name.equalsAscii( "hbox" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new HBox() ); + else if ( name.equalsAscii( "vbox" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new VBox() ); + else if ( name.equalsAscii( "table" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new Table() ); + else if ( name.equalsAscii( "flow" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new Flow() ); + else if ( name.equalsAscii( "bin" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new Bin() ); + else if ( name.equalsAscii( "min-size" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new MinSize() ); + else if ( name.equalsAscii( "align" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new Align() ); + else if ( name.equalsAscii( "dialogbuttonhbox" ) ) + xPeer = uno::Reference< awt::XLayoutContainer >( new DialogButtonHBox() ); + + return xPeer; +} + +uno::Reference <awt::XLayoutConstrains> WidgetFactory::toolkitCreateWidget (uno::Reference <awt::XToolkit> xToolkit, uno::Reference <uno::XInterface> xParent, OUString const& name, long properties) +{ + uno::Reference< awt::XLayoutConstrains > xPeer; + bool bToplevel = !xParent.is(); + + // UNO Control Widget + awt::WindowDescriptor desc; + if ( bToplevel ) + desc.Type = awt::WindowClass_TOP; + else + { + desc.Type = awt::WindowClass_SIMPLE; + + uno::Reference< awt::XWindowPeer > xWinParent( xParent, uno::UNO_QUERY ); + assert( xParent.is() ); + assert( xWinParent.is() ); + /* + With the new three layer instarr/rpath feature, when + prepending toolkit/unxlngx6.pro/lib or $SOLARVER/lib to + LD_LIBRARY_PATH, VCLXWindow::GetImplementation returns 0x0 + vclxtoolkit::ImplCreateWindow failing to create any widget; + although it succeeds here. + + While developing, one now must copy libtlx.so to + $OOO_INSTALL_PREFIX/openoffice.org/basis3.0/program/libtklx.so + each time. + */ + VCLXWindow* parentComponent = VCLXWindow::GetImplementation( xWinParent ); + if ( !parentComponent ) + throw uno::RuntimeException( + OUString::createFromAscii( "parent has no implementation" ), + uno::Reference< uno::XInterface >() ); + desc.Parent = xWinParent; + } + + desc.ParentIndex = 0; + // debugging help ... + desc.Bounds.X = 0; + desc.Bounds.Y = 0; + desc.Bounds.Width = 300; + desc.Bounds.Height = 200; + + desc.WindowAttributes = properties; + desc.WindowServiceName = name; + + uno::Reference< awt::XWindowPeer > xWinPeer; + try + { + OSL_TRACE("Asking toolkit: %s", OUSTRING_CSTR( desc.WindowServiceName ) ); + xWinPeer = xToolkit->createWindow( desc ); + if ( !xWinPeer.is() ) + throw uno::RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot create peer" ) ), + uno::Reference< uno::XInterface >() ); + xPeer = uno::Reference< awt::XLayoutConstrains >( xWinPeer, uno::UNO_QUERY ); + } + catch( uno::Exception & ) + { + DBG_ERROR1( "Warning: %s is not a recognized type\n", OUSTRING_CSTR( name ) ); + return uno::Reference< awt::XLayoutConstrains >(); + } + + return xPeer; +} + +uno::Reference< awt::XLayoutConstrains > +WidgetFactory::createWidget (uno::Reference< awt::XToolkit > xToolkit, uno::Reference< uno::XInterface > xParent, OUString const& name, long properties) +{ + uno::Reference< awt::XLayoutConstrains > xPeer; + + xPeer = uno::Reference <awt::XLayoutConstrains> (createContainer (name), uno::UNO_QUERY); + if ( xPeer.is() ) + return xPeer; + + xPeer = implCreateWidget (xParent, name, properties); + if (xPeer.is ()) + return xPeer; + +#define FIXED_INFO 1 +#if FIXED_INFO + OUString tName = name; + // FIXME + if ( name.equalsAscii( "fixedinfo" ) ) + tName = OUString::createFromAscii( "fixedtext" ); + xPeer = toolkitCreateWidget (xToolkit, xParent, tName, properties); +#else + xPeer = toolkitCreateWidget (xToolkit, xParent, name, properties); +#endif + + return xPeer; +} + +PropHelper::PropHelper() : LockHelper() + , cppu::OPropertySetHelper( maBrdcstHelper ) + , pHelper( NULL ) +{ +} + +void +PropHelper::addProp (const char *pName, sal_Int32 nNameLen, rtl_TextEncoding e, + uno::Type aType, void *pPtr) +{ + // this sucks rocks for effiency ... + PropDetails aDetails; + aDetails.aName = rtl::OUString::intern( pName, nNameLen, e ); + aDetails.aType = aType; + aDetails.pValue = pPtr; + maDetails.push_back( aDetails ); +} + +cppu::IPropertyArrayHelper & SAL_CALL +PropHelper::getInfoHelper() +{ + if ( ! pHelper ) + { + uno::Sequence< beans::Property > aProps( maDetails.size() ); + for ( unsigned int i = 0; i < maDetails.size(); i++) + { + aProps[i].Name = maDetails[i].aName; + aProps[i].Type = maDetails[i].aType; + aProps[i].Handle = i; + aProps[i].Attributes = 0; + } + pHelper = new cppu::OPropertyArrayHelper( aProps, false /* fixme: faster ? */ ); + + } + return *pHelper; +} + +sal_Bool SAL_CALL +PropHelper::convertFastPropertyValue( + uno::Any & rConvertedValue, + uno::Any & rOldValue, + sal_Int32 nHandle, + const uno::Any& rValue ) + throw (lang::IllegalArgumentException) +{ + OSL_ASSERT( nHandle >= 0 && nHandle < (sal_Int32) maDetails.size() ); + + // FIXME: no Any::getValue ... + getFastPropertyValue( rOldValue, nHandle ); + if ( rOldValue != rValue ) + { + rConvertedValue = rValue; + return sal_True; // changed + } + else + { + rConvertedValue.clear(); + rOldValue.clear(); + } + return sal_False; +} + + +void SAL_CALL +PropHelper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, + const uno::Any& rValue ) + throw (uno::Exception) +{ + OSL_ASSERT( nHandle >= 0 && nHandle < (sal_Int32) maDetails.size() ); + + const PropDetails &rInfo = maDetails[ nHandle ]; + + uno_type_assignData( rInfo.pValue, rInfo.aType.getTypeLibType(), + rValue.pData, rValue.pType, + 0, 0, 0 ); + + if ( mpListener ) + mpListener->propertiesChanged(); +} + +void SAL_CALL +PropHelper::getFastPropertyValue( uno::Any& rValue, + sal_Int32 nHandle ) const +{ + OSL_ASSERT( nHandle >= 0 && nHandle < (sal_Int32) maDetails.size() ); + const PropDetails &rInfo = maDetails[ nHandle ]; + rValue.setValue( rInfo.pValue, rInfo.aType ); +} + +::com::sun::star::uno::Any +PropHelper::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + return OPropertySetHelper::queryInterface( rType ); +} + +uno::Reference <beans::XPropertySetInfo> SAL_CALL PropHelper::getPropertySetInfo () throw (uno::RuntimeException) +{ + return css::uno::Reference <css::beans::XPropertySetInfo> (createPropertySetInfo (getInfoHelper ())); +} + +} // namespace layoutimpl + +#include <awt/vclxbutton.hxx> +#include <awt/vclxdialog.hxx> +#include <awt/vclxfixedline.hxx> +#include <awt/vclxplugin.hxx> +#include <awt/vclxscroller.hxx> +#include <awt/vclxsplitter.hxx> +#include <awt/vclxtabcontrol.hxx> +#include <awt/vclxtabpage.hxx> +#include <toolkit/awt/vclxtoolkit.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <vcl/button.hxx> +#include <vcl/dialog.hxx> +#include <vcl/fixed.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/unohelp.hxx> + +#include <layout/layout.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <vcl/lstbox.hxx> +#include <vcl.hxx> + +#include <typeinfo> + +namespace layoutimpl +{ + +uno::Reference <awt::XLayoutConstrains> WidgetFactory::implCreateWidget (uno::Reference <uno::XInterface> xParent, OUString name, long attributes) +{ + Window* parent = 0; + + if (VCLXWindow* parentComponent = VCLXWindow::GetImplementation (xParent)) + parent = parentComponent->GetWindow (); + + VCLXWindow* component = 0; + Window* window = 0; //sfx2CreateWindow (&component, parent, name, attributes); + if (!window) + window = layoutCreateWindow (&component, parent, name, attributes); + + uno::Reference <awt::XLayoutConstrains> reference; + if (window) + { + window->SetCreatedWithToolkit( sal_True ); + if ( component ) + component->SetCreatedWithToolkit( true ); + reference = component; + window->SetComponentInterface( component ); + if ( attributes & awt::WindowAttribute::SHOW ) + window->Show(); + } + + return reference; +} + +extern "C" { static void SAL_CALL thisModule() {} } + +Window* WidgetFactory::sfx2CreateWindow (VCLXWindow** component, Window* parent, OUString const& name, long& attributes) +{ + OSL_TRACE("Asking sfx2: %s", OUSTRING_CSTR (name)); + + if (!mSfx2Library) + { + OUString libraryName = ::vcl::unohelper::CreateLibraryName ("sfx", TRUE); + mSfx2Library = osl_loadModuleRelative (&thisModule, libraryName.pData, SAL_LOADMODULE_DEFAULT); + if (mSfx2Library) + { + OUString functionName (RTL_CONSTASCII_USTRINGPARAM ("CreateWindow")); + mSfx2CreateWidget = (WindowCreator) osl_getFunctionSymbol (mSfx2Library, functionName.pData); + } + } + + if (mSfx2CreateWidget) + return mSfx2CreateWidget (component, name, parent, attributes); + + return 0; +} + +Window* WidgetFactory::layoutCreateWindow (VCLXWindow** component, Window *parent, OUString const& name, long& attributes) +{ + Window* window = 0; + + if (0) + { + ; + } + if ( name.equalsAscii( "dialog" ) ) + { + if ( parent == NULL ) + parent = DIALOG_NO_PARENT; + window = new Dialog( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXDialog(); + + attributes ^= awt::WindowAttribute::SHOW; + } + else if ( name.equalsAscii( "modaldialog" ) ) + { + if ( parent == NULL ) + parent = DIALOG_NO_PARENT; + window = new ModalDialog( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXDialog(); + + attributes ^= awt::WindowAttribute::SHOW; + } + else if ( name.equalsAscii( "modelessdialog" ) ) + { + if ( parent == NULL ) + parent = DIALOG_NO_PARENT; + window = new ModelessDialog (parent, ImplGetWinBits (attributes, 0)); + *component = new layoutimpl::VCLXDialog(); + + attributes ^= awt::WindowAttribute::SHOW; + } + else if ( name.equalsAscii( "sfxdialog" ) ) + { + if ( parent == NULL ) + parent = DIALOG_NO_PARENT; + window = new ClosingDialog (parent, ImplGetWinBits (attributes, 0)); + *component = new layoutimpl::VCLXDialog(); + + attributes ^= awt::WindowAttribute::SHOW; + } + else if ( name.equalsAscii( "sfxmodaldialog" ) ) + { + if ( parent == NULL ) + parent = DIALOG_NO_PARENT; + window = new ClosingModalDialog( parent, + ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXDialog(); + + attributes ^= awt::WindowAttribute::SHOW; + } + else if ( name.equalsAscii( "sfxmodelessdialog" ) ) + { + if ( parent == NULL ) + parent = DIALOG_NO_PARENT; + window = new ClosingModelessDialog (parent, ImplGetWinBits (attributes, 0)); + *component = new layoutimpl::VCLXDialog(); + + attributes ^= awt::WindowAttribute::SHOW; + } + else if ( name.equalsAscii( "tabcontrol" ) ) + { + window = new TabControl( parent, ImplGetWinBits( attributes, WINDOW_TABCONTROL ) ); + *component = new layoutimpl::VCLXTabControl(); + } + else if ( name.equalsAscii( "scroller" ) ) + { + // used FixedImage because I just want some empty non-intrusive widget + window = new FixedImage( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXScroller(); + } + else if ( name.equalsAscii( "hsplitter" ) || name.equalsAscii( "vsplitter" ) ) + { + window = new FixedImage( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXSplitter( name.equalsAscii( "hsplitter" ) ); + } + else if ( name.equalsAscii( "hfixedline" ) || name.equalsAscii( "vfixedline" ) ) + { + WinBits nStyle = ImplGetWinBits( attributes, 0 ); + nStyle ^= WB_HORZ; + if ( name.equalsAscii( "hfixedline" ) ) + nStyle |= WB_HORZ; + else + nStyle |= WB_VERT; + window = new FixedLine( parent, nStyle ); + *component = new layoutimpl::VCLXFixedLine(); + } + else if ( name.equalsAscii( "okbutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXOKButton( window ); + window->SetType (WINDOW_OKBUTTON); + } + else if ( name.equalsAscii( "cancelbutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXCancelButton( window ); + window->SetType (WINDOW_CANCELBUTTON); + } + else if ( name.equalsAscii( "yesbutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXYesButton( window ); + window->SetType (WINDOW_OKBUTTON); + } + else if ( name.equalsAscii( "nobutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + window->SetType (WINDOW_CANCELBUTTON); + *component = new layoutimpl::VCLXNoButton( window ); + } + else if ( name.equalsAscii( "retrybutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXRetryButton( window ); + } + else if ( name.equalsAscii( "ignorebutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXIgnoreButton( window ); + } + else if ( name.equalsAscii( "resetbutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXResetButton( window ); + } + else if ( name.equalsAscii( "applybutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXApplyButton( window ); + } + else if ( name.equalsAscii( "helpbutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXHelpButton( window ); + window->SetType (WINDOW_HELPBUTTON); + } + else if ( name.equalsAscii( "morebutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXMoreButton( window ); + window->SetType (WINDOW_MOREBUTTON); + } + else if ( name.equalsAscii( "advancedbutton" ) ) + { + window = new PushButton( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::VCLXAdvancedButton( window ); + } + else if ( name.equalsAscii( "plugin" ) ) + { + window = new Control( parent, ImplGetWinBits( attributes, 0 ) ); +#ifndef __SUNPRO_CC + OSL_TRACE( "%s: parent=%p (%s)\n", __FUNCTION__, parent, typeid( *parent ).name() ); +#endif + *component = new layoutimpl::VCLXPlugin( window, ImplGetWinBits( attributes, 0 ) ); + } + else if ( name.equalsAscii( "tabpage" ) ) + { + if (layout::TabPage::global_parent) + parent = layout::TabPage::global_parent; + layout::TabPage::global_parent = 0; + //window = new TabPage( parent, ImplGetWinBits( attributes, 0 ) ); + attributes ^= awt::WindowAttribute::SHOW; + WinBits nStyle = ImplGetWinBits( attributes, 0 ); + nStyle |= WB_HIDE; + + if (!parent) + { + window = new Dialog( parent, nStyle ); + *component = new VCLXDialog(); + } + else + { + window = new TabPage( parent, nStyle ); + *component = new VCLXTabPage( window ); + } + } + else if ( name.equalsAscii( "string" ) ) + { + // FIXME: move <string>s.text to simple map<string> in root? + attributes &= ~awt::WindowAttribute::SHOW; + window = new Window( parent, ImplGetWinBits( attributes, 0 ) ); + *component = new layoutimpl::LocalizedString(); + } + else if (name.equalsAscii ("svxfontlistbox") + || name.equalsAscii ("svxlanguagebox")) + { + window = new ListBox (parent, ImplGetWinBits (attributes, 0)); + *component = new VCLXListBox (); + } + return window; +} + +} // namespace layoutimpl + +// Avoid polluting the rest of the code with vcl linkage pieces ... + +#include <vcl/imagerepository.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/graph.hxx> + +namespace layoutimpl +{ + +uno::Reference< graphic::XGraphic > loadGraphic( const char *pName ) +{ + BitmapEx aBmp; + + OUString aStr( pName, strlen( pName ), RTL_TEXTENCODING_ASCII_US ); + if ( aStr.compareToAscii( ".uno:" ) == 0 ) + aStr = aStr.copy( 5 ).toAsciiLowerCase(); + + if ( !vcl::ImageRepository::loadImage( OUString::createFromAscii( pName ), aBmp, true ) ) + return uno::Reference< graphic::XGraphic >(); + + return Graphic( aBmp ).GetXGraphic(); +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/helper.hxx b/toolkit/source/layout/core/helper.hxx new file mode 100644 index 000000000000..f19f74611ff5 --- /dev/null +++ b/toolkit/source/layout/core/helper.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_HELPER_HXX +#define LAYOUT_CORE_HELPER_HXX + +#include <toolkit/dllapi.h> +#include <vector> + +#include <com/sun/star/awt/XLayoutConstrains.hpp> +#include <com/sun/star/awt/XLayoutContainer.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/xml/input/XRoot.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/propshlp.hxx> +#include <osl/module.h> +#include <rtl/ustring.hxx> + +class Window; +class VCLXWindow; +extern "C" +{ + typedef Window* (SAL_CALL *WindowCreator) (VCLXWindow** component, rtl::OUString const& name, Window* parent, long& attributes); +} + +namespace layoutimpl +{ + +namespace css = ::com::sun::star; + +/* ChildProps -- a helper to set child properties for the XLayoutContainer interface. */ + +class LockHelper +{ +public: + osl::Mutex maGuard; + cppu::OBroadcastHelper maBrdcstHelper; + LockHelper() : maBrdcstHelper( maGuard ) + { + } +}; + +class PropHelper : public LockHelper + , public cppu::OPropertySetHelper + , public cppu::OWeakObject +{ + cppu::OPropertyArrayHelper *pHelper; + + struct PropDetails + { + rtl::OUString aName; + css::uno::Type aType; + void *pValue; + }; + std::vector< PropDetails > maDetails; + +protected: + void addProp( char const *pName, sal_Int32 nNameLen, rtl_TextEncoding e, + css::uno::Type aType, void *pPtr ); + +public: + PropHelper(); + + // com::sun::star::uno::XInterface + void SAL_CALL acquire() throw() { OWeakObject::acquire(); } + void SAL_CALL release() throw() { OWeakObject::release(); } + ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + + // cppu::OPropertySetHelper + virtual cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper(); + virtual sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any &, + css::uno::Any &, sal_Int32 nHandle, const css::uno::Any & ) + throw(css::lang::IllegalArgumentException); + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, + const css::uno::Any& rValue ) throw (css::uno::Exception); + using OPropertySetHelper::getFastPropertyValue; + virtual void SAL_CALL getFastPropertyValue( css::uno::Any& rValue, + sal_Int32 nHandle ) const; + + virtual css::uno::Reference <css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo () throw (css::uno::RuntimeException); + + struct Listener + { + virtual void propertiesChanged() = 0; + }; + + void setChangeListener( Listener *pListener ) + { + mpListener = pListener; + } + +protected: + Listener *mpListener; +}; + +css::uno::Any anyFromString (const rtl::OUString &value, const css::uno::Type &type); + +// The native widgets wrapper hierarchy may not reflect that of the layout +// hierarchy as some containers don't have an associated native widget. +// Use this function to get the native parent of the given peer. +css::uno::Reference< css::awt::XWindowPeer > +getParent( css::uno::Reference< css::uno::XInterface > xPeer ); + +class TOOLKIT_DLLPUBLIC WidgetFactory +{ +public: + static oslModule mSfx2Library; + static WindowCreator mSfx2CreateWidget; + + // Should use UNO services in due course + static css::uno::Reference <css::awt::XLayoutConstrains> toolkitCreateWidget (css::uno::Reference <css::awt::XToolkit> xToolkit, css::uno::Reference <css::uno::XInterface> xParent, rtl::OUString const& name, long properties); + static css::uno::Reference< css::awt::XLayoutConstrains > createWidget( css::uno::Reference <css::awt::XToolkit > xToolkit, css::uno::Reference< css::uno::XInterface > xParent, rtl::OUString const &name, long properties); + static css::uno::Reference <css::awt::XLayoutContainer> createContainer (rtl::OUString const& name); + static css::uno::Reference <css::awt::XLayoutConstrains> implCreateWidget (css::uno::Reference <css::uno::XInterface> xParent, rtl::OUString name, long attributes); + static Window* sfx2CreateWindow (VCLXWindow** component, Window* parent, rtl::OUString const& name, long& attributes); + static Window* layoutCreateWindow (VCLXWindow** component, Window *parent, rtl::OUString const& name, long& attributes); +}; + + +css::uno::Reference< css::graphic::XGraphic > loadGraphic( const char *pName ); + +} // end namespace layoutimpl + +#endif /* LAYOUT_CORE_HELPER_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/import.cxx b/toolkit/source/layout/core/import.cxx new file mode 100644 index 000000000000..b4c03918c492 --- /dev/null +++ b/toolkit/source/layout/core/import.cxx @@ -0,0 +1,328 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "import.hxx" + +#include <com/sun/star/awt/XButton.hpp> +#include <com/sun/star/awt/XDialog2.hpp> +#include <vcl/image.hxx> +#include <tools/debug.hxx> +#include <layout/layout.hxx> + +#include "root.hxx" +#include "helper.hxx" +#include "dialogbuttonhbox.hxx" + + +#define XMLNS_LAYOUT_URI "http://openoffice.org/2007/layout" +#define XMLNS_CONTAINER_URI "http://openoffice.org/2007/layout/container" + +namespace layoutimpl +{ +using namespace css; + +using ::rtl::OUString; + +ElementBase::~ElementBase() +SAL_THROW( () ) +{ + //delete mpImport; + //mpImport = 0; +} + +//** parser +WidgetElement::WidgetElement ( sal_Int32 nUid, const OUString &rName, + uno::Reference <xml::input::XAttributes> const &attributes, + ElementBase *pParent, + ImportContext *pImport) +SAL_THROW (()) +: ElementBase( nUid, rName, attributes, pParent, pImport ) +{ + OUString name = rName.toAsciiLowerCase(); + + PropList aProps; + propsFromAttributes( attributes, aProps, pImport->XMLNS_LAYOUT_UID ); + + OUString aId; + findAndRemove( "id", aProps, aId ); + OUString aLang; + findAndRemove( "xml-lang", aProps, aLang ); + + { +//DEBUG + uno::Reference< awt::XLayoutConstrains > xParent; + if ( pParent ) + xParent = ((WidgetElement *) pParent)->mpWidget->getPeer(); + + + mpWidget = pImport->mrRoot.create( aId, name, + getAttributeProps( aProps ), uno::Reference< awt::XLayoutContainer >( xParent, uno::UNO_QUERY ) ); + + } + + // TODO: handle with non-existing widgets + + mpWidget->setProperties( aProps ); + + uno::Reference< awt::XDialog2 > xDialog( mpWidget->getPeer(), uno::UNO_QUERY ); + if ( xDialog.is() ) + { + OUString aTitle; + if ( findAndRemove( "title", aProps, aTitle ) ) + { + OSL_TRACE("Setting title: %s", OUSTRING_CSTR( aTitle ) ); + xDialog->setTitle( aTitle ); + } + OUString aHelpId; + if ( findAndRemove( "help-id", aProps, aHelpId ) ) + { + OSL_TRACE("Setting help-id: %s", OUSTRING_CSTR( aHelpId ) ); + xDialog->setHelpId( aHelpId.toInt32 () ); + } + } // DEBUG: + else if ( pParent == NULL ) + { + DBG_ERROR( "Fatal error: top node isn't a dialog" ); + } + + OUString aOrdering; + if ( findAndRemove( "ordering", aProps, aOrdering ) ) + if ( DialogButtonHBox *b = dynamic_cast<DialogButtonHBox *> ( mpWidget->getPeer().get() ) ) + b->setOrdering ( aOrdering ); + + bool bSetRadioGroup; + OUString aRadioGroup; + bSetRadioGroup = findAndRemove( "radiogroup", aProps, aRadioGroup ); + + mpWidget->setProperties( aProps ); + + // we need to add radio buttons to the group after their properties are + // set, so we can check if they should be the one selected by default or not. + // And the state changed event isn't fired when changing properties. + + uno::Reference< awt::XRadioButton > xRadio( mpWidget->getPeer(), uno::UNO_QUERY ); + if ( xRadio.is() ) + { + if (!bSetRadioGroup) + aRadioGroup = OUString::createFromAscii ("default"); + pImport->mxRadioGroups.addItem( aRadioGroup, xRadio ); + } +} + +WidgetElement::~WidgetElement() +{ + //delete mpWidget; + //mpWidget = 0; +} + +uno::Reference <xml::input::XElement> +WidgetElement::startChildElement ( sal_Int32 nUid, OUString const &name, + uno::Reference <xml::input::XAttributes> const &attributes ) + throw( xml::sax::SAXException, uno::RuntimeException ) +{ + // Adding a child to the widget + WidgetElement *pChild = new WidgetElement ( nUid, name, attributes, this, mpImport ); + + if ( !mpWidget->addChild( pChild->mpWidget ) ) + { + DBG_ERROR2( "ERROR: cannot add %s to container %s, container full", OUSTRING_CSTR( name ), OUSTRING_CSTR( getLocalName() ) ); + throw xml::sax::SAXException(); + } + + PropList aProps; + propsFromAttributes( attributes, aProps, mpImport->XMLNS_CONTAINER_UID ); + mpWidget->setChildProperties( pChild->mpWidget, aProps ); + + return pChild; +} + +// Support Ivo Hinkelmann's move label/text/title attribute to CONTENT +// transex3 hack. +void SAL_CALL +WidgetElement::characters( OUString const& rChars ) + throw (xml::sax::SAXException, uno::RuntimeException) +{ + if ( mpWidget && rChars.trim().getLength() ) + { + uno::Reference< awt::XDialog2 > xDialog( mpWidget->getPeer(), uno::UNO_QUERY ); + uno::Reference< awt::XButton > xButton( mpWidget->getPeer(), uno::UNO_QUERY ); + if ( xDialog.is() ) + xDialog->setTitle( rChars ); + else if ( xButton.is() ) + mpWidget->setProperty( OUString::createFromAscii( "label" ), rChars ); + else + mpWidget->setProperty( OUString::createFromAscii( "text" ), rChars ); + } +} +// ---- ElementBase ---- + +ElementBase::ElementBase( sal_Int32 nUid, OUString const & rLocalName, + uno::Reference< xml::input::XAttributes > const & xAttributes, + ElementBase* pParent, + ImportContext* pImport ) +SAL_THROW(()) +: mpImport( pImport ) + , mpParent( pParent ) + , mnUid( nUid ) + , maLocalName( rLocalName ) + , mxAttributes( xAttributes ) +{ +} + +// ---- ImportContext ---- + +void ImportContext::startDocument( + uno::Reference< xml::input::XNamespaceMapping > const & xNamespaceMapping ) + throw (xml::sax::SAXException, uno::RuntimeException) +{ + XMLNS_LAYOUT_UID = xNamespaceMapping->getUidByUri( + OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_LAYOUT_URI ) ) ); + XMLNS_CONTAINER_UID = xNamespaceMapping->getUidByUri( + OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_CONTAINER_URI ) ) ); +} + +ToplevelElement::ToplevelElement (OUString const &rName, + uno::Reference <xml::input::XAttributes> const &xAttributes, + ImportContext *pImport) +SAL_THROW(()) +: WidgetElement( 0, rName, xAttributes, NULL, pImport ) +{ +} + +ToplevelElement::~ToplevelElement() +{ +} + +uno::Reference< xml::input::XElement > ImportContext::startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + uno::Reference< xml::input::XAttributes > const & xAttributes ) + throw (xml::sax::SAXException, uno::RuntimeException) +{ + if ( XMLNS_LAYOUT_UID != nUid ) + throw xml::sax::SAXException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "invalid namespace!" ) ), + uno::Reference< uno::XInterface >(), uno::Any() ); + return new ToplevelElement( rLocalName, xAttributes, this ); +} + +RadioGroups::RadioGroups() +{ +} + +void RadioGroups::addItem( rtl::OUString id, uno::Reference< awt::XRadioButton > xRadio ) + throw (uno::RuntimeException) +{ + if ( ! xRadio.is() ) + throw uno::RuntimeException(); + + uno::Reference< RadioGroup > group; + RadioGroupsMap::iterator it = mxRadioGroups.find( id ); + if ( it == mxRadioGroups.end() ) + { + group = uno::Reference< RadioGroup > ( new RadioGroup() ); + mxRadioGroups [id] = group; + } + else + group = it->second; + group->addItem( xRadio ); +} + +RadioGroups::RadioGroup::RadioGroup() +{ +} + +void RadioGroups::RadioGroup::addItem( uno::Reference< awt::XRadioButton > xRadio ) +{ + if ( ! mxSelectedRadio.is() ) + { + xRadio->setState( true ); + mxSelectedRadio = xRadio; + } + else if ( xRadio->getState() ) + { +#if 1 + xRadio->setState( false ); +#else // huh, why select last added? + mxSelectedRadio->setState( false ); + mxSelectedRadio = xRadio; +#endif + } + + // TOO late: actionPerformed is called before itemStateChanged. + // If client code (wrongly?) uses actionPerformed, it will see + // the previous RadioButtons' state. + xRadio->addItemListener( this ); + + uno::Reference< awt::XButton > xButton = uno::Reference< awt::XButton > ( xRadio, uno::UNO_QUERY ); + xButton->addActionListener( this ); + + mxRadios.push_back (xRadio); +} + +void RadioGroups::RadioGroup::handleSelected () + throw (uno::RuntimeException) +{ + for ( RadioButtonsList::iterator it = mxRadios.begin(); + it != mxRadios.end(); it++ ) + if ( *it != mxSelectedRadio && (*it)->getState() ) + { + mxSelectedRadio->setState( false ); + mxSelectedRadio = *it; + break; + } +} + +// awt::XItemListener +void RadioGroups::RadioGroup::itemStateChanged( const awt::ItemEvent& e ) + throw (uno::RuntimeException) +{ + // TOO late: actionPerformed is called before itemStateChanged. + // If client code (wrongly?) uses actionPerformed, it will see + // the previous RadioButtons' state. + + // Need this for initialization, though. + if ( e.Selected ) + handleSelected (); +} + +// awt::XActionListener +void RadioGroups::RadioGroup::actionPerformed( const awt::ActionEvent& ) + throw (uno::RuntimeException) +{ + handleSelected (); +} + +// lang::XEventListener +void SAL_CALL RadioGroups::RadioGroup::disposing( const lang::EventObject& ) + throw (uno::RuntimeException) +{ +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/import.hxx b/toolkit/source/layout/core/import.hxx new file mode 100644 index 000000000000..8c9a6c5e3753 --- /dev/null +++ b/toolkit/source/layout/core/import.hxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_IMPORT_HXX +#define LAYOUT_CORE_IMPORT_HXX + +#include <map> +#include <list> +#define _BACKWARD_BACKWARD_WARNING_H 1 +#include <hash_map> + + +#include <com/sun/star/xml/input/XRoot.hpp> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/awt/XButton.hpp> +#include <com/sun/star/awt/XRadioButton.hpp> + +namespace layoutimpl +{ +class LayoutRoot; +class LayoutWidget; +namespace css = ::com::sun::star; + +class RadioGroups +{ +public: + RadioGroups(); + + void addItem( rtl::OUString id, css::uno::Reference< css::awt::XRadioButton > xRadio ) + throw (css::uno::RuntimeException); + +private: + class RadioGroup : public ::cppu::WeakImplHelper1< css::awt::XItemListener > + , public ::cppu::WeakImplHelper1< css::awt::XActionListener > + { + public: + RadioGroup(); + void addItem( css::uno::Reference< css::awt::XRadioButton > xRadio ); + + private: + typedef std::list< css::uno::Reference< css::awt::XRadioButton > > RadioButtonsList; + RadioButtonsList mxRadios; + css::uno::Reference< css::awt::XRadioButton > mxSelectedRadio; + + void handleSelected () + throw (css::uno::RuntimeException); + + // awt::XItemListener + void SAL_CALL itemStateChanged( const css::awt::ItemEvent& e ) + throw (css::uno::RuntimeException); + + // awt::XActionListener + void SAL_CALL actionPerformed( const css::awt::ActionEvent& e ) + throw (css::uno::RuntimeException); + + // lang::XEventListener + void SAL_CALL disposing( const css::lang::EventObject& ) + throw (css::uno::RuntimeException); + }; + + // each RadioGroup will stay alive after RadioGroups die with the ImportContext + // because they are referenced by every XRadioButton through the listener + typedef std::map< rtl::OUString, css::uno::Reference< RadioGroup > > RadioGroupsMap; + RadioGroupsMap mxRadioGroups; +}; + +// parser +class ImportContext : public ::cppu::WeakImplHelper1< css::xml::input::XRoot > +{ +public: + sal_Int32 XMLNS_LAYOUT_UID, XMLNS_CONTAINER_UID; + LayoutRoot &mrRoot; // switch to XNameContainer ref ? + RadioGroups mxRadioGroups; + + inline ImportContext( LayoutRoot &rRoot ) SAL_THROW( () ) + : mrRoot( rRoot ) {} + virtual ~ImportContext() {} + + // XRoot + virtual void SAL_CALL startDocument( + css::uno::Reference< css::xml::input::XNamespaceMapping > + const & xNamespaceMapping ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException); + virtual void SAL_CALL endDocument() + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } + virtual void SAL_CALL processingInstruction( + ::rtl::OUString const & /* rTarget */, ::rtl::OUString const & /* rData */ ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } + virtual void SAL_CALL setDocumentLocator( + css::uno::Reference< css::xml::sax::XLocator > const & /* xLocator */ ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startRootElement( + sal_Int32 nUid, ::rtl::OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes > const & xAttributes ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException); +}; + +class ElementBase : public ::cppu::WeakImplHelper1< css::xml::input::XElement > +{ +protected: + ImportContext *mpImport; +/* TODO: check if all this memebers are needed. */ + ElementBase *mpParent; + sal_Int32 mnUid; + + ::rtl::OUString maLocalName; + css::uno::Reference< css::xml::input::XAttributes > mxAttributes; +public: + ElementBase( + sal_Int32 nUid, ::rtl::OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, ImportContext * pImport ) + SAL_THROW( () ); + virtual ~ElementBase() SAL_THROW(()); + + // XElement + virtual css::uno::Reference<css::xml::input::XElement> SAL_CALL getParent() + throw (css::uno::RuntimeException) + { return static_cast< css::xml::input::XElement * >( mpParent ); } + virtual ::rtl::OUString SAL_CALL getLocalName() throw (css::uno::RuntimeException) + { return maLocalName; } + virtual sal_Int32 SAL_CALL getUid() throw (css::uno::RuntimeException) + { return mnUid; } + virtual css::uno::Reference< css::xml::input::XAttributes > + SAL_CALL getAttributes() throw (css::uno::RuntimeException) + { return mxAttributes; } + + virtual void SAL_CALL ignorableWhitespace( + ::rtl::OUString const & /* rWhitespaces */ ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } + virtual void SAL_CALL characters( ::rtl::OUString const & /* rChars */ ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } + virtual void SAL_CALL processingInstruction( + ::rtl::OUString const & /* Target */, ::rtl::OUString const & /* Data */ ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } + + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, ::rtl::OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes > const & xAttributes ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException) = 0; + virtual void SAL_CALL endElement() + throw (css::xml::sax::SAXException, css::uno::RuntimeException) + { /* ignore */ } +}; + +class WidgetElement : public ElementBase +{ +protected: + LayoutWidget *mpWidget; + +public: + WidgetElement( sal_Int32 nUid, rtl::OUString const &name, + css::uno::Reference< css::xml::input::XAttributes > const &attributes, + ElementBase *parent, ImportContext *import ) SAL_THROW (()); + + ~WidgetElement(); + + + virtual css::uno::Reference< css::xml::input::XElement> SAL_CALL + startChildElement (sal_Int32 id, rtl::OUString const &name, + css::uno::Reference< css::xml::input::XAttributes > const &attributes) + throw( css::xml::sax::SAXException, css::uno::RuntimeException ); + virtual void SAL_CALL characters( ::rtl::OUString const & /* rChars */ ) + throw (css::xml::sax::SAXException, css::uno::RuntimeException); +}; + +class ToplevelElement : public WidgetElement +{ +public: + ToplevelElement( rtl::OUString const &name, + css::uno::Reference< css::xml::input::XAttributes > const &attributes, + ImportContext *import ) SAL_THROW (()); + ~ToplevelElement(); +}; + + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_IMPORT_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/localized-string.cxx b/toolkit/source/layout/core/localized-string.cxx new file mode 100644 index 000000000000..992aa8fea06d --- /dev/null +++ b/toolkit/source/layout/core/localized-string.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "localized-string.hxx" + +#include <toolkit/helper/property.hxx> +#include <vcl/window.hxx> + +namespace layoutimpl +{ + +namespace css = ::com::sun::star; +using namespace css; +using rtl::OUString; + +LocalizedString::LocalizedString() + : VCLXWindow() +{ +} + +void LocalizedString::ImplGetPropertyIds( std::list< sal_uInt16 > &ids ) +{ + PushPropertyIds( ids, BASEPROPERTY_TEXT, 0); + VCLXWindow::ImplGetPropertyIds( ids ); +} + +// XInterface +uno::Any LocalizedString::queryInterface( uno::Type const& rType ) + throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XFixedText*, this ) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +void LocalizedString::setText( OUString const& s ) + throw(uno::RuntimeException) +{ + ::osl::SolarGuard aGuard( GetMutex() ); + + if ( Window *w = GetWindow() ) + return w->SetText( s ); +} + +OUString LocalizedString::getText() + throw(uno::RuntimeException) +{ + ::osl::SolarGuard aGuard( GetMutex() ); + + if ( Window *w = GetWindow() ) + return w->GetText(); + return OUString(); +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/localized-string.hxx b/toolkit/source/layout/core/localized-string.hxx new file mode 100644 index 000000000000..884c702cc371 --- /dev/null +++ b/toolkit/source/layout/core/localized-string.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_LOCALIZED_STRING_HXX +#define LAYOUT_CORE_LOCALIZED_STRING_HXX + +#include <com/sun/star/awt/XFixedText.hpp> +#include <toolkit/awt/vclxwindow.hxx> + +namespace layoutimpl +{ +namespace css = ::com::sun::star; + +// FIXME: misuse XFixedText interface for simple string +class LocalizedString : public css::awt::XFixedText + , public VCLXWindow +{ +public: + LocalizedString(); + + // css::uno::XInterface + css::uno::Any SAL_CALL queryInterface( css::uno::Type const& rType ) + throw(css::uno::RuntimeException); + void SAL_CALL acquire() throw() { OWeakObject::acquire(); } + void SAL_CALL release() throw() { OWeakObject::release(); } + + // css::awt::XFixedText + void SAL_CALL setText( ::rtl::OUString const& s ) + throw(css::uno::RuntimeException); + ::rtl::OUString SAL_CALL getText() + throw(css::uno::RuntimeException); + void SAL_CALL setAlignment( sal_Int16 ) + throw(css::uno::RuntimeException) { } + sal_Int16 SAL_CALL getAlignment() + throw(css::uno::RuntimeException) { return 0; } + + // css::awt::XLayoutConstrains + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException) { return css::awt::Size( 0, 0 ); } + css::awt::Size SAL_CALL getPreferredSize() + throw(css::uno::RuntimeException) { return getMinimumSize(); } + css::awt::Size SAL_CALL calcAdjustedSize( css::awt::Size const& size ) + throw(css::uno::RuntimeException) { return size; } + + static void ImplGetPropertyIds( std::list< sal_uInt16 > &ids ); + virtual void GetPropertyIds( std::list< sal_uInt16 > &ids ) + { return ImplGetPropertyIds( ids ); } +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_LOCALIZED_STRING_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/makefile.mk b/toolkit/source/layout/core/makefile.mk new file mode 100644 index 000000000000..2c90921799af --- /dev/null +++ b/toolkit/source/layout/core/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=../../.. +PRJNAME=toolkit +TARGET=layout-core +ENABLE_EXCEPTIONS=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +# FIXME: This is bad, hmkay +CFLAGS+= -I$(PRJ)/source + +SLOFILES= \ + $(SLO)$/bin.obj \ + $(SLO)$/box-base.obj \ + $(SLO)$/box.obj \ + $(SLO)$/byteseq.obj \ + $(SLO)$/container.obj \ + $(SLO)$/dialogbuttonhbox.obj \ + $(SLO)$/factory.obj \ + $(SLO)$/flow.obj \ + $(SLO)$/helper.obj \ + $(SLO)$/import.obj \ + $(SLO)$/localized-string.obj \ + $(SLO)$/proplist.obj \ + $(SLO)$/root.obj \ + $(SLO)$/table.obj \ + $(SLO)$/timer.obj \ + $(SLO)$/translate.obj\ + $(SLO)$/vcl.obj\ +# + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/toolkit/source/layout/core/precompiled_xmlscript.hxx b/toolkit/source/layout/core/precompiled_xmlscript.hxx new file mode 100644 index 000000000000..67a7d2d4eee8 --- /dev/null +++ b/toolkit/source/layout/core/precompiled_xmlscript.hxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +/* + xmlscript/source/xml_helper/xml_byteseq.cxx compile helper. + + Avoid introducing a toolkit dependency on xmlscript. + + It would be nice to modify xml_byteseq.cxx making it friendlier + to include. +*/ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/proplist.cxx b/toolkit/source/layout/core/proplist.cxx new file mode 100644 index 000000000000..0b15cff83515 --- /dev/null +++ b/toolkit/source/layout/core/proplist.cxx @@ -0,0 +1,431 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "proplist.hxx" + +#include <rtl/ustrbuf.hxx> +#include <toolkit/dllapi.h> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/awt/VclWindowPeerAttribute.hpp> +#include <tools/debug.hxx> + +#include "helper.hxx" + +#if TEST_LAYOUT && !defined( DBG_UTIL ) +#undef DBG_ERROR +#define DBG_ERROR OSL_TRACE +#undef DBG_ERROR1 +#define DBG_ERROR1 OSL_TRACE +#undef DBG_ERROR2 +#define DBG_ERROR2 OSL_TRACE +#endif /* TEST_LAYOUT && !DBG_UTIL */ + +namespace layoutimpl +{ + +using namespace com::sun::star; +using rtl::OString; +using rtl::OUString; +using rtl::OUStringBuffer; + +namespace prophlp +{ + +bool TOOLKIT_DLLPUBLIC +canHandleProps( const uno::Reference< uno::XInterface > &xPeer ) +{ + uno::Reference< beans::XPropertySet > xPropSet( xPeer, uno::UNO_QUERY ); + if ( xPropSet.is() ) + return true; + uno::Reference< beans::XPropertySetInfo > xInfo( xPeer, uno::UNO_QUERY ); + uno::Reference< awt::XVclWindowPeer> xVclPeer( xPeer, uno::UNO_QUERY ); + return xInfo.is() && xVclPeer.is(); +} + +uno::Reference< beans::XPropertySetInfo > TOOLKIT_DLLPUBLIC +queryPropertyInfo( + const uno::Reference< uno::XInterface > &xPeer ) +{ + uno::Reference< beans::XPropertySetInfo > xInfo( xPeer, uno::UNO_QUERY ); + if ( !xInfo.is() ) + { + uno::Reference< beans::XPropertySet > xPropSet( xPeer, uno::UNO_QUERY ); + if ( xPropSet.is() ) + xInfo = xPropSet->getPropertySetInfo(); + } + return xInfo; +} + +void TOOLKIT_DLLPUBLIC +setProperty( const uno::Reference< uno::XInterface > &xPeer, + const OUString &rName, uno::Any aValue ) +{ + uno::Reference< awt::XVclWindowPeer> xVclPeer( xPeer, uno::UNO_QUERY ); + if ( xVclPeer.is() ) + xVclPeer->setProperty( rName, aValue ); + else + { + uno::Reference< beans::XPropertySet > xPropSet( xPeer, uno::UNO_QUERY ); + xPropSet->setPropertyValue( rName, aValue ); + } +} + +uno::Any TOOLKIT_DLLPUBLIC +getProperty( const uno::Reference< uno::XInterface > &xPeer, + const OUString &rName ) +{ + uno::Reference< awt::XVclWindowPeer> xVclPeer( xPeer, uno::UNO_QUERY ); + if ( xVclPeer.is() ) + return xVclPeer->getProperty( rName ); + + uno::Reference< beans::XPropertySet > xPropSet( xPeer, uno::UNO_QUERY ); + return xPropSet->getPropertyValue( rName ); +} + +} // namespace prophlp + + +/* Given a string and a type, it converts the string to the type, and returns + it encapsulated in Any. */ +uno::Any anyFromString( OUString const& value, uno::Type const& type ) +{ + sal_Int16 radix = 10; + OUString intval = value; + if ( value.getLength() > 2 && value[0] == '0' && value[1] == 'x' ) + intval = value.copy( 2 ), radix = 16; + else if ( value.getLength() > 1 && value[0] == '#' ) + intval = value.copy( 1 ), radix = 16; + switch ( type.getTypeClass() ) + { + case uno::TypeClass_CHAR: + return uno::makeAny( value.toChar() ); + case uno::TypeClass_BOOLEAN: + if ( value == OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) ) + return uno::makeAny( true ); + else if ( value == OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) ) ) + return uno::makeAny( false ); + break; // ends switch, throws exception + case uno::TypeClass_BYTE: + return uno::makeAny( ( sal_uInt8 ) intval.toInt32( radix ) ); + case uno::TypeClass_SHORT: + return uno::makeAny( ( sal_Int16 ) intval.toInt32( radix ) ); + case uno::TypeClass_UNSIGNED_SHORT: + return uno::makeAny( ( sal_uInt16 ) intval.toInt32( radix ) ); + case uno::TypeClass_ENUM: + return uno::makeAny( ( sal_Int16 ) intval.toInt32( radix ) ); + case uno::TypeClass_LONG: + return uno::makeAny( ( sal_Int32 ) intval.toInt32( radix ) ); + case uno::TypeClass_UNSIGNED_LONG: + return uno::makeAny( ( sal_uInt32 ) intval.toInt32( radix ) ); + case uno::TypeClass_HYPER: + return uno::makeAny( ( sal_Int64 ) intval.toInt64( radix ) ); + case uno::TypeClass_UNSIGNED_HYPER: + return uno::makeAny( ( sal_uInt16 ) intval.toInt64( radix ) ); + case uno::TypeClass_FLOAT: + return uno::makeAny( value.toFloat() ); + case uno::TypeClass_DOUBLE: + return uno::makeAny( value.toDouble() ); + case uno::TypeClass_STRING: + return uno::makeAny( value ); + case uno::TypeClass_CONSTANT: + return uno::makeAny( intval.toInt32( radix ) ); + case uno::TypeClass_INTERFACE: + return uno::makeAny( loadGraphic( OUSTRING_CSTR( value ) ) ); + case uno::TypeClass_SEQUENCE: + { + sal_Int32 i = 0; + bool escaped = false, first = true; + OUString item, token; + std::list< OUString > values; + do + { + token = value.getToken( 0, ':', i ); + + if ( !token.getLength() && !escaped ) + { + escaped = true; + item += OUString( ':' ); + } + else if ( escaped ) + { + escaped = false; + item += token; + } + else + { + if ( !first ) + values.push_back( item ); + item = token; + } + first = false; + } + while ( i >= 0 ); + if ( item.getLength() ) + values.push_back( item ); + + uno::Sequence< OUString > seq( values.size() ); + i = 0; + for ( std::list< OUString >::const_iterator it = values.begin(); + it != values.end(); it++, i++ ) + seq[ i ] = *it; + + return uno::makeAny( seq ); + } + + default: + DBG_ERROR1( "ERROR: unknown property type of value: `%s'\n", OUSTRING_CSTR( value ) ); + break; + } + throw uno::RuntimeException(); +} + +/* Converts the XML naming scheme to UNO's, for legacy compatibility + (so, ergo, "one-two-three-four" -> "OneTwoThreeFour"). */ +static OUString toUnoNaming ( OUString const &string ) +{ + OUStringBuffer buffer( string.getLength() ); + sal_Unicode *str = string.pData->buffer; + bool capitalize = true; + + for ( int i = 0; i < string.getLength(); i++ ) + { + if ( i == 0 && str[0] == '_' ) + /* Skip translate-me prefix. */ + continue; + if ( str[i] == '-' ) + capitalize = true; + else + { + if ( capitalize && str[i] >= 'a' && str[i] <= 'z' ) + buffer.append( (sal_Unicode ) ( str[i] - 'a' + 'A' ) ); + else + buffer.append( (sal_Unicode ) str[i] ); + capitalize = false; + } + } + + return buffer.makeStringAndClear(); +} + +/* + * convert incoming XML style property names, to AWT style property names. + * convert the values based on introspection information. + * apply to either an XPropertySet or an XPropertySetInfo | XVclWindowPeer + * aggregate. + */ +void +setProperties( uno::Reference< uno::XInterface > const& xPeer, + PropList const& rProps ) +{ + if ( !prophlp::canHandleProps( xPeer ) ) + { + DBG_ERROR( "Error: setProperties - bad handle ignoring props:\n" ); + for ( PropList::const_iterator it = rProps.begin(); it != rProps.end(); + it++ ) + { + DBG_ERROR2( "%s=%s\n", OUSTRING_CSTR( it->first ), OUSTRING_CSTR( it->second ) ); + } + return; + } + + for ( PropList::const_iterator it = rProps.begin(); it != rProps.end(); + it++ ) + setProperty( xPeer, it->first, it->second ); +} + +void +setProperty( uno::Reference< uno::XInterface > const& xPeer, + OUString const& attr, OUString const& value ) +{ + OUString unoAttr = toUnoNaming( attr ); + + OSL_TRACE( "setting %s=%s", OUSTRING_CSTR( attr ), OUSTRING_CSTR( value ) ); + // get a Property object + beans::Property prop; + try + { + uno::Reference< beans::XPropertySetInfo > xInfo + = prophlp::queryPropertyInfo( xPeer ); + prop = xInfo->getPropertyByName( unoAttr ); + } + catch( beans::UnknownPropertyException & ) + { + DBG_ERROR1( "Warning: unknown attribute: `%s'\n", OUSTRING_CSTR( unoAttr ) ); + return; + } + + if ( prop.Name.getLength() <= 0 ) + { + DBG_ERROR1( "Warning: missing prop: `%s'\n", OUSTRING_CSTR( unoAttr ) ); + return; + } + + // encapsulates value in an uno::Any + uno::Any any; + try + { + any = anyFromString( value, prop.Type ); + } + catch( uno::RuntimeException & ) + { + DBG_ERROR5( "Warning: %s( %s )( %s ) attribute is of type %s( rejected: %s )\n", OUSTRING_CSTR( unoAttr ), OUSTRING_CSTR( value ), OUSTRING_CSTR( prop.Name ), OUSTRING_CSTR( prop.Type.getTypeName() ), OUSTRING_CSTR( value ) ); + return; + } + + // sets value on property + try + { + prophlp::setProperty( xPeer, unoAttr, any ); + } + catch( ... ) + { + DBG_ERROR2( "Warning: cannot set attribute %s to %s \n", OUSTRING_CSTR( unoAttr ), OUSTRING_CSTR( value ) ); + } +} + + + + +struct AttributesMap +{ + const char *name; + long value; + bool windowAttr; +}; +static const AttributesMap attribsMap[] = +{ + { "autohscroll", awt::VclWindowPeerAttribute::AUTOHSCROLL, false }, + { "autovscroll", awt::VclWindowPeerAttribute::AUTOVSCROLL, false }, + { "center", awt::VclWindowPeerAttribute::CENTER, false }, + { "clipchildren", awt::VclWindowPeerAttribute::CLIPCHILDREN, false }, + { "closeable", awt::WindowAttribute::CLOSEABLE, true }, + { "defbutton", awt::VclWindowPeerAttribute::DEFBUTTON, false }, + { "dropdown", awt::VclWindowPeerAttribute::DROPDOWN, false }, + { "fullsize", awt::WindowAttribute::FULLSIZE, true }, //FIXME? + { "group", awt::VclWindowPeerAttribute::GROUP, false }, + { "has_border", awt::WindowAttribute::BORDER, true }, + { "hscroll", awt::VclWindowPeerAttribute::HSCROLL, false }, + { "left", awt::VclWindowPeerAttribute::LEFT, false }, + { "moveable", awt::WindowAttribute::MOVEABLE, true }, + { "noborder", awt::VclWindowPeerAttribute::NOBORDER, false }, + { "nolabel", awt::VclWindowPeerAttribute::NOLABEL, false }, + { "optimumsize", awt::WindowAttribute::OPTIMUMSIZE, false }, + { "readonly", awt::VclWindowPeerAttribute::READONLY, false }, + { "right", awt::VclWindowPeerAttribute::RIGHT, false }, + { "show", awt::WindowAttribute::SHOW, true }, + { "sizeable", awt::WindowAttribute::SIZEABLE, true }, + { "sort", awt::VclWindowPeerAttribute::SORT, false }, + { "spin", awt::VclWindowPeerAttribute::SPIN, false }, + { "vscroll", awt::VclWindowPeerAttribute::VSCROLL, false }, + + // cutting on OK, YES_NO_CANCEL and related obsite attributes... +}; +static const int attribsMapLen = sizeof( attribsMap ) / sizeof( AttributesMap ); + +void propsFromAttributes( const uno::Reference<xml::input::XAttributes> & xAttributes, + PropList &rProps, sal_Int32 nNamespace ) +{ + sal_Int32 nAttrs = xAttributes->getLength(); + for ( sal_Int32 i = 0; i < nAttrs; i++ ) + { + if ( nNamespace != xAttributes->getUidByIndex( i ) ) + continue; + + std::pair< OUString, OUString > aElem + ( xAttributes->getLocalNameByIndex( i ), + xAttributes->getValueByIndex( i ) ); + + if ( aElem.first.getLength() > 0 ) // namespace bits .. + rProps.push_back( aElem ); + } +} + +bool +findAndRemove( const char *pAttr, PropList &rProps, OUString &rValue ) +{ + PropList::iterator it; + OUString aName = OUString::createFromAscii( pAttr ); + + for ( it = rProps.begin(); it != rProps.end(); it++ ) + { + if ( it->first.equalsIgnoreAsciiCase( aName ) + || it->first.equalsIgnoreAsciiCase( OUString::createFromAscii ("_") + aName ) ) + { + rValue = it->second; + rProps.erase( it ); + return true; + } + } + rValue = OUString(); + return false; +} + +long +getAttributeProps( PropList &rProps ) +{ + long nAttrs = 0; + OUString aValue; + + OUString trueStr( RTL_CONSTASCII_USTRINGPARAM( "true" ) ); + + if ( findAndRemove( "show", rProps, aValue ) && + aValue.equalsIgnoreAsciiCase( + OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) ) ) ) + ; + else + nAttrs |= awt::WindowAttribute::SHOW; + + for ( int i = 0; i < attribsMapLen; i++ ) + { + if ( findAndRemove( attribsMap[i].name, rProps, aValue ) ) + { + if ( aValue.equalsIgnoreAsciiCase( trueStr ) ) + nAttrs |= attribsMap[i].value; + } + } + + if ( findAndRemove( "align", rProps, aValue ) ) + { + sal_Int32 nVal = aValue.toInt32(); + + if ( nVal == 0 /* PROPERTY_ALIGN_LEFT */ ) + nAttrs |= awt::VclWindowPeerAttribute::LEFT; + else if ( nVal == 1 /* PROPERTY_ALIGN_CENTER */ ) + nAttrs |= awt::VclWindowPeerAttribute::CENTER; + else if ( nVal == 2 ) + nAttrs |= awt::VclWindowPeerAttribute::RIGHT; + } + + return nAttrs; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/proplist.hxx b/toolkit/source/layout/core/proplist.hxx new file mode 100644 index 000000000000..20eacbd19885 --- /dev/null +++ b/toolkit/source/layout/core/proplist.hxx @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_PROPLIST_HXX +#define LAYOUT_CORE_PROPLIST_HXX + +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/xml/input/XAttributes.hpp> +#include <list> +#include <rtl/ustring.hxx> +#include <toolkit/dllapi.h> +\ +namespace layoutimpl +{ + +namespace css = ::com::sun::star; + +typedef std::list< std::pair< rtl::OUString, rtl::OUString > > PropList; + +void propsFromAttributes( const css::uno::Reference<css::xml::input::XAttributes> & xAttributes, + PropList &rProps, sal_Int32 nNamespace ); + +void setProperties( css::uno::Reference< css::uno::XInterface > const& xPeer, + PropList const& rProps); + +void setProperty( css::uno::Reference< css::uno::XInterface > const& xPeer, + rtl::OUString const& attr, rtl::OUString const& value ); + +long getAttributeProps( PropList &rProps ); +bool findAndRemove( const char *pAttr, PropList &rProps, rtl::OUString &rValue); + +// Helpers - unfortunately VCLXWindows don't implement XPropertySet +// but containers do - these helpers help us to hide this +namespace prophlp +{ + +// can we set properties on this handle ? +bool TOOLKIT_DLLPUBLIC canHandleProps( const css::uno::Reference< css::uno::XInterface > &xRef ); +// if so which properties ? +css::uno::Reference< css::beans::XPropertySetInfo > TOOLKIT_DLLPUBLIC queryPropertyInfo( + const css::uno::Reference< css::uno::XInterface > &xRef ); +// set / get ... +void TOOLKIT_DLLPUBLIC setProperty( const css::uno::Reference< css::uno::XInterface > &xRef, + const rtl::OUString &rName, + css::uno::Any aValue ); +css::uno::Any TOOLKIT_DLLPUBLIC getProperty( const css::uno::Reference< css::uno::XInterface > &xRef, + const rtl::OUString &rName ); +} // namespace prophlp + +} // namespace layoutimpl + + +#if !OUSTRING_CSTR_PARANOIA +#define OUSTRING_CSTR( str ) \ + rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ).getStr() +#else + +inline char const* OUSTRING_CSTR( rtl::OUString const& str ) +{ + rtl::OString *leak + = new rtl::OString (rtl::OUStringToOString (str, RTL_TEXTENCODING_ASCII_US)); + return leak->getStr(); +} + +#endif + +#endif /* LAYOUT_CORE_PROPLIST_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/root.cxx b/toolkit/source/layout/core/root.cxx new file mode 100644 index 000000000000..db6bedc075fc --- /dev/null +++ b/toolkit/source/layout/core/root.cxx @@ -0,0 +1,393 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "root.hxx" + +#include <cassert> + +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/XMessageBox.hpp> +#include <com/sun/star/awt/MessageBoxButtons.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/awt/XMessageBoxFactory.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> + +#include "helper.hxx" +#include "import.hxx" +#include "timer.hxx" +#include "translate.hxx" + +namespace layoutimpl +{ + +using namespace css; +using ::rtl::OUString; + +LayoutRoot::LayoutRoot( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) + : mbDisposed( sal_False ) + , mxFactory( xFactory ) + , mpListeners( NULL ) + , mpToplevel( NULL ) +{ + if ( !xFactory.is() ) + throw uno::RuntimeException(); + mxLayoutUnit = uno::Reference< awt::XLayoutUnit >( new LayoutUnit() ); +} + +LayoutRoot::~LayoutRoot() +{ +// TODO: we want to delete the top level LayoutWidget... + ::osl::MutexGuard aGuard( maMutex ); + if ( !mbDisposed ) + { + try + { + m_refCount++; // inhibit multiple destruction + dispose(); + } + catch( uno::Exception& ) + { + } + } +} + +void ShowMessageBox( uno::Reference< lang::XMultiServiceFactory > const& xFactory, uno::Reference< awt::XToolkit > xToolkit, OUString const& aTitle, OUString const& aMessage ) +{ + uno::Reference< uno::XInterface > iDesktop = xFactory->createInstance + ( OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ); + uno::Reference< frame::XDesktop > xDesktop ( iDesktop, uno::UNO_QUERY ); + uno::Reference< frame::XFrame > xFrame ( xDesktop->getCurrentFrame() ); + uno::Reference< awt::XWindow > xContainerWindow( xFrame->getContainerWindow() ); + uno::Reference< awt::XWindowPeer > xWindowPeer( xContainerWindow, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XMessageBoxFactory > xMessageBoxFactory( xToolkit, uno::UNO_QUERY ); + + awt::Rectangle aRectangle; + uno::Reference< awt::XMessageBox > xMessageBox + = xMessageBoxFactory->createMessageBox + ( xWindowPeer, aRectangle, OUString::createFromAscii( "errorbox" ), + awt::MessageBoxButtons::BUTTONS_OK, aTitle, aMessage ); + + if ( xMessageBox.is() ) + xMessageBox->execute(); + //FIXME: exceptions not caught and printed at top level?? + //else + //printf( "%s\n", OUSTRING_CSTR( aMessage ) ); +} + +void LayoutRoot::error( OUString const& message ) +{ + OSL_TRACE( "%s\n", OUSTRING_CSTR( message ) ); + ShowMessageBox( mxFactory, mxToolkit, + OUString::createFromAscii( "Fatal error" ), + message ); + throw uno::RuntimeException( message, uno::Reference< uno::XInterface >() ); +} + +// XInitialization +void SAL_CALL LayoutRoot::initialize( const uno::Sequence< uno::Any >& aArguments ) + throw ( uno::Exception, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( mbDisposed ) + throw lang::DisposedException(); + + if ( mxContainer.is() ) // only 1 init ... + throw uno::Exception(); + + if ( !aArguments.getLength() ) + throw lang::IllegalArgumentException(); + + OSL_ENSURE( aArguments.getLength() == 1, "Wrong arg count\n" ); + + OUString aXMLName; + if ( !( aArguments[0] >>= aXMLName ) ) + throw lang::IllegalArgumentException(); + + uno::Reference< xml::sax::XParser > xParser + ( mxFactory->createInstance( + OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) ), + uno::UNO_QUERY ); + OSL_ASSERT( xParser.is() ); + if (! xParser.is()) + { + throw uno::RuntimeException( + OUString::createFromAscii( "cannot create sax-parser component" ), + uno::Reference< uno::XInterface >() ); + } + + // FIXME: quite possibly we want to pass this in ... + uno::Reference< awt::XToolkit > xToolkit; + + mxToolkit = uno::Reference< awt::XToolkit >( + mxFactory->createInstance( + OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ), + uno::UNO_QUERY ); + + if ( !mxToolkit.is() ) + throw uno::RuntimeException( + OUString::createFromAscii( "failed to create toolkit!" ), + uno::Reference< uno::XInterface >() ); + + OUString aXMLFile = readRightTranslation( aXMLName ); + uno::Reference< io::XInputStream > xStream = getFileAsStream( aXMLFile ); + if (! xStream.is() ) + error( OUString::createFromAscii( "Installation problem: cannot find XML file:" ) + aXMLName ); + + // error handler, entity resolver omitted + + ImportContext *pCtx = new ImportContext( *this ); + + uno::Reference< xml::input::XRoot > xRoot( pCtx ); + uno::Sequence < uno::Any > aArgs( 1 ); + aArgs[0] <<= xRoot; + uno::Reference< xml::sax::XDocumentHandler > xDocHandler + (mxFactory->createInstanceWithArguments + ( OUString::createFromAscii( "com.sun.star.xml.input.SaxDocumentHandler" ), + aArgs ), uno::UNO_QUERY ); + + if (! xDocHandler.is() ) + error( OUString::createFromAscii( "cannot find SAx handler for document type of:") + aXMLName ); + + xParser->setDocumentHandler( xDocHandler ); + + xml::sax::InputSource source; + source.aInputStream = xStream; + source.sSystemId = OUString::createFromAscii( "virtual file" ); + + try + { + xParser->parseStream( source ); + } + catch ( xml::sax::SAXParseException& e ) + { + OUString c = OUString::createFromAscii( ":" ); + error( aXMLName + + c + OUString::valueOf( e.LineNumber ) + + c + OUString::valueOf( e.ColumnNumber ) + + c + OUString::createFromAscii( "Sax parse error" ) ); + } +} + +// XLayoutContainer +uno::Reference< awt::XLayoutContainer > LayoutRoot::getLayoutContainer() throw (uno::RuntimeException) +{ + return uno::Reference< awt::XLayoutContainer >(); +} + +// local helper ... +void LayoutRoot::addItem( const OUString &rName, + const uno::Reference< awt::XLayoutConstrains > &xRef ) +{ + maItems[ rName ] = xRef; +} + +// XNameAccess +uno::Any SAL_CALL LayoutRoot::getByName( const OUString &rName ) + throw ( container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbDisposed ) + throw lang::DisposedException(); + + uno::Reference< awt::XLayoutConstrains > xItem; + ItemHash::iterator i = maItems.find( rName ); + if ( i != maItems.end() ) + xItem = i->second; + return uno::makeAny( xItem ); +} + +sal_Bool SAL_CALL LayoutRoot::hasByName( const OUString &rName ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbDisposed ) throw lang::DisposedException(); + + ItemHash::iterator i = maItems.find( rName ); + return i != maItems.end(); +} + +uno::Sequence< OUString > SAL_CALL LayoutRoot::getElementNames() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + if ( mbDisposed ) throw lang::DisposedException(); + + uno::Sequence< OUString > aNames( maItems.size() ); + sal_Int32 nPos = 0; + + for ( ItemHash::const_iterator it = maItems.begin(); + it != maItems.end(); it++ ) + aNames[ nPos++ ] = it->first; + + return aNames; +} + +uno::Type SAL_CALL LayoutRoot::getElementType() + throw ( uno::RuntimeException ) +{ + return getCppuType( ( const uno::Reference< awt::XLayoutConstrains >* )NULL ); +} + +sal_Bool SAL_CALL LayoutRoot::hasElements() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( mbDisposed ) throw lang::DisposedException(); + + return maItems.size() > 0; +} + +// XComponent +void SAL_CALL LayoutRoot::dispose() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( mbDisposed ) throw lang::DisposedException(); + + if ( mpListeners ) + { + + lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) ); + mpListeners->disposeAndClear( aSource ); + delete mpListeners; + mpListeners = NULL; + } + + maItems.clear(); + mbDisposed = sal_True; +} + +void SAL_CALL LayoutRoot::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( mbDisposed ) throw lang::DisposedException(); + + if ( !mpListeners ) + mpListeners = new ::cppu::OInterfaceContainerHelper( maMutex ); + mpListeners->addInterface( xListener ); +} + +void SAL_CALL LayoutRoot::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + if ( mbDisposed ) throw lang::DisposedException(); + + if ( mpListeners ) + mpListeners->removeInterface( xListener ); +} + +// builder + +LayoutWidget *LayoutRoot::create( OUString id, const OUString unoName, long attrbs,uno::Reference< awt::XLayoutContainer > xParent ) +{ + LayoutWidget *pWidget = new LayoutWidget( mxToolkit, xParent, unoName, attrbs ); + if ( !mpToplevel ) + { + mpToplevel = pWidget; + mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY ); + mxContainer = pWidget->mxContainer; + } + if ( pWidget->mxContainer.is() ) + pWidget->mxContainer->setLayoutUnit( mxLayoutUnit ); + if ( id.getLength() ) + maItems[ id ] = pWidget->getPeer(); + return pWidget; +} + +LayoutWidget::LayoutWidget( uno::Reference< awt::XToolkit > xToolkit, + uno::Reference< awt::XLayoutContainer > xParent, + OUString unoName, long attrbs ) +{ + while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() ) + { + uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY ); + assert( xContainer.is() ); + xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY ); + } + + mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, attrbs ); + assert( mxWidget.is() ); + mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY ); +} + +LayoutWidget::~LayoutWidget() +{ + /* should we dispose of the references...? */ + // at least of its children... Or should root? +} + +bool LayoutWidget::addChild( LayoutWidget *pChild ) +{ + if ( !mxContainer.is() ) + return false; + + try + { + mxContainer->addChild( pChild->mxWidget ); + } + catch( awt::MaxChildrenException ex ) + { + return false; + } + return true; +} + +void LayoutWidget::setProperties( PropList const& rProps ) +{ + ::layoutimpl::setProperties( mxWidget, rProps ); +} + +void LayoutWidget::setProperty( OUString const& attr, OUString const& value ) +{ + ::layoutimpl::setProperty( mxWidget, attr, value ); +} + +void LayoutWidget::setChildProperties( LayoutWidget *pChild, + PropList const& rProps ) +{ + uno::Reference< beans::XPropertySet > xChildPeer; + xChildPeer = mxContainer->getChildProperties( pChild->mxWidget ); + + if ( xChildPeer.is() ) + ::layoutimpl::setProperties( xChildPeer, rProps ); +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/root.hxx b/toolkit/source/layout/core/root.hxx new file mode 100644 index 000000000000..b4e3fe68cfb3 --- /dev/null +++ b/toolkit/source/layout/core/root.hxx @@ -0,0 +1,159 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_ROOT_HXX +#define LAYOUT_CORE_ROOT_HXX + +#define _BACKWARD_BACKWARD_WARNING_H 1 +#include <hash_map> + +#include <com/sun/star/awt/XLayoutRoot.hpp> +#include <com/sun/star/awt/XToolkit.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <toolkit/dllapi.h> + +#include <layout/core/proplist.hxx> + +namespace layoutimpl +{ + +namespace css = ::com::sun::star; + +css::uno::Reference< css::io::XInputStream > getFileAsStream( const rtl::OUString &rName ); + +/* Interface generation code -- to hook to a parser. */ + +/* + TODO: (ricardo) I think we should cut on LayoutRoot, stripping out its widget + proxy interface (just make it return the root widget). Would even make it easier + if there was interest to support multiple toplevel widgets in the same file. + + We also need to make sure the code gets diposed well... There is no need to keep + these objects around after initialization... +*/ + + +class LayoutWidget; + +class TOOLKIT_DLLPUBLIC LayoutRoot : public ::cppu::WeakImplHelper3< + css::awt::XLayoutRoot, + css::lang::XInitialization, + css::lang::XComponent> +{ +protected: + ::osl::Mutex maMutex; + + typedef std::hash_map< rtl::OUString, + css::uno::Reference< css::awt::XLayoutConstrains >, + ::rtl::OUStringHash > ItemHash; + ItemHash maItems; + + sal_Bool mbDisposed; + css::uno::Reference< css::lang::XMultiServiceFactory > mxFactory; + ::cppu::OInterfaceContainerHelper *mpListeners; + + css::uno::Reference< css::awt::XWindow > mxWindow; + css::uno::Reference< css::awt::XLayoutContainer > mxContainer; + + css::uno::Reference< css::awt::XToolkit > mxToolkit; + LayoutWidget *mpToplevel; + css::uno::Reference< css::awt::XLayoutUnit > mxLayoutUnit; + + void error( rtl::OUString const& message ); + +public: + LayoutRoot( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ); + virtual ~LayoutRoot(); + + void addItem( const rtl::OUString &rName, + const css::uno::Reference< css::awt::XLayoutConstrains > &xRef ); + + void setWindow( css::uno::Reference< css::awt::XLayoutConstrains > xPeer ) + { + mxWindow = css::uno::Reference< css::awt::XWindow >( xPeer, css::uno::UNO_QUERY ); + } + + // get XLayoutContainer + virtual css::uno::Reference< css::awt::XLayoutContainer > SAL_CALL getLayoutContainer() throw (css::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw (css::uno::Exception, css::uno::RuntimeException); + + // XNameAccess + virtual css::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException); + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose() throw (css::uno::RuntimeException); + virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw (css::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) throw (css::uno::RuntimeException); + + // generator + virtual LayoutWidget *create( rtl::OUString id, const rtl::OUString unoName, long attrbs, css::uno::Reference< css::awt::XLayoutContainer > xParent ); +}; + +class TOOLKIT_DLLPUBLIC LayoutWidget +{ + friend class LayoutRoot; + +public: + LayoutWidget() {} + LayoutWidget( css::uno::Reference< css::awt::XToolkit > xToolkit, + css::uno::Reference< css::awt::XLayoutContainer > xToplevel, + rtl::OUString unoName, long attrbs ); + virtual ~LayoutWidget(); + + virtual void setProperties( const PropList &rProps ); + virtual void setProperty( rtl::OUString const& attr, rtl::OUString const& value ); + + virtual bool addChild( LayoutWidget *pChild ); + virtual void setChildProperties( LayoutWidget *pChild, const PropList &rProps ); + + inline css::uno::Reference< css::awt::XLayoutConstrains > getPeer() + { return mxWidget; } + inline css::uno::Reference< css::awt::XLayoutContainer > getContainer() + { return mxContainer; } + +protected: + css::uno::Reference< css::awt::XLayoutConstrains > mxWidget; + css::uno::Reference< css::awt::XLayoutContainer > mxContainer; +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_ROOT_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/table.cxx b/toolkit/source/layout/core/table.cxx new file mode 100644 index 000000000000..d724c8c48083 --- /dev/null +++ b/toolkit/source/layout/core/table.cxx @@ -0,0 +1,314 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <table.hxx> + +#include <sal/macros.h> +#include <osl/mutex.hxx> +#include <cppuhelper/propshlp.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <com/sun/star/awt/PosSize.hpp> +#include <tools/debug.hxx> + +// fixed point precision for distributing error +#define FIXED_PT 16 + +namespace layoutimpl +{ + +using namespace com::sun::star; + +Table::ChildProps::ChildProps( Table::ChildData *pData ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "XExpand" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &( pData->mbExpand[ 0 ] ) ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "YExpand" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &( pData->mbExpand[ 1 ] ) ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "ColSpan" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &( pData->mnColSpan ) ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "RowSpan" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &( pData->mnRowSpan ) ); +} + +bool Table::ChildData::isVisible() +{ + return Box_Base::ChildData::isVisible() + && ( mnColSpan > 0 ) && ( mnRowSpan > 0 ); +} + +Table::Table() + : Box_Base() + , mnColsLen( 1 )// another default value could be 0xffff for infinite columns( = 1 row ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Columns" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &mnColsLen ); +} + +Table::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild ) + : Box_Base::ChildData( xChild ) +// , mbExpand( { 1, 1 } ) + , mnColSpan( 1 ) + , mnRowSpan( 1 ) + , mnLeftCol( 0 ) + , mnRightCol( 0 ) + , mnTopRow( 0 ) + , mnBottomRow( 0 ) +{ + mbExpand[ 0 ] = 1; + mbExpand[ 1 ] = 1; +} + +Table::ChildData* +Table::createChild( uno::Reference< awt::XLayoutConstrains > const& xChild ) +{ + return new ChildData( xChild ); +} + +Table::ChildProps* +Table::createChildProps( Box_Base::ChildData *pData ) +{ + return new ChildProps( static_cast<Table::ChildData*> ( pData ) ); +} + +void SAL_CALL +Table::addChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw( uno::RuntimeException, awt::MaxChildrenException ) +{ + if ( xChild.is() ) + { + Box_Base::addChild( xChild ); + // cause of flicker + allocateChildAt( xChild, awt::Rectangle( 0,0,0,0 ) ); + } +} + +awt::Size SAL_CALL +Table::getMinimumSize() throw( uno::RuntimeException ) +{ + int nRowsLen = 0; + + // 1. layout the table -- adjust to cope with row-spans... + { + // temporary 1D representation of the table + std::vector< ChildData *> aTable; + + int col = 0; + int row = 0; + for ( std::list<Box_Base::ChildData *>::iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Table::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + + while ( col + SAL_MIN( child->mnColSpan, mnColsLen ) > mnColsLen ) + { + col = 0; + row++; + + unsigned int i = col +( row*mnColsLen ); + while ( aTable.size() > i && !aTable[ i ] ) + i++; + + col = i % mnColsLen; + row = i / mnColsLen; + } + + child->mnLeftCol = col; + child->mnRightCol = SAL_MIN( col + child->mnColSpan, mnColsLen ); + child->mnTopRow = row; + child->mnBottomRow = row + child->mnRowSpan; + + col += child->mnColSpan; + + unsigned int start = child->mnLeftCol +( child->mnTopRow*mnColsLen ); + unsigned int end =( child->mnRightCol-1 ) +( ( child->mnBottomRow-1 )*mnColsLen ); + if ( aTable.size() < end+1 ) + aTable.resize( end+1, NULL ); + for ( unsigned int i = start; i < end; i++ ) + aTable[ i ] = child; + + nRowsLen = SAL_MAX( nRowsLen, child->mnBottomRow ); + } + } + + // 2. calculate columns/rows sizes + for ( int g = 0; g < 2; g++ ) + { + std::vector< GroupData > &aGroup = g == 0 ? maCols : maRows; + + aGroup.clear(); + aGroup.resize( g == 0 ? mnColsLen : nRowsLen ); + + // 2.1 base sizes on one-column/row children + for ( std::list<Box_Base::ChildData *>::iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Table::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + const int nFirstAttach = g == 0 ? child->mnLeftCol : child->mnTopRow; + const int nLastAttach = g == 0 ? child->mnRightCol : child->mnBottomRow; + + if ( nFirstAttach == nLastAttach-1 ) + { + child->maRequisition = child->mxChild->getMinimumSize(); + int attach = nFirstAttach; + int child_size = g == 0 ? child->maRequisition.Width + : child->maRequisition.Height; + aGroup[ attach ].mnSize = SAL_MAX( aGroup[ attach ].mnSize, + child_size ); + if ( child->mbExpand[ g ] ) + aGroup[ attach ].mbExpand = true; + } + } + + // 2.2 make sure multiple-columns/rows children fit + for ( std::list<Box_Base::ChildData *>::iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Table::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + const int nFirstAttach = g == 0 ? child->mnLeftCol : child->mnTopRow; + const int nLastAttach = g == 0 ? child->mnRightCol : child->mnBottomRow; + + if ( nFirstAttach != nLastAttach-1 ) + { + child->maRequisition = child->mxChild->getMinimumSize(); + int size = 0; + int expandables = 0; + for ( int i = nFirstAttach; i < nLastAttach; i++ ) + { + size += aGroup[ i ].mnSize; + if ( aGroup[ i ].mbExpand ) + expandables++; + } + + int child_size = g == 0 ? child->maRequisition.Width + : child->maRequisition.Height; + int extra = child_size - size; + if ( extra > 0 ) + { + if ( expandables ) + extra /= expandables; + else + extra /= nLastAttach - nFirstAttach; + + for ( int i = nFirstAttach; i < nLastAttach; i++ ) + if ( expandables == 0 || aGroup[ i ].mbExpand ) + aGroup[ i ].mnSize += extra; + } + } + } + } + + // 3. Sum everything up + mnColExpandables =( mnRowExpandables = 0 ); + maRequisition.Width =( maRequisition.Height = 0 ); + for ( std::vector<GroupData>::iterator it = maCols.begin(); + it != maCols.end(); it++ ) + { + maRequisition.Width += it->mnSize; + if ( it->mbExpand ) + mnColExpandables++; + } + for ( std::vector<GroupData>::iterator it = maRows.begin(); + it != maRows.end(); it++ ) + { + maRequisition.Height += it->mnSize; + if ( it->mbExpand ) + mnRowExpandables++; + } + + return maRequisition; +} + +void SAL_CALL +Table::allocateArea( const awt::Rectangle &rArea ) + throw( uno::RuntimeException ) +{ + maAllocation = rArea; + if ( maCols.size() == 0 || maRows.size() == 0 ) + return; + + int nExtraSize[ 2 ] = { SAL_MAX( rArea.Width - maRequisition.Width, 0 ), + SAL_MAX( rArea.Height - maRequisition.Height, 0 ) }; + // split it + nExtraSize[ 0 ] /= mnColExpandables ? mnColExpandables : mnColsLen; + nExtraSize[ 1 ] /= mnRowExpandables ? mnRowExpandables : maRows.size(); + + for ( std::list<Box_Base::ChildData *>::const_iterator it + = maChildren.begin(); it != maChildren.end(); it++ ) + { + ChildData *child = static_cast<Table::ChildData*> ( *it ); + if ( !child->isVisible() ) + continue; + + awt::Rectangle rChildArea( rArea.X, rArea.Y, 0, 0 ); + + for ( int g = 0; g < 2; g++ ) + { + std::vector< GroupData > &aGroup = g == 0 ? maCols : maRows; + const int nFirstAttach = g == 0 ? child->mnLeftCol : child->mnTopRow; + const int nLastAttach = g == 0 ? child->mnRightCol : child->mnBottomRow; + + for ( int i = 0; i < nFirstAttach; i++ ) + { + int gSize = aGroup[ i ].mnSize; + if ( aGroup[ i ].mbExpand ) + gSize += nExtraSize[ g ]; + if ( g == 0 ) + rChildArea.X += gSize; + else + rChildArea.Y += gSize; + } + for ( int i = nFirstAttach; i < nLastAttach; i++ ) + { + int gSize = aGroup[ i ].mnSize; + if ( aGroup[ i ].mbExpand ) + gSize += nExtraSize[ g ]; + if ( g == 0 ) + rChildArea.Width += gSize; + else + rChildArea.Height += gSize; + } + } + + allocateChildAt( child->mxChild, rChildArea ); + } +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/table.hxx b/toolkit/source/layout/core/table.hxx new file mode 100644 index 000000000000..5fa20d2412dc --- /dev/null +++ b/toolkit/source/layout/core/table.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_TABLE_HXX +#define LAYOUT_CORE_TABLE_HXX + +#include <layout/core/box-base.hxx> + +namespace layoutimpl +{ + +class Table : public Box_Base +{ +public: + // Children properties + struct ChildData : public Box_Base::ChildData + { + sal_Bool mbExpand[ 2 ]; + sal_Int32 mnColSpan; + sal_Int32 mnRowSpan; + int mnLeftCol; + int mnRightCol; + int mnTopRow; + int mnBottomRow; + + ChildData( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ); + bool isVisible(); + }; + + struct ChildProps : public Box_Base::ChildProps + { + ChildProps( ChildData *pData ); + }; + +protected: + + // a group of children; either a column or a row + struct GroupData + { + sal_Bool mbExpand; + int mnSize; // request size (width or height) + GroupData() : mbExpand( false ), mnSize( 0 ) {} + }; + + // Table properties + sal_Int32 mnColsLen; + std::vector< GroupData > maCols; + std::vector< GroupData > maRows; + int mnColExpandables, mnRowExpandables; + + ChildData *createChild( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ); + ChildProps *createChildProps( Box_Base::ChildData* pData ); + +public: + Table(); + + // css::awt::XLayoutContainer + virtual void SAL_CALL addChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child ) + throw (css::uno::RuntimeException, css::awt::MaxChildrenException); + + virtual void SAL_CALL allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException); + + virtual css::awt::Size SAL_CALL getMinimumSize() + throw(css::uno::RuntimeException); + + // unimplemented: + virtual sal_Bool SAL_CALL hasHeightForWidth() + throw(css::uno::RuntimeException) + { return false; } + virtual sal_Int32 SAL_CALL getHeightForWidth( sal_Int32 /*nWidth*/ ) + throw(css::uno::RuntimeException) + { return maRequisition.Height; } +}; + +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_TABLE_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/timer.cxx b/toolkit/source/layout/core/timer.cxx new file mode 100644 index 000000000000..1749a9af91d6 --- /dev/null +++ b/toolkit/source/layout/core/timer.cxx @@ -0,0 +1,151 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/timer.hxx b/toolkit/source/layout/core/timer.hxx new file mode 100644 index 000000000000..5c6408985500 --- /dev/null +++ b/toolkit/source/layout/core/timer.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_TIMER_HXX +#define LAYOUT_CORE_TIMER_HXX + +#include <com/sun/star/awt/XLayoutUnit.hpp> +#include <cppuhelper/implbase1.hxx> + +namespace layoutimpl +{ + +typedef ::cppu::WeakImplHelper1< com::sun::star::awt::XLayoutUnit > LayoutUnit_Base; + +class LayoutUnit : public LayoutUnit_Base +{ +public: + LayoutUnit(); + void SAL_CALL queueResize( const com::sun::star::uno::Reference< com::sun::star::awt::XLayoutContainer > &xContainer ) + throw( com::sun::star::uno::RuntimeException ); +}; + +} + +#endif /* LAYOUT_CORE_TIMER_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/translate.cxx b/toolkit/source/layout/core/translate.cxx new file mode 100644 index 000000000000..916ecbf18d9b --- /dev/null +++ b/toolkit/source/layout/core/translate.cxx @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "translate.hxx" + +#include <list> +#if TEST_LAYOUT +#include <cstdio> +#include "tools/getprocessworkingdir.hxx" +#endif + +#include <unotools/bootstrap.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/ucbhelper.hxx> +#include <vcl/svapp.hxx> + +#include "proplist.hxx" + +namespace layoutimpl +{ +namespace css = ::com::sun::star; +using namespace css; +using ::rtl::OUString; +using ::utl::LocalFileHelper; +using ::utl::UCBContentHelper; +using ::utl::Bootstrap; + +static std::list<OUString> +getLocaleSubdirList( lang::Locale const& rLocale ) +{ + std::list<OUString> aSubdirs; + aSubdirs.push_front( OUString::createFromAscii( "." ) ); + aSubdirs.push_front( OUString::createFromAscii( "en-US" ) ); + if ( rLocale.Language.getLength() ) + aSubdirs.push_front( rLocale.Language ); + if ( rLocale.Country.getLength() ) + { + OUString aLocaleCountry = rLocale.Language + + OUString::createFromAscii( "-" ) + + rLocale.Country; + aSubdirs.push_front( aLocaleCountry ); + if ( rLocale.Variant.getLength() ) + aSubdirs.push_front( aLocaleCountry + + OUString::createFromAscii( "." ) + + rLocale.Variant ); + } + return aSubdirs; +} + +static bool +fileExists( String const& aFile ) +{ + String aUrl; + LocalFileHelper::ConvertPhysicalNameToURL( aFile, aUrl ); + return UCBContentHelper::Exists( aUrl ); +} + +static OUString +getFirstExisting( OUString const& aDir, std::list<OUString> const& aSubDirs, + OUString const& aXMLName ) +{ + static OUString const aSlash = OUString::createFromAscii( "/" ); + String aResult; + for ( std::list<OUString>::const_iterator i = aSubDirs.begin(); + i != aSubDirs.end(); i++ ) + { + String aFile = aDir + aSlash + *i + aSlash + aXMLName; + OSL_TRACE( "testing: %s", OUSTRING_CSTR( aFile ) ); + if ( fileExists( aFile ) ) + return aFile; + } + return OUString(); +} + +/* FIXME: IWBN to share code with impimagetree.cxx, also for reading + from zip files. */ +OUString +readRightTranslation( OUString const& aXMLName ) +{ + String aXMLFile; + std::list<OUString> aSubdirs + = getLocaleSubdirList( Application::GetSettings().GetUILocale() ); +#if TEST_LAYOUT // read from cwd first + OUString aCurrentWorkingUrl; + tools::getProcessWorkingDir( &aCurrentWorkingUrl ); + String aCurrentWorkingDir; + LocalFileHelper::ConvertURLToPhysicalName( aCurrentWorkingUrl, aCurrentWorkingDir ); + aXMLFile = getFirstExisting( aCurrentWorkingDir, aSubdirs, aXMLName ); + if ( aXMLFile.Len() ) + ; + else +#endif /* TEST_LAYOUT */ + { + OUString aShareUrl; + Bootstrap::locateSharedData( aShareUrl ); + OUString aXMLUrl = aShareUrl + OUString::createFromAscii( "/layout" ); + String aXMLDir; + LocalFileHelper::ConvertURLToPhysicalName( aXMLUrl, aXMLDir ); + aXMLFile = getFirstExisting( aXMLDir, aSubdirs, aXMLName ); + } + + OSL_TRACE( "FOUND:%s", OUSTRING_CSTR ( OUString (aXMLFile) ) ); + return aXMLFile; +} + +} // namespace layoutimpl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/translate.hxx b/toolkit/source/layout/core/translate.hxx new file mode 100644 index 000000000000..251958ff92c0 --- /dev/null +++ b/toolkit/source/layout/core/translate.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_TRANSLATE_HXX +#define LAYOUT_CORE_TRANSLATE_HXX + +namespace rtl { +class OUString; +} // namespace rtl + +namespace layoutimpl +{ +::rtl::OUString readRightTranslation( ::rtl::OUString const& aXMLName ); +} // namespace layoutimpl + +#endif /* LAYOUT_CORE_TRANSLATE_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/vcl.cxx b/toolkit/source/layout/core/vcl.cxx new file mode 100644 index 000000000000..53dae2563d73 --- /dev/null +++ b/toolkit/source/layout/core/vcl.cxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <vcl.hxx> + +#include <sal/types.h> +#include <vcl/button.hxx> + +static PushButton* get_button (Dialog const* dialog, sal_uInt32 type) +{ + Window* child = dialog->GetWindow (WINDOW_FIRSTCHILD); + while (child) + { + if (child->GetType () == type) + return static_cast <PushButton*> (child); + child = child->GetWindow (WINDOW_NEXT); + } + + return 0; +} + +#define IMPLEMENT_CLOSING_DIALOG(cls)\ + Closing##cls::Closing##cls (Window* parent, WinBits bits)\ + : cls (parent, bits)\ + , mClosing (false)\ + {\ + }\ + BOOL Closing##cls::Close ()\ + {\ + if (mClosing)\ + EndDialog (false);\ + else if (PushButton *cancel = get_button (this, WINDOW_CANCELBUTTON))\ + cancel->Click ();\ + else if (PushButton *ok = get_button (this, WINDOW_OKBUTTON))\ + ok->Click ();\ + mClosing = true;\ + return false;\ + } + +IMPLEMENT_CLOSING_DIALOG (Dialog); +IMPLEMENT_CLOSING_DIALOG (ModelessDialog); +IMPLEMENT_CLOSING_DIALOG (ModalDialog); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/source/layout/core/vcl.hxx b/toolkit/source/layout/core/vcl.hxx new file mode 100644 index 000000000000..d7fb5a4ffeb4 --- /dev/null +++ b/toolkit/source/layout/core/vcl.hxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef LAYOUT_CORE_VCL_HXX +#define LAYOUT_CORE_VCL_HXX + +#include <vcl/dialog.hxx> + +#define DECLARE_CLOSING_DIALOG(cls)\ + class Closing##cls : public cls\ + {\ + public:\ + bool mClosing;\ + Closing##cls (Window* parent, WinBits bits);\ + virtual BOOL Close ();\ + } + +DECLARE_CLOSING_DIALOG (Dialog); +DECLARE_CLOSING_DIALOG (ModalDialog); +DECLARE_CLOSING_DIALOG (ModelessDialog); + +#undef DECLARE_CLOSING_DIALOG + +#endif /* LAYOUT_CORE_VCL_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |