diff options
Diffstat (limited to 'toolkit/source/controls')
33 files changed, 17388 insertions, 0 deletions
diff --git a/toolkit/source/controls/accessiblecontrolcontext.cxx b/toolkit/source/controls/accessiblecontrolcontext.cxx new file mode 100644 index 000000000000..96bf73bacd7a --- /dev/null +++ b/toolkit/source/controls/accessiblecontrolcontext.cxx @@ -0,0 +1,383 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: accessiblecontrolcontext.cxx,v $ + * $Revision: 1.10 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <toolkit/controls/accessiblecontrolcontext.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <vcl/svapp.hxx> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/window.hxx> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using ::comphelper::OContextEntryGuard; + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::accessibility; + + //==================================================================== + //= OAccessibleControlContext + //==================================================================== + //-------------------------------------------------------------------- + OAccessibleControlContext::OAccessibleControlContext() + :OAccessibleControlContext_Base( ) + { + // nothing to do here, we have a late ctor + } + + //-------------------------------------------------------------------- + OAccessibleControlContext::~OAccessibleControlContext() + { + ensureDisposed(); + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE3( OAccessibleControlContext, OAccessibleControlContext_Base, OAccessibleImplementationAccess, OAccessibleControlContext_IBase ) + IMPLEMENT_FORWARD_XTYPEPROVIDER3( OAccessibleControlContext, OAccessibleControlContext_Base, OAccessibleImplementationAccess, OAccessibleControlContext_IBase ) + // (order matters: the first is the class name, the second is the class doing the ref counting) + + //-------------------------------------------------------------------- + void OAccessibleControlContext::Init( const Reference< XAccessible >& _rxCreator ) SAL_THROW( ( Exception ) ) + { + OContextEntryGuard aGuard( this ); + + // retrieve the model of the control + OSL_ENSURE( !m_xControlModel.is(), "OAccessibleControlContext::Init: already know a control model....!???" ); + + Reference< awt::XControl > xControl( _rxCreator, UNO_QUERY ); + if ( xControl.is() ) + m_xControlModel = m_xControlModel.query( xControl->getModel() ); + OSL_ENSURE( m_xControlModel.is(), "OAccessibleControlContext::Init: invalid creator (no control, or control without model!" ); + if ( !m_xControlModel.is() ) + throw DisposedException(); // caught by the caller (the create method) + + // start listening at the model + startModelListening(); + + // announce the XAccessible to our base class + OAccessibleControlContext_Base::lateInit( _rxCreator ); + } + + //-------------------------------------------------------------------- + OAccessibleControlContext* OAccessibleControlContext::create( const Reference< XAccessible >& _rxCreator ) SAL_THROW( ( ) ) + { + OAccessibleControlContext* pNew = NULL; + try + { + pNew = new OAccessibleControlContext; + pNew->Init( _rxCreator ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "OAccessibleControlContext::create: caught an exception from the late ctor!" ); + } + return pNew; + } + + //-------------------------------------------------------------------- + void OAccessibleControlContext::startModelListening( ) SAL_THROW( ( Exception ) ) + { + Reference< XComponent > xModelComp( m_xControlModel, UNO_QUERY ); + OSL_ENSURE( xModelComp.is(), "OAccessibleControlContext::startModelListening: invalid model!" ); + if ( xModelComp.is() ) + xModelComp->addEventListener( this ); + } + + //-------------------------------------------------------------------- + void OAccessibleControlContext::stopModelListening( ) SAL_THROW( ( Exception ) ) + { + Reference< XComponent > xModelComp( m_xControlModel, UNO_QUERY ); + OSL_ENSURE( xModelComp.is(), "OAccessibleControlContext::stopModelListening: invalid model!" ); + if ( xModelComp.is() ) + xModelComp->removeEventListener( this ); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleControlContext::getAccessibleChildCount( ) throw (RuntimeException) + { + // we do not have children + return 0; + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException) + { + // we do not have children + throw IndexOutOfBoundsException(); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleParent( ) throw (RuntimeException) + { + OContextEntryGuard aGuard( this ); + OSL_ENSURE( implGetForeignControlledParent().is(), "OAccessibleControlContext::getAccessibleParent: somebody forgot to set a parent!" ); + // this parent of us is foreign controlled - somebody has to set it using the OAccessibleImplementationAccess + // class, before integrating our instance into an AccessibleDocumentModel + return implGetForeignControlledParent(); + } + + //-------------------------------------------------------------------- + sal_Int16 SAL_CALL OAccessibleControlContext::getAccessibleRole( ) throw (RuntimeException) + { + return AccessibleRole::SHAPE; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OAccessibleControlContext::getAccessibleDescription( ) throw (RuntimeException) + { + OContextEntryGuard aGuard( this ); + return getModelStringProperty( "HelpText" ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OAccessibleControlContext::getAccessibleName( ) throw (RuntimeException) + { + OContextEntryGuard aGuard( this ); + return getModelStringProperty( "Name" ); + } + + //-------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL OAccessibleControlContext::getAccessibleRelationSet( ) throw (RuntimeException) + { + return NULL; + } + + //-------------------------------------------------------------------- + Reference< XAccessibleStateSet > SAL_CALL OAccessibleControlContext::getAccessibleStateSet( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + // no OContextEntryGuard here, as we do not want to throw an exception in case we're not alive anymore + + ::utl::AccessibleStateSetHelper* pStateSet = NULL; + if ( isAlive() ) + { + // no own states, only the ones which are foreign controlled + pStateSet = new ::utl::AccessibleStateSetHelper( implGetForeignControlledStates() ); + } + else + { // only the DEFUNC state if we're already disposed + pStateSet = new ::utl::AccessibleStateSetHelper; + pStateSet->AddState( AccessibleStateType::DEFUNC ); + } + return pStateSet; + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleControlContext::disposing( const EventObject& + #if OSL_DEBUG_LEVEL > 0 + _rSource + #endif + ) throw ( RuntimeException ) + { + OSL_ENSURE( Reference< XPropertySet >( _rSource.Source, UNO_QUERY ).get() == m_xControlModel.get(), + "OAccessibleControlContext::disposing: where did this come from?" ); + + stopModelListening( ); + m_xControlModel.clear(); + m_xModelPropsInfo.clear(); + + OAccessibleControlContext_Base::disposing(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString OAccessibleControlContext::getModelStringProperty( const sal_Char* _pPropertyName ) + { + ::rtl::OUString sReturn; + try + { + if ( !m_xModelPropsInfo.is() && m_xControlModel.is() ) + m_xModelPropsInfo = m_xControlModel->getPropertySetInfo(); + + ::rtl::OUString sPropertyName( ::rtl::OUString::createFromAscii( _pPropertyName ) ); + if ( m_xModelPropsInfo.is() && m_xModelPropsInfo->hasPropertyByName( sPropertyName ) ) + m_xControlModel->getPropertyValue( sPropertyName ) >>= sReturn; + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "OAccessibleControlContext::getModelStringProperty: caught an exception!" ); + } + return sReturn; + } + + //-------------------------------------------------------------------- + Window* OAccessibleControlContext::implGetWindow( Reference< awt::XWindow >* _pxUNOWindow ) const + { + Reference< awt::XControl > xControl( getAccessibleCreator(), UNO_QUERY ); + Reference< awt::XWindow > xWindow; + if ( xControl.is() ) + xWindow = xWindow.query( xControl->getPeer() ); + + Window* pWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) : NULL; + + if ( _pxUNOWindow ) + *_pxUNOWindow = xWindow; + return pWindow; + } + + //-------------------------------------------------------------------- + awt::Rectangle SAL_CALL OAccessibleControlContext::implGetBounds( ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // want to do some VCL stuff here ... + OContextEntryGuard aGuard( this ); + + OSL_ENSURE( sal_False, "OAccessibleControlContext::implGetBounds: performance issue: forced to calc the size myself!" ); + // In design mode (and this is what this class is for), the surrounding shape (if any) should handle this call + // The problem is that in design mode, our size may not be correct (in the drawing layer, controls are + // positioned/sized for painting only), and that calculation of our position is expensive + + // what we know (or can obtain from somewhere): + // * the PosSize of our peer, relative to it's parent window + // * the parent window which the PosSize is relative to + // * our foreign controlled accessible parent + // from this info, we can determine the the position of our peer relative to the foreign parent + + // our control + Reference< awt::XWindow > xWindow; + Window* pVCLWindow = implGetWindow( &xWindow ); + + awt::Rectangle aBounds( 0, 0, 0, 0 ); + if ( xWindow.is() ) + { + // ugly, but .... though the XWindow has a getPosSize, it is impossible to determine the + // parent which this position/size is relative to. This means we must tunnel UNO and ask the + // implementation + Window* pVCLParent = pVCLWindow ? pVCLWindow->GetParent() : NULL; + + // the relative location of the window + ::Point aWindowRelativePos( 0, 0); + if ( pVCLWindow ) + aWindowRelativePos = pVCLWindow->GetPosPixel(); + + // the screnn position of the "window parent" of the control + ::Point aVCLParentScreenPos( 0, 0 ); + if ( pVCLParent ) + aVCLParentScreenPos = pVCLParent->GetPosPixel(); + + // the screen position of the "accessible parent" of the control + Reference< XAccessible > xParentAcc( implGetForeignControlledParent() ); + Reference< XAccessibleComponent > xParentAccComponent; + if ( xParentAcc.is() ) + xParentAccComponent = xParentAccComponent.query( xParentAcc->getAccessibleContext() ); + awt::Point aAccParentScreenPos( 0, 0 ); + if ( xParentAccComponent.is() ) + aAccParentScreenPos = xParentAccComponent->getLocationOnScreen(); + + // now the size of the control + aBounds = xWindow->getPosSize(); + + // correct the pos + aBounds.X = aWindowRelativePos.X() + aVCLParentScreenPos.X() - aAccParentScreenPos.X; + aBounds.Y = aWindowRelativePos.Y() + aVCLParentScreenPos.Y() - aAccParentScreenPos.Y; + } + + return aBounds; + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleAtPoint( const awt::Point& /* _rPoint */ ) throw (RuntimeException) + { + // no children at all + return NULL; + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleControlContext::grabFocus( ) throw (RuntimeException) + { + OSL_ENSURE( sal_False, "OAccessibleControlContext::grabFocus: !isFocusTraversable, but grabFocus!" ); + } + + //-------------------------------------------------------------------- + Any SAL_CALL OAccessibleControlContext::getAccessibleKeyBinding( ) throw (RuntimeException) + { + // we do not have any key bindings to activate a UNO control in design mode + return Any(); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleControlContext::getForeground( ) throw (::com::sun::star::uno::RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // want to do some VCL stuff here ... + OContextEntryGuard aGuard( this ); + + Window* pWindow = implGetWindow( ); + sal_Int32 nColor = 0; + if ( pWindow ) + { + if ( pWindow->IsControlForeground() ) + nColor = pWindow->GetControlForeground().GetColor(); + else + { + Font aFont; + if ( pWindow->IsControlFont() ) + aFont = pWindow->GetControlFont(); + else + aFont = pWindow->GetFont(); + nColor = aFont.GetColor().GetColor(); + } + } + return nColor; + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleControlContext::getBackground( ) throw (::com::sun::star::uno::RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // want to do some VCL stuff here ... + OContextEntryGuard aGuard( this ); + + Window* pWindow = implGetWindow( ); + sal_Int32 nColor = 0; + if ( pWindow ) + { + if ( pWindow->IsControlBackground() ) + nColor = pWindow->GetControlBackground().GetColor(); + else + nColor = pWindow->GetBackground().GetColor().GetColor(); + } + + return nColor; + } + +//........................................................................ +} //namespace toolkit +//........................................................................ + diff --git a/toolkit/source/controls/dialogcontrol.cxx b/toolkit/source/controls/dialogcontrol.cxx new file mode 100644 index 000000000000..07d459a6111a --- /dev/null +++ b/toolkit/source/controls/dialogcontrol.cxx @@ -0,0 +1,2107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dialogcontrol.cxx,v $ + * $Revision: 1.27 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/wall.hxx> +#include <vos/mutex.hxx> +#include <toolkit/controls/dialogcontrol.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/unopropertyarrayhelper.hxx> +#include <toolkit/controls/geometrycontrolmodel.hxx> +#include <toolkit/controls/unocontrols.hxx> +#include "toolkit/controls/formattedcontrol.hxx" +#include "toolkit/controls/roadmapcontrol.hxx" +#ifndef TOOLKIT_INC_TOOLKIT_CONTROLS_TKSCROLLBAR_HXX +#include "toolkit/controls/tkscrollbar.hxx" +#endif +#include <toolkit/controls/stdtabcontroller.hxx> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/resource/XStringResourceResolver.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <tools/list.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <comphelper/processfactory.hxx> +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <comphelper/types.hxx> + +#include <comphelper/componentcontext.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <vcl/graph.hxx> +#include <vcl/image.hxx> + +#include "tree/treecontrol.hxx" +#include "grid/gridcontrol.hxx" + +#include <map> +#include <algorithm> +#include <functional> +#include "tools/urlobj.hxx" +#include "osl/file.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::util; +using namespace toolkit; + +#define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" )) +#define PROPERTY_DIALOGSOURCEURL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogSourceURL" )) +#define PROPERTY_IMAGEURL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImageURL" )) +#define PROPERTY_GRAPHIC ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" )) + +//HELPER +::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl ); + +struct LanguageDependentProp +{ + const char* pPropName; + sal_Int32 nPropNameLength; +}; + +// ---------------------------------------------------------------------------- +namespace +{ + static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties() + { + static Sequence< ::rtl::OUString > s_aLanguageDependentProperties; + if ( s_aLanguageDependentProperties.getLength() == 0 ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( s_aLanguageDependentProperties.getLength() == 0 ) + { + s_aLanguageDependentProperties.realloc( 2 ); + s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) ); + s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); + // note: properties must be sorted + } + } + return s_aLanguageDependentProperties; + } + + static uno::Reference< graphic::XGraphic > lcl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL ) + { + uno::Reference< graphic::XGraphic > xGraphic; + if ( !_rURL.getLength() ) + return xGraphic; + + try + { + ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); + uno::Reference< graphic::XGraphicProvider > xProvider; + if ( aContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) ) + { + uno::Sequence< beans::PropertyValue > aMediaProperties(1); + aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aMediaProperties[0].Value <<= _rURL; + xGraphic = xProvider->queryGraphic( aMediaProperties ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return xGraphic; + } + +} + +// ---------------------------------------------------------------------------- +// functor for disposing a control model +struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void > +{ + void operator()( Reference< XControlModel >& _rxModel ) + { + try + { + ::comphelper::disposeComponent( _rxModel ); + } + catch( const Exception& ) + { + DBG_ERROR( "DisposeControlModel::(): caught an exception while disposing a component!" ); + } + } +}; + +// ---------------------------------------------------------------------------- +// functor for searching control model by name +struct FindControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, bool > +{ +private: + const ::rtl::OUString& m_rName; + +public: + FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { } + + bool operator()( const UnoControlDialogModel::UnoControlModelHolder& _rCompare ) + { + return ( _rCompare.second == m_rName ) ? true : false; + } +}; + +// ---------------------------------------------------------------------------- +// functor for cloning a control model, and insertion into a target list +struct CloneControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, void > +{ +private: + UnoControlDialogModel::UnoControlModelHolderList& m_rTargetList; + +public: + CloneControlModel( UnoControlDialogModel::UnoControlModelHolderList& _rTargetList ) + :m_rTargetList( _rTargetList ) + { + } + + void operator()( const UnoControlDialogModel::UnoControlModelHolder& _rSource ) + { + // clone the source object + Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY ); + Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY ); + // add to target list + m_rTargetList.push_back( UnoControlDialogModel::UnoControlModelHolder( xClone, _rSource.second ) ); + } +}; + +// ---------------------------------------------------------------------------- +// functor for comparing a XControlModel with a given reference +struct CompareControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, bool > +{ +private: + Reference< XControlModel > m_xReference; +public: + CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { } + + bool operator()( const UnoControlDialogModel::UnoControlModelHolder& _rCompare ) + { + return ( _rCompare.first.get() == m_xReference.get() ) ? true : false; + } +}; + +// ---------------------------------------------------------------------------- +static void lcl_throwIllegalArgumentException( ) +{ // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... + throw IllegalArgumentException(); +} + +// ---------------------------------------------------------------------------- +static void lcl_throwNoSuchElementException( ) +{ // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... + throw NoSuchElementException(); +} + +// ---------------------------------------------------------------------------- +static void lcl_throwElementExistException( ) +{ // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... + throw ElementExistException(); +} + +// ---------------------------------------------------------------------------- +static const ::rtl::OUString& getTabIndexPropertyName( ) +{ + static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) ); + return s_sTabIndexProperty; +} + +// ---------------------------------------------------------------------------- +static const ::rtl::OUString& getStepPropertyName( ) +{ + static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); + return s_sStepProperty; +} + +// ---------------------------------------------------- +// class UnoControlDialogModel +// ---------------------------------------------------- +UnoControlDialogModel::UnoControlDialogModel() + :maContainerListeners( *this ) + ,maChangeListeners ( GetMutex() ) + ,mbGroupsUpToDate( sal_False ) +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); +// ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); +// ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_TITLE ); + ImplRegisterProperty( BASEPROPERTY_SIZEABLE ); + ImplRegisterProperty( BASEPROPERTY_DESKTOP_AS_PARENT ); + ImplRegisterProperty( BASEPROPERTY_DECORATION ); + ImplRegisterProperty( BASEPROPERTY_DIALOGSOURCEURL ); + ImplRegisterProperty( BASEPROPERTY_GRAPHIC ); + ImplRegisterProperty( BASEPROPERTY_IMAGEURL ); + + Any aBool; + aBool <<= (sal_Bool) sal_True; + ImplRegisterProperty( BASEPROPERTY_MOVEABLE, aBool ); + ImplRegisterProperty( BASEPROPERTY_CLOSEABLE, aBool ); +} + +UnoControlDialogModel::UnoControlDialogModel( const UnoControlDialogModel& rModel ) + : UnoControlDialogModel_IBase( rModel ) + , UnoControlDialogModel_Base( rModel ) + , maContainerListeners( *this ) + , maChangeListeners ( GetMutex() ) + , mbGroupsUpToDate( sal_False ) +{ +} + +UnoControlDialogModel::~UnoControlDialogModel() +{ + maModels.clear(); + mbGroupsUpToDate = sal_False; +} + +Any UnoControlDialogModel::queryAggregation( const Type & rType ) throw(RuntimeException) +{ + Any aRet( UnoControlDialogModel_IBase::queryInterface( rType ) ); + return (aRet.hasValue() ? aRet : UnoControlDialogModel_Base::queryAggregation( rType )); +} + +// XTypeProvider +IMPL_IMPLEMENTATION_ID( UnoControlDialogModel ) +Sequence< Type > UnoControlDialogModel::getTypes() throw(RuntimeException) +{ + return ::comphelper::concatSequences( + UnoControlDialogModel_IBase::getTypes(), + UnoControlDialogModel_Base::getTypes() + ); +} + +::rtl::OUString UnoControlDialogModel::getServiceName( ) throw(RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialogModel ); +} + +Any UnoControlDialogModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + Any aAny; + + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog ); + break; + default: + aAny = UnoControlModel::ImplGetDefaultValue( nPropId ); + } + + return aAny; +} + +::cppu::IPropertyArrayHelper& UnoControlDialogModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +void SAL_CALL UnoControlDialogModel::dispose( ) throw(RuntimeException) +{ + // ==================================================================== + // tell our listeners + { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + EventObject aDisposeEvent; + aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) ); + + maContainerListeners.disposeAndClear( aDisposeEvent ); + maChangeListeners.disposeAndClear( aDisposeEvent ); + } + + // ==================================================================== + // call the base class + UnoControlModel::dispose(); + + // ==================================================================== + // dispose our child models + // for this, collect the models (we collect them from maModels, and this is modified when disposing children) + ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() ); + + ::std::transform( + maModels.begin(), maModels.end(), // source range + aChildModels.begin(), // target location + ::std::select1st< UnoControlModelHolder >( ) // operation to apply -> select the XControlModel part + ); + + // now dispose + ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() ); + aChildModels.clear(); + + mbGroupsUpToDate = sal_False; +} + +// XMultiPropertySet +Reference< XPropertySetInfo > UnoControlDialogModel::getPropertySetInfo( ) throw(RuntimeException) +{ + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +UnoControlModel* UnoControlDialogModel::Clone() const +{ + // clone the container itself + UnoControlDialogModel* pClone = new UnoControlDialogModel( *this ); + + // clone all children + ::std::for_each( + maModels.begin(), maModels.end(), + CloneControlModel( pClone->maModels ) + ); + + return pClone; +} + +UnoControlDialogModel::UnoControlModelHolderList::iterator UnoControlDialogModel::ImplFindElement( const ::rtl::OUString& rName ) +{ + return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) ); +} + +// ::XMultiServiceFactory +Reference< XInterface > UnoControlDialogModel::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + OGeometryControlModel_Base* pNewModel = NULL; + + if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlEditModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlFileControlModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlButtonModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlImageControlModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlListBoxModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoTreeModel >; + else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 ) + pNewModel = new OGeometryControlModel< UnoGridModel >; + + if ( !pNewModel ) + { + Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); + if ( xORB.is() ) + { + Reference< XInterface > xObject = xORB->createInstance( aServiceSpecifier ); + Reference< XServiceInfo > xSI( xObject, UNO_QUERY ); + Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY ); + Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY ); + if ( xAgg.is() ) + { + if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) ) + { + // release 3 of the 4 references we have to the object + xAgg.clear(); + xSI.clear(); + xObject.clear(); + + pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier ); + } + } + } + } + + Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel; + return xNewModel; +} + +Reference< XInterface > UnoControlDialogModel::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /* Arguments */ ) throw(Exception, RuntimeException) +{ + return createInstance( ServiceSpecifier ); +} + +Sequence< ::rtl::OUString > UnoControlDialogModel::getAvailableServiceNames() throw(RuntimeException) +{ + static Sequence< ::rtl::OUString >* pNamesSeq = NULL; + if ( !pNamesSeq ) + { + pNamesSeq = new Sequence< ::rtl::OUString >( 21 ); + ::rtl::OUString* pNames = pNamesSeq->getArray(); + pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel ); + pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel ); + pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel ); + pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel ); + pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel ); + pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ); + pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel ); + pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel ); + pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel ); + pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel ); + pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel ); + pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel ); + pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel ); + pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel ); + pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel ); + pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel ); + pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel ); + pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel ); + pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel ); + pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel ); + pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel ); + pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel ); + + } + return *pNamesSeq; +} + +// XContainer +void UnoControlDialogModel::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) +{ + maContainerListeners.addInterface( l ); +} + +void UnoControlDialogModel::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) +{ + maContainerListeners.removeInterface( l ); +} + +// XElementAcces +Type UnoControlDialogModel::getElementType() throw(RuntimeException) +{ + Type aType = getCppuType( ( Reference< XControlModel>* ) NULL ); + return aType; +} + +sal_Bool UnoControlDialogModel::hasElements() throw(RuntimeException) +{ + return !maModels.empty(); +} + +// XNameContainer, XNameReplace, XNameAccess +void UnoControlDialogModel::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XControlModel > xNewModel; + aElement >>= xNewModel; + if ( !xNewModel.is() ) + lcl_throwIllegalArgumentException(); + + UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); + if ( maModels.end() == aElementPos ) + lcl_throwNoSuchElementException(); + + // stop listening at the old model + stopControlListening( aElementPos->first ); + Reference< XControlModel > xReplaced( aElementPos->first ); + // remember the new model, and start listening + aElementPos->first = xNewModel; + startControlListening( xNewModel ); + + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element = aElement; + aEvent.ReplacedElement <<= xReplaced; + aEvent.Accessor <<= aName; + + // notify the container listener + maContainerListeners.elementReplaced( aEvent ); + + // our "tab controller model" has potentially changed -> notify this + implNotifyTabModelChange( aName ); +} + +Any UnoControlDialogModel::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); + if ( maModels.end() == aElementPos ) + lcl_throwNoSuchElementException(); + + return makeAny( aElementPos->first ); +} + +Sequence< ::rtl::OUString > UnoControlDialogModel::getElementNames() throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aNames( maModels.size() ); + + ::std::transform( + maModels.begin(), maModels.end(), // source range + aNames.getArray(), // target range + ::std::select2nd< UnoControlModelHolder >() // operator to apply: select the second element (the name) + ); + + return aNames; +} + +sal_Bool UnoControlDialogModel::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) +{ + return maModels.end() != ImplFindElement( aName ); +} + +void UnoControlDialogModel::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XControlModel > xM; + aElement >>= xM; + + if ( xM.is() ) + { + Reference< beans::XPropertySet > xProps( xM, UNO_QUERY ); + if ( xProps.is() ) + { + + Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo(); + + ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL ); + if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty )) + { + Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty ); + + ::rtl::OUString absoluteUrl = + getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl ); + + aUrl <<= absoluteUrl; + + xProps.get()->setPropertyValue( sImageSourceProperty , aUrl ); + } + } + } + + + + if ( !aName.getLength() || !xM.is() ) + lcl_throwIllegalArgumentException(); + + UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); + if ( maModels.end() != aElementPos ) + lcl_throwElementExistException(); + + maModels.push_back( UnoControlModelHolder( xM, aName ) ); + mbGroupsUpToDate = sal_False; + startControlListening( xM ); + + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element <<= aElement; + aEvent.Accessor <<= aName; + maContainerListeners.elementInserted( aEvent ); + + // our "tab controller model" has potentially changed -> notify this + implNotifyTabModelChange( aName ); +} + +void UnoControlDialogModel::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); + if ( maModels.end() == aElementPos ) + lcl_throwNoSuchElementException(); + + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element <<= aElementPos->first; + aEvent.Accessor <<= aName; + maContainerListeners.elementRemoved( aEvent ); + + stopControlListening( aElementPos->first ); + Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY ); + maModels.erase( aElementPos ); + mbGroupsUpToDate = sal_False; + + if ( xPS.is() ) + try + { + xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) ); + } + catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } + + // our "tab controller model" has potentially changed -> notify this + implNotifyTabModelChange( aName ); +} + +// ---------------------------------------------------------------------------- +sal_Bool SAL_CALL UnoControlDialogModel::getGroupControl( ) throw (RuntimeException) +{ + return sal_True; +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::setGroupControl( sal_Bool ) throw (RuntimeException) +{ + DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" ); +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + // set the tab indexes according to the order of models in the sequence + const Reference< XControlModel >* pControls = _rControls.getConstArray( ); + const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength(); + + sal_Int16 nTabIndex = 1; + + for ( ; pControls != pControlsEnd; ++pControls ) + { + // look up the control in our own structure. This is to prevent invalid arguments + UnoControlModelHolderList::const_iterator aPos = + ::std::find_if( + maModels.begin(), maModels.end(), + CompareControlModel( *pControls ) + ); + if ( maModels.end() != aPos ) + { + // okay, this is an existent model + // now set the TabIndex property (if applicable) + Reference< XPropertySet > xProps( aPos->first, UNO_QUERY ); + Reference< XPropertySetInfo > xPSI; + if ( xProps.is() ) + xPSI = xProps->getPropertySetInfo(); + if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) + xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) ); + } + mbGroupsUpToDate = sal_False; + } +} + + +typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel; + +// ---------------------------------------------------------------------------- +Sequence< Reference< XControlModel > > SAL_CALL UnoControlDialogModel::getControlModels( ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + MapIndexToModel aSortedModels; + // will be the sorted container of all models which have a tab index property + ::std::vector< Reference< XControlModel > > aUnindexedModels; + // will be the container of all models which do not have a tab index property + + UnoControlModelHolderList::const_iterator aLoop = maModels.begin(); + for ( ; aLoop != maModels.end(); ++aLoop ) + { + Reference< XControlModel > xModel( aLoop->first ); + + // see if the model has a TabIndex property + Reference< XPropertySet > xControlProps( xModel, UNO_QUERY ); + Reference< XPropertySetInfo > xPSI; + if ( xControlProps.is() ) + xPSI = xControlProps->getPropertySetInfo( ); + DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" ); + + // has it? + if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) + { // yes + sal_Int32 nTabIndex = -1; + xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex; + + aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) ); + } + else if ( xModel.is() ) + // no, it hasn't, but we have to include it, anyway + aUnindexedModels.push_back( xModel ); + } + + // okay, here we have a container of all our models, sorted by tab index, + // plus a container of "unindexed" models + // -> merge them + Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() ); + ::std::transform( + aSortedModels.begin(), aSortedModels.end(), + ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ), + ::std::select2nd< MapIndexToModel::value_type >( ) + ); + + return aReturn; +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException) +{ + // not supported. We have only implicit grouping: + // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on + // implementation details) that VCL does grouping according to the order of controls automatically + // At least VCL does this for all we're interested in: Radio buttons. + DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" ); +} + +// ---------------------------------------------------------------------------- +namespace +{ + enum GroupingMachineState + { + eLookingForGroup, + eExpandingGroup + }; + + // ........................................................................ + static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel ) + { + sal_Int32 nStep = 0; + try + { + Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY ); + xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep; + } + catch( const Exception& ) + { + DBG_ERROR( "lcl_getDialogStep: caught an exception while determining the dialog page!" ); + } + return nStep; + } +} + +// ---------------------------------------------------------------------------- +sal_Int32 SAL_CALL UnoControlDialogModel::getGroupCount( ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + implUpdateGroupStructure(); + + return maGroups.size(); +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + implUpdateGroupStructure(); + + if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) ) + { + DBG_ERROR( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" ); + _rGroup.realloc( 0 ); + _rName = ::rtl::OUString(); + } + else + { + AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup; + _rGroup.realloc( aGroupPos->size() ); + // copy the models + ::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() ); + // give the group a name + _rName = ::rtl::OUString::valueOf( _nGroup ); + } +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + ::rtl::OUString sDummyName; + getGroup( _rName.toInt32( ), _rGroup, sDummyName ); +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) +{ + maChangeListeners.addInterface( _rxListener ); +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) +{ + maChangeListeners.removeInterface( _rxListener ); +} + +// ---------------------------------------------------------------------------- +void UnoControlDialogModel::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor ) +{ + // multiplex to our change listeners: + // the changes event + ChangesEvent aEvent; + aEvent.Source = *this; + aEvent.Base <<= aEvent.Source; // the "base of the changes root" is also ourself + aEvent.Changes.realloc( 1 ); // exactly one change + aEvent.Changes[ 0 ].Accessor <<= _rAccessor; + + + Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() ); + const Reference< XInterface >* pListener = aChangeListeners.getConstArray(); + const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength(); + for ( ; pListener != pListenerEnd; ++pListener ) + { + if ( pListener->is() ) + static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent ); + } +} + + +// ---------------------------------------------------------------------------- +void UnoControlDialogModel::implUpdateGroupStructure() +{ + if ( mbGroupsUpToDate ) + // nothing to do + return; + + // conditions for a group: + // * all elements of the group are radio buttons + // * all elements of the group are on the same dialog page + // * in the overall control order (determined by the tab index), all elements are subsequent + + maGroups.clear(); + + Sequence< Reference< XControlModel > > aControlModels = getControlModels(); + const Reference< XControlModel >* pControlModels = aControlModels.getConstArray(); + const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength(); + + // in extreme we have as much groups as controls + maGroups.reserve( aControlModels.getLength() ); + + GroupingMachineState eState = eLookingForGroup; // the current state of our machine + Reference< XServiceInfo > xModelSI; // for checking for a radion button + AllGroups::iterator aCurrentGroup = maGroups.end(); // the group which we're currently building + sal_Int32 nCurrentGroupStep = -1; // the step which all controls of the current group belong to + sal_Bool bIsRadioButton; // is it a radio button? + +#if OSL_DEBUG_LEVEL > 1 + ::std::vector< ::rtl::OUString > aCurrentGroupLabels; +#endif + + for ( ; pControlModels != pControlModelsEnd; ++pControlModels ) + { + // we'll need this in every state + xModelSI = xModelSI.query( *pControlModels ); + bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) ); + + switch ( eState ) + { + case eLookingForGroup: + { + if ( !bIsRadioButton ) + // this is no radio button -> still looking for the beginning of a group + continue; + // the current model is a radio button + // -> we found the beginning of a new group + // create the place for this group + size_t nGroups = maGroups.size(); + maGroups.resize( nGroups + 1 ); + aCurrentGroup = maGroups.begin() + nGroups; + // and add the (only, til now) member + aCurrentGroup->push_back( *pControlModels ); + + // get the step which all controls of this group now have to belong to + nCurrentGroupStep = lcl_getDialogStep( *pControlModels ); + // new state: looking for further members + eState = eExpandingGroup; + +#if OSL_DEBUG_LEVEL > 1 + Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY ); + ::rtl::OUString sLabel; + if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) ) + xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel; + aCurrentGroupLabels.push_back( sLabel ); +#endif + } + break; + + case eExpandingGroup: + { + if ( !bIsRadioButton ) + { // no radio button -> the group is done + aCurrentGroup = maGroups.end(); + eState = eLookingForGroup; +#if OSL_DEBUG_LEVEL > 1 + aCurrentGroupLabels.clear(); +#endif + continue; + } + + // it is a radio button - is it on the proper page? + const sal_Int32 nThisModelStep = lcl_getDialogStep( *pControlModels ); + if ( ( nThisModelStep == nCurrentGroupStep ) // the current button is on the same dialog page + || ( 0 == nThisModelStep ) // the current button appears on all pages + ) + { + // -> it belongs to the same group + aCurrentGroup->push_back( *pControlModels ); + // state still is eExpandingGroup - we're looking for further elements + eState = eExpandingGroup; + +#if OSL_DEBUG_LEVEL > 1 + Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY ); + ::rtl::OUString sLabel; + if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) ) + xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel; + aCurrentGroupLabels.push_back( sLabel ); +#endif + continue; + } + + // it's a radio button, but on a different page + // -> we open a new group for it + + // close the old group + aCurrentGroup = maGroups.end(); +#if OSL_DEBUG_LEVEL > 1 + aCurrentGroupLabels.clear(); +#endif + + // open a new group + size_t nGroups = maGroups.size(); + maGroups.resize( nGroups + 1 ); + aCurrentGroup = maGroups.begin() + nGroups; + // and add the (only, til now) member + aCurrentGroup->push_back( *pControlModels ); + + nCurrentGroupStep = nThisModelStep; + + // state is the same: we still are looking for further elements of the current group + eState = eExpandingGroup; +#if OSL_DEBUG_LEVEL > 1 + Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY ); + ::rtl::OUString sLabel; + if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) ) + xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel; + aCurrentGroupLabels.push_back( sLabel ); +#endif + } + break; + } + } + + mbGroupsUpToDate = sal_True; +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ), + "UnoControlDialogModel::propertyChange: not listening for this property!" ); + + // the accessor for the changed element + ::rtl::OUString sAccessor; + UnoControlModelHolderList::const_iterator aPos = + ::std::find_if( + maModels.begin(), maModels.end(), + CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) ) + ); + OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" ); + if ( maModels.end() != aPos ) + sAccessor = aPos->second; + + // our groups are not up-to-date + mbGroupsUpToDate = sal_False; + + // notify + implNotifyTabModelChange( sAccessor ); +} + +// ---------------------------------------------------------------------------- +void SAL_CALL UnoControlDialogModel::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException) +{ +} + +// ---------------------------------------------------------------------------- +void UnoControlDialogModel::startControlListening( const Reference< XControlModel >& _rxChildModel ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY ); + Reference< XPropertySetInfo > xPSI; + if ( xModelProps.is() ) + xPSI = xModelProps->getPropertySetInfo(); + + if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) + xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this ); +} + +// ---------------------------------------------------------------------------- +void UnoControlDialogModel::stopControlListening( const Reference< XControlModel >& _rxChildModel ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY ); + Reference< XPropertySetInfo > xPSI; + if ( xModelProps.is() ) + xPSI = xModelProps->getPropertySetInfo(); + + if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) + xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this ); +} + +// ============================================================================ +// = class ResourceListener +// ============================================================================ + +ResourceListener::ResourceListener( + const Reference< util::XModifyListener >& rListener ) : + OWeakObject(), + m_xListener( rListener ), + m_bListening( false ) +{ +} + +ResourceListener::~ResourceListener() +{ +} + +// XInterface +Any SAL_CALL ResourceListener::queryInterface( const Type& rType ) +throw ( RuntimeException ) +{ + Any a = ::cppu::queryInterface( + rType , + static_cast< XModifyListener* >( this ), + static_cast< XEventListener* >( this )); + + if ( a.hasValue() ) + return a; + + return OWeakObject::queryInterface( rType ); +} + +void SAL_CALL ResourceListener::acquire() throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL ResourceListener::release() throw () +{ + OWeakObject::release(); +} + +void ResourceListener::startListening( + const Reference< resource::XStringResourceResolver >& rResource ) +{ + Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY ); + + { + // --- SAFE --- + ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); + bool bListening( m_bListening ); + bool bResourceSet( m_xResource.is() ); + aGuard.clear(); + // --- SAFE --- + + if ( bListening && bResourceSet ) + stopListening(); + + // --- SAFE --- + aGuard.reset(); + m_xResource = rResource; + aGuard.clear(); + // --- SAFE --- + } + + Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY ); + if ( xModifyBroadcaster.is() ) + { + try + { + xModifyBroadcaster->addModifyListener( xThis ); + + // --- SAFE --- + ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); + m_bListening = true; + // --- SAFE --- + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } +} + +void ResourceListener::stopListening() +{ + Reference< util::XModifyBroadcaster > xModifyBroadcaster; + + // --- SAFE --- + ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); + if ( m_bListening && m_xResource.is() ) + xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY ); + aGuard.clear(); + // --- SAFE --- + + Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + if ( xModifyBroadcaster.is() ) + { + try + { + // --- SAFE --- + aGuard.reset(); + m_bListening = false; + m_xResource.clear(); + aGuard.clear(); + // --- SAFE --- + + xModifyBroadcaster->removeModifyListener( xThis ); + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } +} + +// XModifyListener +void SAL_CALL ResourceListener::modified( + const lang::EventObject& aEvent ) +throw ( RuntimeException ) +{ + Reference< util::XModifyListener > xListener; + + // --- SAFE --- + ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); + xListener = m_xListener; + aGuard.clear(); + // --- SAFE --- + + if ( xListener.is() ) + { + try + { + xListener->modified( aEvent ); + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } +} + +// XEventListener +void SAL_CALL ResourceListener::disposing( + const EventObject& Source ) +throw ( RuntimeException ) +{ + Reference< lang::XEventListener > xListener; + Reference< resource::XStringResourceResolver > xResource; + + // --- SAFE --- + ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); + Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY ); + Reference< XInterface > xIfacList( m_xListener, UNO_QUERY ); + aGuard.clear(); + // --- SAFE --- + + if ( Source.Source == xIfacRes ) + { + // --- SAFE --- + aGuard.reset(); + m_bListening = false; + xResource = m_xResource; + xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY ); + m_xResource.clear(); + aGuard.clear(); + // --- SAFE --- + + if ( xListener.is() ) + { + try + { + xListener->disposing( Source ); + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } + } + else if ( Source.Source == xIfacList ) + { + // --- SAFE --- + aGuard.reset(); + m_bListening = false; + xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY ); + xResource = m_xResource; + m_xResource.clear(); + m_xListener.clear(); + aGuard.clear(); + // --- SAFE --- + + // Remove ourself as listener from resource resolver + Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY ); + Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + if ( xModifyBroadcaster.is() ) + { + try + { + xModifyBroadcaster->removeModifyListener( xThis ); + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } + } +} + +// ============================================================================ +// = class UnoDialogControl +// ============================================================================ + +UnoDialogControl::UnoDialogControl() : + maTopWindowListeners( *this ), + mbWindowListener(false), + mbSizeModified(false), + mbPosModified(false) +{ + maComponentInfos.nWidth = 300; + maComponentInfos.nHeight = 450; + mxListener = new ResourceListener( Reference< util::XModifyListener >( + static_cast< OWeakObject* >( this ), UNO_QUERY )); +} + +::rtl::OUString UnoDialogControl::GetComponentServiceName() +{ + + sal_Bool bDecoration( sal_True ); + ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_DECORATION )) >>= bDecoration; + if ( bDecoration ) + return ::rtl::OUString::createFromAscii( "Dialog" ); + else + return ::rtl::OUString::createFromAscii( "TabPage" ); +} + +// XInterface +Any UnoDialogControl::queryAggregation( const Type & rType ) throw(RuntimeException) +{ + Any aRet( UnoDialogControl_IBase::queryInterface( rType ) ); + return (aRet.hasValue() ? aRet : UnoControlContainer::queryAggregation( rType )); +} + +// XTypeProvider +IMPL_IMPLEMENTATION_ID( UnoDialogControl ) +Sequence< Type > UnoDialogControl::getTypes() throw(RuntimeException) +{ + return ::comphelper::concatSequences( + UnoDialogControl_IBase::getTypes(), + UnoControlContainer::getTypes() + ); +} + +void UnoDialogControl::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName ) +{ + Reference< XPropertySet > xP( rxModel, UNO_QUERY ); + + ::rtl::OUString aDefCtrl; + xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl; + + // Add our own resource resolver to a newly created control + Reference< resource::XStringResourceResolver > xStringResourceResolver; + rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); + + Any aAny; + ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver; + + aAny <<= xStringResourceResolver; + xP->setPropertyValue( aPropName, aAny ); + + Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + Reference < XControl > xCtrl( xMSF->createInstance( aDefCtrl ), UNO_QUERY ); + + DBG_ASSERT( xCtrl.is(), "UnoDialogControl::ImplInsertControl: could not create the control!" ); + if ( xCtrl.is() ) + { + xCtrl->setModel( rxModel ); + addControl( rName, xCtrl ); + // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model + // (which we formerly did herein) + // 08.01.2001 - 96008 - fs@openoffice.org + + ImplSetPosSize( xCtrl ); + } +} + +void UnoDialogControl::ImplRemoveControl( Reference< XControlModel >& rxModel ) +{ + Sequence< Reference< XControl > > aControls = getControls(); + Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel ); + if ( xCtrl.is() ) + removeControl( xCtrl ); +} + +void UnoDialogControl::ImplSetPosSize( Reference< XControl >& rxCtrl ) +{ + Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY ); + + sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0; + xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX; + xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY; + xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth; + xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight; + + // Currentley we are simply using MAP_APPFONT + OutputDevice*pOutDev = Application::GetDefaultDevice(); + DBG_ASSERT( pOutDev, "Missing Default Device!" ); + if ( pOutDev ) + { + ::Size aTmp( nX, nY ); + aTmp = pOutDev->LogicToPixel( aTmp, MAP_APPFONT ); + nX = aTmp.Width(); + nY = aTmp.Height(); + aTmp = ::Size( nWidth, nHeight ); + aTmp = pOutDev->LogicToPixel( aTmp, MAP_APPFONT ); + nWidth = aTmp.Width(); + nHeight = aTmp.Height(); + } + else + { + Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True ); + Reference< XDevice > xD( xPeer, UNO_QUERY ); + + SimpleFontMetric aFM; + FontDescriptor aFD; + Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) ); + aVal >>= aFD; + if ( aFD.StyleName.getLength() ) + { + Reference< XFont > xFont = xD->getFont( aFD ); + aFM = xFont->getFontMetric(); + } + else + { + Reference< XGraphics > xG = xD->createGraphics(); + aFM = xG->getFontMetric(); + } + + sal_Int16 nH = aFM.Ascent + aFM.Descent; + sal_Int16 nW = nH/2; // calculate avarage width?! + + nX *= nW; + nX /= 4; + nWidth *= nW; + nWidth /= 4; + nY *= nH; + nY /= 8; + nHeight *= nH; + nHeight /= 8; + } + Reference < XWindow > xW( rxCtrl, UNO_QUERY ); + xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE ); +} + +void UnoDialogControl::dispose() throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + EventObject aEvt; + aEvt.Source = static_cast< ::cppu::OWeakObject* >( this ); + maTopWindowListeners.disposeAndClear( aEvt ); + + // Notify our listener helper about dispose + // --- SAFE --- + ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() ); + Reference< XEventListener > xListener( mxListener, UNO_QUERY ); + mxListener.clear(); + aGuard.clear(); + // --- SAFE --- + + if ( xListener.is() ) + xListener->disposing( aEvt ); + + UnoControlContainer::dispose(); +} + +void SAL_CALL UnoDialogControl::disposing( + const EventObject& Source ) +throw(RuntimeException) +{ + rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); + Reference< resource::XStringResourceResolver > xStringResourceResolver; + + ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver; + Reference< XInterface > xIfac( xStringResourceResolver, UNO_QUERY ); + + if ( Source.Source == xIfac ) + { + Any aAny; + + // Reset resource resolver reference + ImplSetPropertyValue( aPropName, aAny, sal_True ); + ImplUpdateResourceResolver(); + } + else + { + UnoControlContainer::disposing( Source ); + } +} + +sal_Bool UnoDialogControl::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + // destroy the old tab controller, if existent + if ( mxTabController.is() ) + { + mxTabController->setModel( NULL ); // just to be sure, should not be necessary + removeTabController( mxTabController ); + ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary + mxTabController.clear(); + } + + if ( getModel().is() ) + { + Sequence< Reference< XControl > > aControls = getControls(); + const Reference< XControl >* pCtrls = aControls.getConstArray(); + const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength(); + + for ( ; pCtrls < pCtrlsEnd; ++pCtrls ) + removeControl( *pCtrls ); + // will implicitly call removingControl, which will remove the PropertyChangeListener + // (which we formerly did herein) + // 08.01.2001 - 96008 - fs@openoffice.org + + Reference< XContainer > xC( getModel(), UNO_QUERY ); + if ( xC.is() ) + xC->removeContainerListener( this ); + + Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY ); + if ( xChangeNotifier.is() ) + xChangeNotifier->removeChangesListener( this ); + } + + sal_Bool bRet = UnoControl::setModel( rxModel ); + + if ( getModel().is() ) + { + Reference< XNameAccess > xNA( getModel(), UNO_QUERY ); + if ( xNA.is() ) + { + Sequence< ::rtl::OUString > aNames = xNA->getElementNames(); + const ::rtl::OUString* pNames = aNames.getConstArray(); + sal_uInt32 nCtrls = aNames.getLength(); + + Reference< XControlModel > xCtrlModel; + for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames ) + { + xNA->getByName( *pNames ) >>= xCtrlModel; + ImplInsertControl( xCtrlModel, *pNames ); + } + } + + Reference< XContainer > xC( getModel(), UNO_QUERY ); + if ( xC.is() ) + xC->addContainerListener( this ); + + Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY ); + if ( xChangeNotifier.is() ) + xChangeNotifier->addChangesListener( this ); + } + + Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY ); + if ( xTabbing.is() ) + { + mxTabController = new StdTabController; + mxTabController->setModel( xTabbing ); + addTabController( mxTabController ); + } + ImplStartListingForResourceEvents(); + + return bRet; +} + +void UnoDialogControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + UnoControl::setDesignMode( bOn ); + + Sequence< Reference< XControl > > xCtrls = getControls(); + sal_Int32 nControls = xCtrls.getLength(); + Reference< XControl >* pControls = xCtrls.getArray(); + for ( sal_Int32 n = 0; n < nControls; n++ ) + pControls[n]->setDesignMode( bOn ); + + // #109067# in design mode the tab controller is not notified about + // tab index changes, therefore the tab order must be activated + // when switching from design mode to live mode + if ( mxTabController.is() && !bOn ) + mxTabController->activateTabOrder(); +} + +void UnoDialogControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + UnoControlContainer::createPeer( rxToolkit, rParentPeer ); + + Reference < XTopWindow > xTW( getPeer(), UNO_QUERY ); + if ( xTW.is() ) + { + xTW->setMenuBar( mxMenuBar ); + + if ( !mbWindowListener ) + { + Reference< XWindowListener > xWL( static_cast< cppu::OWeakObject*>( this ), UNO_QUERY ); + addWindowListener( xWL ); + mbWindowListener = true; + } + + if ( maTopWindowListeners.getLength() ) + xTW->addTopWindowListener( &maTopWindowListeners ); + } +} + +void UnoDialogControl::PrepareWindowDescriptor( ::com::sun::star::awt::WindowDescriptor& rDesc ) +{ + sal_Bool bDecoration( sal_True ); + ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_DECORATION )) >>= bDecoration; + if ( !bDecoration ) + { + // Now we have to manipulate the WindowDescriptor + rDesc.WindowAttributes = rDesc.WindowAttributes | ::com::sun::star::awt::WindowAttribute::NODECORATION; + } + + // We have to set the graphic property before the peer + // will be created. Otherwise the properties will be copied + // into the peer via propertiesChangeEvents. As the order of + // can lead to overwrites we have to set the graphic property + // before the propertiesChangeEvents are sent! + ::rtl::OUString aImageURL; + Reference< graphic::XGraphic > xGraphic; + if (( ImplGetPropertyValue( PROPERTY_IMAGEURL ) >>= aImageURL ) && + ( aImageURL.getLength() > 0 )) + { + ::rtl::OUString absoluteUrl = + getPhysicalLocation( ImplGetPropertyValue( PROPERTY_DIALOGSOURCEURL ), + ImplGetPropertyValue( PROPERTY_IMAGEURL )); + + xGraphic = lcl_getGraphicFromURL_nothrow( absoluteUrl ); + ImplSetPropertyValue( PROPERTY_GRAPHIC, uno::makeAny( xGraphic ), sal_True ); + } +} + +void UnoDialogControl::elementInserted( const ContainerEvent& Event ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XControlModel > xModel; + ::rtl::OUString aName; + + Event.Accessor >>= aName; + Event.Element >>= xModel; + ImplInsertControl( xModel, aName ); +} + +void UnoDialogControl::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XControlModel > xModel; + Event.Element >>= xModel; + if ( xModel.is() ) + ImplRemoveControl( xModel ); +} + +void UnoDialogControl::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XControlModel > xModel; + Event.ReplacedElement >>= xModel; + if ( xModel.is() ) + ImplRemoveControl( xModel ); + + ::rtl::OUString aName; + Event.Accessor >>= aName; + Event.Element >>= xModel; + ImplInsertControl( xModel, aName ); +} + +void UnoDialogControl::addTopWindowListener( const Reference< XTopWindowListener >& rxListener ) throw (RuntimeException) +{ + maTopWindowListeners.addInterface( rxListener ); + if( getPeer().is() && maTopWindowListeners.getLength() == 1 ) + { + Reference < XTopWindow > xTW( getPeer(), UNO_QUERY ); + xTW->addTopWindowListener( &maTopWindowListeners ); + } +} + +void UnoDialogControl::removeTopWindowListener( const Reference< XTopWindowListener >& rxListener ) throw (RuntimeException) +{ + if( getPeer().is() && maTopWindowListeners.getLength() == 1 ) + { + Reference < XTopWindow > xTW( getPeer(), UNO_QUERY ); + xTW->removeTopWindowListener( &maTopWindowListeners ); + } + maTopWindowListeners.removeInterface( rxListener ); +} + +void UnoDialogControl::toFront( ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + if ( getPeer().is() ) + { + Reference< XTopWindow > xTW( getPeer(), UNO_QUERY ); + if( xTW.is() ) + xTW->toFront(); + } +} + +void UnoDialogControl::toBack( ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + if ( getPeer().is() ) + { + Reference< XTopWindow > xTW( getPeer(), UNO_QUERY ); + if( xTW.is() ) + xTW->toBack(); + } +} + +void UnoDialogControl::setMenuBar( const Reference< XMenuBar >& rxMenuBar ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + mxMenuBar = rxMenuBar; + if ( getPeer().is() ) + { + Reference< XTopWindow > xTW( getPeer(), UNO_QUERY ); + if( xTW.is() ) + xTW->setMenuBar( mxMenuBar ); + } +} + +static ::Size ImplMapPixelToAppFont( OutputDevice* pOutDev, const ::Size& aSize ) +{ + ::Size aTmp = pOutDev->PixelToLogic( aSize, MAP_APPFONT ); + return aTmp; +} + +// ::com::sun::star::awt::XWindowListener +void SAL_CALL UnoDialogControl::windowResized( const ::com::sun::star::awt::WindowEvent& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + OutputDevice*pOutDev = Application::GetDefaultDevice(); + DBG_ASSERT( pOutDev, "Missing Default Device!" ); + if ( pOutDev && !mbSizeModified ) + { + // Currentley we are simply using MAP_APPFONT + ::Size aAppFontSize( e.Width, e.Height ); + + Reference< XControl > xDialogControl( *this, UNO_QUERY_THROW ); + Reference< XDevice > xDialogDevice( xDialogControl->getPeer(), UNO_QUERY ); + OSL_ENSURE( xDialogDevice.is(), "UnoDialogControl::windowResized: no peer, but a windowResized event?" ); + if ( xDialogDevice.is() ) + { + DeviceInfo aDeviceInfo( xDialogDevice->getInfo() ); + aAppFontSize.Width() -= aDeviceInfo.LeftInset + aDeviceInfo.RightInset; + aAppFontSize.Height() -= aDeviceInfo.TopInset + aDeviceInfo.BottomInset; + } + + aAppFontSize = ImplMapPixelToAppFont( pOutDev, aAppFontSize ); + + // Remember that changes have been done by listener. No need to + // update the position because of property change event. + mbSizeModified = true; + Sequence< rtl::OUString > aProps( 2 ); + Sequence< Any > aValues( 2 ); + // Properties in a sequence must be sorted! + aProps[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" )); + aProps[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" )); + aValues[0] <<= aAppFontSize.Height(); + aValues[1] <<= aAppFontSize.Width(); + + ImplSetPropertyValues( aProps, aValues, true ); + mbSizeModified = false; + } +} + +void SAL_CALL UnoDialogControl::windowMoved( const ::com::sun::star::awt::WindowEvent& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + OutputDevice*pOutDev = Application::GetDefaultDevice(); + DBG_ASSERT( pOutDev, "Missing Default Device!" ); + if ( pOutDev && !mbPosModified ) + { + // Currentley we are simply using MAP_APPFONT + Any aAny; + ::Size aTmp( e.X, e.Y ); + aTmp = ImplMapPixelToAppFont( pOutDev, aTmp ); + + // Remember that changes have been done by listener. No need to + // update the position because of property change event. + mbPosModified = true; + Sequence< rtl::OUString > aProps( 2 ); + Sequence< Any > aValues( 2 ); + aProps[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" )); + aProps[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" )); + aValues[0] <<= aTmp.Width(); + aValues[1] <<= aTmp.Height(); + + ImplSetPropertyValues( aProps, aValues, true ); + mbPosModified = false; + } +} + +void SAL_CALL UnoDialogControl::windowShown( const ::com::sun::star::lang::EventObject& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + (void)e; +} + +void SAL_CALL UnoDialogControl::windowHidden( const ::com::sun::star::lang::EventObject& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + (void)e; +} + +// XPropertiesChangeListener +void UnoDialogControl::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException) +{ + if( !isDesignMode() && !mbCreatingCompatiblePeer ) + { + ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ); + ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ); + ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ); + ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ); + + sal_Int32 nLen = rEvents.getLength(); + for( sal_Int32 i = 0; i < nLen; i++ ) + { + const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i]; + Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY ); + sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get(); + if ( ( rEvt.PropertyName == s1 ) || + ( rEvt.PropertyName == s2 ) || + ( rEvt.PropertyName == s3 ) || + ( rEvt.PropertyName == s4 ) ) + { + if ( bOwnModel ) + { + if ( !mbPosModified && !mbSizeModified ) + { + // Don't set new pos/size if we get new values from window listener + Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY ); + ImplSetPosSize( xThis ); + } + } + else + { + Sequence<Reference<XControl> > aControlSequence(getControls()); + Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) ); + ImplSetPosSize( aControlRef ); + } + break; + } + else if ( bOwnModel && rEvt.PropertyName.equalsAsciiL( "ResourceResolver", 16 )) + { + ImplStartListingForResourceEvents(); + } + } + } + + sal_Int32 nLen = rEvents.getLength(); + for( sal_Int32 i = 0; i < nLen; i++ ) + { + const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i]; + Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY ); + sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get(); + if ( bOwnModel && rEvt.PropertyName.equalsAsciiL( "ImageURL", 8 )) + { + ::rtl::OUString aImageURL; + Reference< graphic::XGraphic > xGraphic; + if (( ImplGetPropertyValue( PROPERTY_IMAGEURL ) >>= aImageURL ) && + ( aImageURL.getLength() > 0 )) + { + ::rtl::OUString absoluteUrl = + getPhysicalLocation( ImplGetPropertyValue( PROPERTY_DIALOGSOURCEURL ), + ImplGetPropertyValue( PROPERTY_IMAGEURL )); + + xGraphic = lcl_getGraphicFromURL_nothrow( absoluteUrl ); + } + + ImplSetPropertyValue( PROPERTY_GRAPHIC, uno::makeAny( xGraphic ), sal_True ); + break; + } + } + + UnoControlContainer::ImplModelPropertiesChanged( rEvents ); +} + +void UnoDialogControl::ImplStartListingForResourceEvents() +{ + Reference< resource::XStringResourceResolver > xStringResourceResolver; + + ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver; + + // Add our helper as listener to retrieve notifications about changes + Reference< util::XModifyListener > rListener( mxListener ); + ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() ); + + // resource listener will stop listening if resolver reference is empty + if ( pResourceListener ) + pResourceListener->startListening( xStringResourceResolver ); + ImplUpdateResourceResolver(); +} + +void UnoDialogControl::ImplUpdateResourceResolver() +{ + rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); + Reference< resource::XStringResourceResolver > xStringResourceResolver; + + ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver; + if ( !xStringResourceResolver.is() ) + return; + + Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver; + + Sequence< rtl::OUString > aPropNames(1); + aPropNames[0] = aPropName; + + const Sequence< Reference< awt::XControl > > aSeq = getControls(); + for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ ) + { + Reference< XControl > xControl( aSeq[i] ); + Reference< XPropertySet > xPropertySet; + + if ( xControl.is() ) + xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY ); + + if ( !xPropertySet.is() ) + continue; + + try + { + Reference< resource::XStringResourceResolver > xCurrStringResourceResolver; + Any aOldValue = xPropertySet->getPropertyValue( aPropName ); + if ( ( aOldValue >>= xCurrStringResourceResolver ) + && ( xStringResourceResolver == xCurrStringResourceResolver ) + ) + { + Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY ); + Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY ); + xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener ); + } + else + xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver ); + } + /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ... + catch ( const Exception& ) + { + } + } + + // propagate resource resolver changes to language dependent props of the dialog + Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY ); + if ( xPropertySet.is() ) + { + Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY ); + Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY ); + xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener ); + } +} + +void UnoDialogControl::setTitle( const ::rtl::OUString& Title ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + Any aAny; + aAny <<= Title; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TITLE ), aAny, sal_True ); +} + +::rtl::OUString UnoDialogControl::getTitle() throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + return ImplGetPropertyValue_UString( BASEPROPERTY_TITLE ); +} + +sal_Int16 UnoDialogControl::execute() throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + sal_Int16 nDone = -1; + if ( getPeer().is() ) + { + Reference< XDialog > xDlg( getPeer(), UNO_QUERY ); + if( xDlg.is() ) + { + GetComponentInfos().bVisible = sal_True; + nDone = xDlg->execute(); + GetComponentInfos().bVisible = sal_False; + } + } + return nDone; +} + +void UnoDialogControl::endExecute() throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + if ( getPeer().is() ) + { + Reference< XDialog > xDlg( getPeer(), UNO_QUERY ); + if( xDlg.is() ) + { + xDlg->endExecute(); + GetComponentInfos().bVisible = sal_False; + } + } +} + +void UnoDialogControl::addingControl( const Reference< XControl >& _rxControl ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + UnoControlContainer::addingControl( _rxControl ); + + if ( _rxControl.is() ) + { + Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY ); + if ( xProps.is() ) + { + Sequence< ::rtl::OUString > aNames( 4 ); + ::rtl::OUString* pNames = aNames.getArray(); + *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" ); + *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" ); + *pNames++ = ::rtl::OUString::createFromAscii( "Width" ); + *pNames++ = ::rtl::OUString::createFromAscii( "Height" ); + + xProps->addPropertiesChangeListener( aNames, this ); + } + } +} + +void UnoDialogControl::removingControl( const Reference< XControl >& _rxControl ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + UnoControlContainer::removingControl( _rxControl ); + + if ( _rxControl.is() ) + { + Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY ); + if ( xProps.is() ) + xProps->removePropertiesChangeListener( this ); + } + +} + +void SAL_CALL UnoDialogControl::changesOccurred( const ChangesEvent& ) throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // a tab controller model may have changed + + // #109067# in design mode don't notify the tab controller + // about tab index changes + if ( mxTabController.is() && !mbDesignMode ) + mxTabController->activateTabOrder(); +} + +// XModifyListener +void SAL_CALL UnoDialogControl::modified( + const lang::EventObject& /*rEvent*/ ) +throw (RuntimeException) +{ + ImplUpdateResourceResolver(); +} + +// ---------------------------------------------------- +// Helper Method to convert relative url to physical location +// ---------------------------------------------------- + +::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl ) +{ + + + ::rtl::OUString ret; + + ::rtl::OUString baseLocation; + ::rtl::OUString url; + + rbase >>= baseLocation; + rUrl >>= url; + + if ( url.getLength() > 0 ) + { + INetURLObject urlObj(baseLocation); + urlObj.removeSegment(); + baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE ); + ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, ret ); + } + + return ret; +} + diff --git a/toolkit/source/controls/eventcontainer.cxx b/toolkit/source/controls/eventcontainer.cxx new file mode 100644 index 000000000000..b841badd8b0a --- /dev/null +++ b/toolkit/source/controls/eventcontainer.cxx @@ -0,0 +1,217 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: eventcontainer.cxx,v $ + * $Revision: 1.6 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + + +#include <osl/mutex.hxx> +#include <cppuhelper/queryinterface.hxx> +#ifndef _CPPUHELER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#include <cppuhelper/factory.hxx> +#include <cppuhelper/interfacecontainer.hxx> + +#include "toolkit/controls/eventcontainer.hxx" +#include <com/sun/star/script/ScriptEventDescriptor.hpp> + + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace com::sun::star::registry; +using namespace com::sun::star::script; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace std; + + +namespace toolkit +{ + +// Methods XElementAccess +Type NameContainer_Impl::getElementType() + throw(RuntimeException) +{ + return mType; +} + +sal_Bool NameContainer_Impl::hasElements() + throw(RuntimeException) +{ + sal_Bool bRet = (mnElementCount > 0); + return bRet; +} + +// Methods XNameAccess +Any NameContainer_Impl::getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + NameContainerNameMap::iterator aIt = mHashMap.find( aName ); + if( aIt == mHashMap.end() ) + { + throw NoSuchElementException(); + } + sal_Int32 iHashResult = (*aIt).second; + Any aRetAny = mValues.getConstArray()[ iHashResult ]; + return aRetAny; +} + +Sequence< OUString > NameContainer_Impl::getElementNames() + throw(RuntimeException) +{ + return mNames; +} + +sal_Bool NameContainer_Impl::hasByName( const OUString& aName ) + throw(RuntimeException) +{ + NameContainerNameMap::iterator aIt = mHashMap.find( aName ); + sal_Bool bRet = ( aIt != mHashMap.end() ); + return bRet; +} + + +// Methods XNameReplace +void NameContainer_Impl::replaceByName( const OUString& aName, const Any& aElement ) + throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) +{ + Type aAnyType = aElement.getValueType(); + if( mType != aAnyType ) + throw IllegalArgumentException(); + + NameContainerNameMap::iterator aIt = mHashMap.find( aName ); + if( aIt == mHashMap.end() ) + { + throw NoSuchElementException(); + } + sal_Int32 iHashResult = (*aIt).second; + Any aOldElement = mValues.getConstArray()[ iHashResult ]; + mValues.getArray()[ iHashResult ] = aElement; + + // Fire event + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element <<= aElement; + aEvent.ReplacedElement = aOldElement; + aEvent.Accessor <<= aName; + maContainerListeners.elementReplaced( aEvent ); +} + + +// Methods XNameContainer +void NameContainer_Impl::insertByName( const OUString& aName, const Any& aElement ) + throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) +{ + Type aAnyType = aElement.getValueType(); + if( mType != aAnyType ) + throw IllegalArgumentException(); + + NameContainerNameMap::iterator aIt = mHashMap.find( aName ); + if( aIt != mHashMap.end() ) + { + throw ElementExistException(); + } + + sal_Int32 nCount = mNames.getLength(); + mNames.realloc( nCount + 1 ); + mValues.realloc( nCount + 1 ); + mNames.getArray()[ nCount ] = aName; + mValues.getArray()[ nCount ] = aElement; + mHashMap[ aName ] = nCount; + + // Fire event + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element <<= aElement; + aEvent.Accessor <<= aName; + maContainerListeners.elementInserted( aEvent ); +} + +void NameContainer_Impl::removeByName( const OUString& Name ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + NameContainerNameMap::iterator aIt = mHashMap.find( Name ); + if( aIt == mHashMap.end() ) + { + throw NoSuchElementException(); + } + + sal_Int32 iHashResult = (*aIt).second; + Any aOldElement = mValues.getConstArray()[ iHashResult ]; + + // Fire event + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element = aOldElement; + aEvent.Accessor <<= Name; + maContainerListeners.elementRemoved( aEvent ); + + mHashMap.erase( aIt ); + sal_Int32 iLast = mNames.getLength() - 1; + if( iLast != iHashResult ) + { + OUString* pNames = mNames.getArray(); + Any* pValues = mValues.getArray(); + pNames[ iHashResult ] = pNames[ iLast ]; + pValues[ iHashResult ] = pValues[ iLast ]; + mHashMap[ pNames[ iHashResult ] ] = iHashResult; + } + mNames.realloc( iLast ); + mValues.realloc( iLast ); + +} + +// Methods XContainer +void NameContainer_Impl::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& l ) throw(::com::sun::star::uno::RuntimeException) +{ + maContainerListeners.addInterface( l ); +} + +void NameContainer_Impl::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& l ) throw(::com::sun::star::uno::RuntimeException) +{ + maContainerListeners.removeInterface( l ); +} + + + +// Ctor +ScriptEventContainer::ScriptEventContainer( void ) + : NameContainer_Impl( getCppuType( (ScriptEventDescriptor*) NULL ) ) +{ +} + +} + + + + diff --git a/toolkit/source/controls/formattedcontrol.cxx b/toolkit/source/controls/formattedcontrol.cxx new file mode 100644 index 000000000000..6171067f1185 --- /dev/null +++ b/toolkit/source/controls/formattedcontrol.cxx @@ -0,0 +1,470 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: formattedcontrol.cxx,v $ + * $Revision: 1.14 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <toolkit/controls/formattedcontrol.hxx> +#include <toolkit/helper/unopropertyarrayhelper.hxx> +#include <toolkit/helper/property.hxx> + +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> + +#include <tools/diagnose_ex.h> +#include <comphelper/processfactory.hxx> +#include <osl/diagnose.h> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::util; + + // ------------------------------------------------------------------- + namespace + { + // ............................................................... + ::osl::Mutex& getDefaultFormatsMutex() + { + static ::osl::Mutex s_aDefaultFormatsMutex; + return s_aDefaultFormatsMutex; + } + + // ............................................................... + Reference< XNumberFormatsSupplier >& lcl_getDefaultFormatsAccess_nothrow() + { + static Reference< XNumberFormatsSupplier > s_xDefaultFormats; + return s_xDefaultFormats; + } + + // ............................................................... + bool& lcl_getTriedCreation() + { + static bool s_bTriedCreation = false; + return s_bTriedCreation; + } + + // ............................................................... + const Reference< XNumberFormatsSupplier >& lcl_getDefaultFormats_throw() + { + ::osl::MutexGuard aGuard( getDefaultFormatsMutex() ); + + bool& rbTriedCreation = lcl_getTriedCreation(); + Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() ); + if ( !rDefaultFormats.is() && !rbTriedCreation ) + { + rbTriedCreation = true; + rDefaultFormats = Reference< XNumberFormatsSupplier >( + ::comphelper::createProcessComponent( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatsSupplier" ) ) ), + UNO_QUERY_THROW + ); + } + if ( !rDefaultFormats.is() ) + throw RuntimeException(); + + return rDefaultFormats; + } + + // ............................................................... + static oslInterlockedCount s_refCount(0); + + // ............................................................... + void lcl_registerDefaultFormatsClient() + { + osl_incrementInterlockedCount( &s_refCount ); + } + + // ............................................................... + void lcl_revokeDefaultFormatsClient() + { + ::osl::ClearableMutexGuard aGuard( getDefaultFormatsMutex() ); + if ( 0 == osl_decrementInterlockedCount( &s_refCount ) ) + { + Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() ); + Reference< XNumberFormatsSupplier > xReleasePotentialLastReference( rDefaultFormats ); + rDefaultFormats.clear(); + lcl_getTriedCreation() = false; + + aGuard.clear(); + xReleasePotentialLastReference.clear(); + } + } + } + + // =================================================================== + // = UnoControlFormattedFieldModel + // =================================================================== + // ------------------------------------------------------------------- + UnoControlFormattedFieldModel::UnoControlFormattedFieldModel() + :m_bRevokedAsClient( false ) + ,m_bSettingValueAndText( false ) + { + ImplRegisterProperty( BASEPROPERTY_ALIGN ); + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT ); + ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE ); + ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX ); + ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); + ImplRegisterProperty( BASEPROPERTY_FORMATKEY ); + ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_REPEAT ); + ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY ); + ImplRegisterProperty( BASEPROPERTY_READONLY ); + ImplRegisterProperty( BASEPROPERTY_SPIN ); + ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT ); + ImplRegisterProperty( BASEPROPERTY_TABSTOP ); + ImplRegisterProperty( BASEPROPERTY_TEXT ); + ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR ); + ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION ); + ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT ); + ImplRegisterProperty( BASEPROPERTY_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR ); + + Any aTreatAsNumber; + aTreatAsNumber <<= (sal_Bool) sal_True; + ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER, aTreatAsNumber ); + + lcl_registerDefaultFormatsClient(); + } + + // ------------------------------------------------------------------- + UnoControlFormattedFieldModel::~UnoControlFormattedFieldModel() + { + } + + // ------------------------------------------------------------------- + ::rtl::OUString UnoControlFormattedFieldModel::getServiceName() throw(RuntimeException) + { + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedFieldModel ); + } + + // ------------------------------------------------------------------- + void SAL_CALL UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) + { + UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + + switch ( nHandle ) + { + case BASEPROPERTY_EFFECTIVE_VALUE: + if ( !m_bSettingValueAndText ) + impl_updateTextFromValue_nothrow(); + break; + case BASEPROPERTY_FORMATSSUPPLIER: + impl_updateCachedFormatter_nothrow(); + impl_updateTextFromValue_nothrow(); + break; + case BASEPROPERTY_FORMATKEY: + impl_updateCachedFormatKey_nothrow(); + impl_updateTextFromValue_nothrow(); + break; + } + } + + // ------------------------------------------------------------------- + void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow() + { + if ( !m_xCachedFormatter.is() ) + impl_updateCachedFormatter_nothrow(); + if ( !m_xCachedFormatter.is() ) + return; + + try + { + Any aEffectiveValue; + getFastPropertyValue( aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE ); + + ::rtl::OUString sStringValue; + if ( !( aEffectiveValue >>= sStringValue ) ) + { + double nDoubleValue(0); + if ( aEffectiveValue >>= nDoubleValue ) + { + sal_Int32 nFormatKey( 0 ); + if ( m_aCachedFormat.hasValue() ) + m_aCachedFormat >>= nFormatKey; + sStringValue = m_xCachedFormatter->convertNumberToString( nFormatKey, nDoubleValue ); + } + } + + Reference< XPropertySet > xThis( *this, UNO_QUERY ); + xThis->setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), makeAny( sStringValue ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + // ------------------------------------------------------------------- + void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow() + { + Any aFormatsSupplier; + getFastPropertyValue( aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER ); + try + { + Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, UNO_QUERY ); + if ( !xSupplier.is() ) + xSupplier = lcl_getDefaultFormats_throw(); + + if ( !m_xCachedFormatter.is() ) + { + m_xCachedFormatter = Reference< XNumberFormatter >( + ::comphelper::createProcessComponent( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" ) ) ), + UNO_QUERY_THROW + ); + } + m_xCachedFormatter->attachNumberFormatsSupplier( xSupplier ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + // ------------------------------------------------------------------- + void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow() + { + Any aFormatKey; + getFastPropertyValue( aFormatKey, BASEPROPERTY_FORMATKEY ); + m_aCachedFormat = aFormatKey; + } + + // ------------------------------------------------------------------- + void UnoControlFormattedFieldModel::dispose( ) throw(RuntimeException) + { + UnoControlModel::dispose(); + + ::osl::MutexGuard aGuard( GetMutex() ); + if ( !m_bRevokedAsClient ) + { + lcl_revokeDefaultFormatsClient(); + m_bRevokedAsClient = true; + } + } + + // ------------------------------------------------------------------- + void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount, sal_Int32* _pHandles, + Any* _pValues, sal_Int32* _pValidHandles ) const SAL_THROW(()) + { + ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_EFFECTIVE_VALUE, BASEPROPERTY_TEXT ); + + UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles ); + } + + // ------------------------------------------------------------------- + namespace + { + class ResetFlagOnExit + { + private: + bool& m_rFlag; + + public: + ResetFlagOnExit( bool& _rFlag ) + :m_rFlag( _rFlag ) + { + } + ~ResetFlagOnExit() + { + m_rFlag = false; + } + }; + } + + // ------------------------------------------------------------------- + void SAL_CALL UnoControlFormattedFieldModel::setPropertyValues( const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) + { + bool bSettingValue = false; + bool bSettingText = false; + for ( const ::rtl::OUString* pPropertyNames = _rPropertyNames.getConstArray(); + pPropertyNames != _rPropertyNames.getConstArray() + _rPropertyNames.getLength(); + ++pPropertyNames + ) + { + if ( BASEPROPERTY_EFFECTIVE_VALUE == GetPropertyId( *pPropertyNames ) ) + bSettingValue = true; + + if ( BASEPROPERTY_TEXT == GetPropertyId( *pPropertyNames ) ) + bSettingText = true; + } + + m_bSettingValueAndText = ( bSettingValue && bSettingText ); + ResetFlagOnExit aResetFlag( m_bSettingValueAndText ); + UnoControlModel::setPropertyValues( _rPropertyNames, _rValues ); + } + + // ------------------------------------------------------------------- + sal_Bool UnoControlFormattedFieldModel::convertFastPropertyValue( + Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId, + const Any& rValue ) throw (IllegalArgumentException) + { + if ( BASEPROPERTY_EFFECTIVE_DEFAULT == nPropId && rValue.hasValue() ) + { + double dVal = 0; + sal_Int32 nVal = 0; + ::rtl::OUString sVal; + sal_Bool bStreamed = (rValue >>= dVal); + if ( bStreamed ) + { + rConvertedValue <<= dVal; + } + else + { + bStreamed = (rValue >>= nVal); + if ( bStreamed ) + { + rConvertedValue <<= static_cast<double>(nVal); + } + else + { + bStreamed = (rValue >>= sVal); + if ( bStreamed ) + { + rConvertedValue <<= sVal; + } + } + } + + if ( bStreamed ) + { + getFastPropertyValue( rOldValue, nPropId ); + return !CompareProperties( rConvertedValue, rOldValue ); + } + + throw IllegalArgumentException( + ( ::rtl::OUString::createFromAscii("Unable to convert the given value for the property ") + += GetPropertyName((sal_uInt16)nPropId) ) + += ::rtl::OUString::createFromAscii(" (double, integer, or string expected)."), + static_cast< XPropertySet* >(this), + 1); + } + + return UnoControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nPropId, rValue ); + } + + // ------------------------------------------------------------------- + Any UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const + { + Any aReturn; + switch (nPropId) + { + case BASEPROPERTY_DEFAULTCONTROL: aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedField ) ); break; + + case BASEPROPERTY_TREATASNUMBER: aReturn <<= (sal_Bool)sal_True; break; + + case BASEPROPERTY_EFFECTIVE_DEFAULT: + case BASEPROPERTY_EFFECTIVE_VALUE: + case BASEPROPERTY_EFFECTIVE_MAX: + case BASEPROPERTY_EFFECTIVE_MIN: + case BASEPROPERTY_FORMATKEY: + case BASEPROPERTY_FORMATSSUPPLIER: + // (void) + break; + + default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break; + } + + return aReturn; + } + + // ------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& UnoControlFormattedFieldModel::getInfoHelper() + { + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; + } + + // beans::XMultiPropertySet + // ------------------------------------------------------------------- + Reference< XPropertySetInfo > UnoControlFormattedFieldModel::getPropertySetInfo( ) throw(RuntimeException) + { + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + // =================================================================== + // = UnoFormattedFieldControl + // =================================================================== + // ------------------------------------------------------------------- + UnoFormattedFieldControl::UnoFormattedFieldControl() + { + } + + // ------------------------------------------------------------------- + ::rtl::OUString UnoFormattedFieldControl::GetComponentServiceName() + { + return ::rtl::OUString::createFromAscii( "FormattedField" ); + } + + // ------------------------------------------------------------------- + void UnoFormattedFieldControl::textChanged(const TextEvent& e) throw(RuntimeException) + { + Reference< XVclWindowPeer > xPeer(getPeer(), UNO_QUERY); + OSL_ENSURE(xPeer.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?"); + + Sequence< ::rtl::OUString > aNames( 2 ); + aNames[0] = GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE ); + aNames[1] = GetPropertyName( BASEPROPERTY_TEXT ); + + Sequence< Any > aValues( 2 ); + aValues[0] = xPeer->getProperty( aNames[0] ); + aValues[1] = xPeer->getProperty( aNames[1] ); + + ImplSetPropertyValues( aNames, aValues, FALSE ); + + if ( GetTextListeners().getLength() ) + GetTextListeners().textChanged( e ); + } + +//........................................................................ +} // namespace toolkit +//........................................................................ diff --git a/toolkit/source/controls/geometrycontrolmodel.cxx b/toolkit/source/controls/geometrycontrolmodel.cxx new file mode 100644 index 000000000000..8c4a5d864165 --- /dev/null +++ b/toolkit/source/controls/geometrycontrolmodel.cxx @@ -0,0 +1,656 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: geometrycontrolmodel.cxx,v $ + * $Revision: 1.25 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "toolkit/controls/geometrycontrolmodel.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <osl/diagnose.h> +#include <rtl/instance.hxx> +#include <comphelper/property.hxx> +#include <comphelper/sequence.hxx> +#ifndef _COM_SUN_STAR_XNAMECONTAINER_HPP_ +#include <toolkit/controls/eventcontainer.hxx> +#endif +#include <toolkit/helper/property.hxx> +#include <tools/debug.hxx> +#include <algorithm> +#include <functional> +#include <comphelper/sequence.hxx> + + +#define GCM_PROPERTY_ID_POS_X 1 +#define GCM_PROPERTY_ID_POS_Y 2 +#define GCM_PROPERTY_ID_WIDTH 3 +#define GCM_PROPERTY_ID_HEIGHT 4 +#define GCM_PROPERTY_ID_NAME 5 +#define GCM_PROPERTY_ID_TABINDEX 6 +#define GCM_PROPERTY_ID_STEP 7 +#define GCM_PROPERTY_ID_TAG 8 +#define GCM_PROPERTY_ID_RESOURCERESOLVER 9 + +#define GCM_PROPERTY_POS_X ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionX")) +#define GCM_PROPERTY_POS_Y ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionY")) +#define GCM_PROPERTY_WIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width")) +#define GCM_PROPERTY_HEIGHT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height")) +#define GCM_PROPERTY_NAME ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")) +#define GCM_PROPERTY_TABINDEX ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TabIndex")) +#define GCM_PROPERTY_STEP ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Step")) +#define GCM_PROPERTY_TAG ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tag")) +#define GCM_PROPERTY_RESOURCERESOLVER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ResourceResolver")) + +#define DEFAULT_ATTRIBS() PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT + +//........................................................................ +// namespace toolkit +// { +//........................................................................ + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::container; + using namespace ::comphelper; + + //==================================================================== + //= OGeometryControlModel_Base + //==================================================================== + //-------------------------------------------------------------------- + OGeometryControlModel_Base::OGeometryControlModel_Base(::com::sun::star::uno::XAggregation* _pAggregateInstance) + :OPropertySetAggregationHelper( m_aBHelper ) + ,OPropertyContainer( m_aBHelper ) + ,OGCM_Base( m_aMutex ) + ,m_nPosX(0) + ,m_nPosY(0) + ,m_nWidth(0) + ,m_nHeight(0) + ,m_nTabIndex(-1) + ,m_nStep(0) + ,m_bCloneable(sal_False) + { + OSL_ENSURE(NULL != _pAggregateInstance, "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid aggregate!"); + + increment(m_refCount); + { + m_xAggregate = _pAggregateInstance; + + { // check if the aggregat is cloneable + Reference< XCloneable > xCloneAccess(m_xAggregate, UNO_QUERY); + m_bCloneable = xCloneAccess.is(); + } + + setAggregation(m_xAggregate); + m_xAggregate->setDelegator(static_cast< XWeak* >(this)); + } + decrement(m_refCount); + + registerProperties(); + } + + //-------------------------------------------------------------------- + OGeometryControlModel_Base::OGeometryControlModel_Base(Reference< XCloneable >& _rxAggregateInstance) + :OPropertySetAggregationHelper( m_aBHelper ) + ,OPropertyContainer( m_aBHelper ) + ,OGCM_Base( m_aMutex ) + ,m_nPosX(0) + ,m_nPosY(0) + ,m_nWidth(0) + ,m_nHeight(0) + ,m_nTabIndex(-1) + ,m_nStep(0) + ,m_bCloneable(_rxAggregateInstance.is()) + { + increment(m_refCount); + { + { + // ensure that the temporary gets destructed NOW + m_xAggregate = Reference< XAggregation >(_rxAggregateInstance, UNO_QUERY); + } + OSL_ENSURE(m_xAggregate.is(), "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid object given!"); + + // now the aggregate has a ref count of 2, but before setting the delegator it must be 1 + _rxAggregateInstance.clear(); + // now it should be the 1 we need here ... + + setAggregation(m_xAggregate); + m_xAggregate->setDelegator(static_cast< XWeak* >(this)); + } + decrement(m_refCount); + + registerProperties(); + } + + //-------------------------------------------------------------------- + Sequence< Type > SAL_CALL OGeometryControlModel_Base::getTypes( ) throw (RuntimeException) + { + // our own types + Sequence< Type > aTypes = ::comphelper::concatSequences( + OPropertySetAggregationHelper::getTypes(), + OPropertyContainer::getTypes(), + OGCM_Base::getTypes() + ); + + if ( m_xAggregate.is() ) + { + // retrieve the types of the aggregate + Reference< XTypeProvider > xAggregateTypeProv; + m_xAggregate->queryAggregation( ::getCppuType( &xAggregateTypeProv ) ) >>= xAggregateTypeProv; + OSL_ENSURE( xAggregateTypeProv.is(), "OGeometryControlModel_Base::getTypes: aggregate should be a type provider!" ); + Sequence< Type > aAggTypes; + if ( xAggregateTypeProv.is() ) + aAggTypes = xAggregateTypeProv->getTypes(); + + // concat the sequences + sal_Int32 nOldSize = aTypes.getLength(); + aTypes.realloc( nOldSize + aAggTypes.getLength() ); + ::std::copy( + aAggTypes.getConstArray(), + aAggTypes.getConstArray() + aAggTypes.getLength(), + aTypes.getArray() + nOldSize + ); + } + + return aTypes; + } + + //-------------------------------------------------------------------- + void OGeometryControlModel_Base::registerProperties() + { + // register our members for the property handling of the OPropertyContainer + registerProperty(GCM_PROPERTY_POS_X, GCM_PROPERTY_ID_POS_X, DEFAULT_ATTRIBS(), &m_nPosX, ::getCppuType(&m_nPosX)); + registerProperty(GCM_PROPERTY_POS_Y, GCM_PROPERTY_ID_POS_Y, DEFAULT_ATTRIBS(), &m_nPosY, ::getCppuType(&m_nPosY)); + registerProperty(GCM_PROPERTY_WIDTH, GCM_PROPERTY_ID_WIDTH, DEFAULT_ATTRIBS(), &m_nWidth, ::getCppuType(&m_nWidth)); + registerProperty(GCM_PROPERTY_HEIGHT, GCM_PROPERTY_ID_HEIGHT, DEFAULT_ATTRIBS(), &m_nHeight, ::getCppuType(&m_nHeight)); + registerProperty(GCM_PROPERTY_NAME, GCM_PROPERTY_ID_NAME, DEFAULT_ATTRIBS(), &m_aName, ::getCppuType(&m_aName)); + registerProperty(GCM_PROPERTY_TABINDEX, GCM_PROPERTY_ID_TABINDEX, DEFAULT_ATTRIBS(), &m_nTabIndex, ::getCppuType(&m_nTabIndex)); + registerProperty(GCM_PROPERTY_STEP, GCM_PROPERTY_ID_STEP, DEFAULT_ATTRIBS(), &m_nStep, ::getCppuType(&m_nStep)); + registerProperty(GCM_PROPERTY_TAG, GCM_PROPERTY_ID_TAG, DEFAULT_ATTRIBS(), &m_aTag, ::getCppuType(&m_aTag)); + registerProperty(GCM_PROPERTY_RESOURCERESOLVER, GCM_PROPERTY_ID_RESOURCERESOLVER, DEFAULT_ATTRIBS(), &m_xStrResolver, ::getCppuType(&m_xStrResolver)); + } + + //-------------------------------------------------------------------- + ::com::sun::star::uno::Any OGeometryControlModel_Base::ImplGetDefaultValueByHandle(sal_Int32 nHandle) const + { + ::com::sun::star::uno::Any aDefault; + + switch ( nHandle ) + { + case GCM_PROPERTY_ID_POS_X: aDefault <<= (sal_Int32) 0; break; + case GCM_PROPERTY_ID_POS_Y: aDefault <<= (sal_Int32) 0; break; + case GCM_PROPERTY_ID_WIDTH: aDefault <<= (sal_Int32) 0; break; + case GCM_PROPERTY_ID_HEIGHT: aDefault <<= (sal_Int32) 0; break; + case GCM_PROPERTY_ID_NAME: aDefault <<= ::rtl::OUString(); break; + case GCM_PROPERTY_ID_TABINDEX: aDefault <<= (sal_Int16) -1; break; + case GCM_PROPERTY_ID_STEP: aDefault <<= (sal_Int32) 0; break; + case GCM_PROPERTY_ID_TAG: aDefault <<= ::rtl::OUString(); break; + case GCM_PROPERTY_ID_RESOURCERESOLVER: aDefault <<= Reference< resource::XStringResourceResolver >(); break; + default: DBG_ERROR( "ImplGetDefaultValueByHandle - unknown Property" ); + } + + return aDefault; + } + + //-------------------------------------------------------------------- + ::com::sun::star::uno::Any OGeometryControlModel_Base::ImplGetPropertyValueByHandle(sal_Int32 nHandle) const + { + ::com::sun::star::uno::Any aValue; + + switch ( nHandle ) + { + case GCM_PROPERTY_ID_POS_X: aValue <<= m_nPosX; break; + case GCM_PROPERTY_ID_POS_Y: aValue <<= m_nPosY; break; + case GCM_PROPERTY_ID_WIDTH: aValue <<= m_nWidth; break; + case GCM_PROPERTY_ID_HEIGHT: aValue <<= m_nHeight; break; + case GCM_PROPERTY_ID_NAME: aValue <<= m_aName; break; + case GCM_PROPERTY_ID_TABINDEX: aValue <<= m_nTabIndex; break; + case GCM_PROPERTY_ID_STEP: aValue <<= m_nStep; break; + case GCM_PROPERTY_ID_TAG: aValue <<= m_aTag; break; + case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue <<= m_xStrResolver; break; + default: DBG_ERROR( "ImplGetPropertyValueByHandle - unknown Property" ); + } + + return aValue; + } + + //-------------------------------------------------------------------- + void OGeometryControlModel_Base::ImplSetPropertyValueByHandle(sal_Int32 nHandle, const :: com::sun::star::uno::Any& aValue) + { + switch ( nHandle ) + { + case GCM_PROPERTY_ID_POS_X: aValue >>= m_nPosX; break; + case GCM_PROPERTY_ID_POS_Y: aValue >>= m_nPosY; break; + case GCM_PROPERTY_ID_WIDTH: aValue >>= m_nWidth; break; + case GCM_PROPERTY_ID_HEIGHT: aValue >>= m_nHeight; break; + case GCM_PROPERTY_ID_NAME: aValue >>= m_aName; break; + case GCM_PROPERTY_ID_TABINDEX: aValue >>= m_nTabIndex; break; + case GCM_PROPERTY_ID_STEP: aValue >>= m_nStep; break; + case GCM_PROPERTY_ID_TAG: aValue >>= m_aTag; break; + case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue >>= m_xStrResolver; break; + default: DBG_ERROR( "ImplSetPropertyValueByHandle - unknown Property" ); + } + } + + //-------------------------------------------------------------------- + Any SAL_CALL OGeometryControlModel_Base::queryAggregation( const Type& _rType ) throw(RuntimeException) + { + Any aReturn; + if (_rType.equals(::getCppuType(static_cast< Reference< XCloneable>* >(NULL))) && !m_bCloneable) + // somebody is asking for the XCloneable interface, but our aggregate does not support it + // -> outta here + // (need this extra check, cause OGCM_Base::queryAggregation would return this interface + // in every case) + return aReturn; + + aReturn = OGCM_Base::queryAggregation(_rType); + // the basic interfaces (XInterface, XAggregation etc) + + if (!aReturn.hasValue()) + aReturn = OPropertySetAggregationHelper::queryInterface(_rType); + // the property set related interfaces + + if (!aReturn.hasValue() && m_xAggregate.is()) + aReturn = m_xAggregate->queryAggregation(_rType); + // the interfaces our aggregate can provide + + return aReturn; + } + + //-------------------------------------------------------------------- + Any SAL_CALL OGeometryControlModel_Base::queryInterface( const Type& _rType ) throw(RuntimeException) + { + return OGCM_Base::queryInterface(_rType); + } + + //-------------------------------------------------------------------- + void SAL_CALL OGeometryControlModel_Base::acquire( ) throw() + { + OGCM_Base::acquire(); + } + + //-------------------------------------------------------------------- + void SAL_CALL OGeometryControlModel_Base::release( ) throw() + { + OGCM_Base::release(); + } + + //-------------------------------------------------------------------- + void OGeometryControlModel_Base::releaseAggregation() + { + // release the aggregate (_before_ clearing m_xAggregate) + if (m_xAggregate.is()) + m_xAggregate->setDelegator(NULL); + setAggregation(NULL); + } + + //-------------------------------------------------------------------- + OGeometryControlModel_Base::~OGeometryControlModel_Base() + { + releaseAggregation(); + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OGeometryControlModel_Base::convertFastPropertyValue(Any& _rConvertedValue, Any& _rOldValue, + sal_Int32 _nHandle, const Any& _rValue) throw (IllegalArgumentException) + { + return OPropertyContainer::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue); + } + + //-------------------------------------------------------------------- + void SAL_CALL OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception) + { + OPropertyContainer::setFastPropertyValue_NoBroadcast(_nHandle, _rValue); + } + + //-------------------------------------------------------------------- + void SAL_CALL OGeometryControlModel_Base::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const + { + OPropertyArrayAggregationHelper& rPH = static_cast<OPropertyArrayAggregationHelper&>(const_cast<OGeometryControlModel_Base*>(this)->getInfoHelper()); + ::rtl::OUString sPropName; + sal_Int32 nOriginalHandle = -1; + + if (rPH.fillAggregatePropertyInfoByHandle(&sPropName, &nOriginalHandle, _nHandle)) + OPropertySetAggregationHelper::getFastPropertyValue(_rValue, _nHandle); + else + OPropertyContainer::getFastPropertyValue(_rValue, _nHandle); + } + + //-------------------------------------------------------------------- + ::com::sun::star::beans::PropertyState OGeometryControlModel_Base::getPropertyStateByHandle(sal_Int32 nHandle) + { + ::com::sun::star::uno::Any aValue = ImplGetPropertyValueByHandle( nHandle ); + ::com::sun::star::uno::Any aDefault = ImplGetDefaultValueByHandle( nHandle ); + + return CompareProperties( aValue, aDefault ) ? ::com::sun::star::beans::PropertyState_DEFAULT_VALUE : ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + } + + //-------------------------------------------------------------------- + void OGeometryControlModel_Base::setPropertyToDefaultByHandle(sal_Int32 nHandle) + { + ImplSetPropertyValueByHandle( nHandle , ImplGetDefaultValueByHandle( nHandle ) ); + } + + //-------------------------------------------------------------------- + ::com::sun::star::uno::Any OGeometryControlModel_Base::getPropertyDefaultByHandle( sal_Int32 nHandle ) const + { + return ImplGetDefaultValueByHandle( nHandle ); + } + + //-------------------------------------------------------------------- + Reference< XPropertySetInfo> SAL_CALL OGeometryControlModel_Base::getPropertySetInfo() throw(RuntimeException) + { + return OPropertySetAggregationHelper::createPropertySetInfo(getInfoHelper()); + } + + //-------------------------------------------------------------------- + Reference< XCloneable > SAL_CALL OGeometryControlModel_Base::createClone( ) throw(RuntimeException) + { + OSL_ENSURE(m_bCloneable, "OGeometryControlModel_Base::createClone: invalid call!"); + if (!m_bCloneable) + return Reference< XCloneable >(); + + // let the aggregate create it's own clone + // the interface + Reference< XCloneable > xCloneAccess; + m_xAggregate->queryAggregation(::getCppuType(&xCloneAccess)) >>= xCloneAccess; + OSL_ENSURE(xCloneAccess.is(), "OGeometryControlModel_Base::createClone: suspicious aggregate!"); + if (!xCloneAccess.is()) + return Reference< XCloneable >(); + // the aggregate's clone + Reference< XCloneable > xAggregateClone = xCloneAccess->createClone(); + OSL_ENSURE(xAggregateClone.is(), "OGeometryControlModel_Base::createClone: suspicious return of the aggregate!"); + + // create a new wrapper aggregating this return value + OGeometryControlModel_Base* pOwnClone = createClone_Impl(xAggregateClone); + OSL_ENSURE(pOwnClone, "OGeometryControlModel_Base::createClone: invalid derivee behaviour!"); + OSL_ENSURE(!xAggregateClone.is(), "OGeometryControlModel_Base::createClone: invalid ctor behaviour!"); + // should have been reset + + // set properties + pOwnClone->m_nPosX = m_nPosX; + pOwnClone->m_nPosY = m_nPosY; + pOwnClone->m_nWidth = m_nWidth; + pOwnClone->m_nHeight = m_nHeight; + pOwnClone->m_aName = m_aName; + pOwnClone->m_nTabIndex = m_nTabIndex; + pOwnClone->m_nStep = m_nStep; + pOwnClone->m_aTag = m_aTag; + + + // Clone event container + Reference< ::com::sun::star::script::XScriptEventsSupplier > xEventsSupplier = + static_cast< ::com::sun::star::script::XScriptEventsSupplier* >( this ); + Reference< ::com::sun::star::script::XScriptEventsSupplier > xCloneEventsSupplier = + static_cast< ::com::sun::star::script::XScriptEventsSupplier* >( pOwnClone ); + + if( xEventsSupplier.is() && xCloneEventsSupplier.is() ) + { + Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents(); + Reference< XNameContainer > xCloneEventCont = xCloneEventsSupplier->getEvents(); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aNames = + xEventCont->getElementNames(); + const ::rtl::OUString* pNames = aNames.getConstArray(); + sal_Int32 i, nNameCount = aNames.getLength(); + + for( i = 0 ; i < nNameCount ; i++ ) + { + ::rtl::OUString aName = pNames[ i ]; + ::com::sun::star::uno::Any aElement = xEventCont->getByName( aName ); + xCloneEventCont->insertByName( aName, aElement ); + } + } + + return pOwnClone; + } + + //-------------------------------------------------------------------- + Reference< XNameContainer > SAL_CALL OGeometryControlModel_Base::getEvents() throw(RuntimeException) + { + if( !mxEventContainer.is() ) + mxEventContainer = (XNameContainer*)new toolkit::ScriptEventContainer(); + return mxEventContainer; + } + + //-------------------------------------------------------------------- + void SAL_CALL OGeometryControlModel_Base::disposing() + { + OGCM_Base::disposing(); + OPropertySetAggregationHelper::disposing(); + + Reference<XComponent> xComp; + if ( query_aggregation( m_xAggregate, xComp ) ) + xComp->dispose(); + } + + //==================================================================== + //= OCommonGeometryControlModel + //==================================================================== + //-------------------------------------------------------------------- + + typedef ::std::hash_map< ::rtl::OUString, sal_Int32, ::comphelper::UStringHash > HashMapString2Int; + typedef ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > > PropSeqArray; + typedef ::std::vector< ::std::vector< sal_Int32 > > IntArrayArray; + + // for creating class-unique PropertySetInfo's, we need some info: + namespace { struct ServiceSpecifierMap : public rtl::Static< HashMapString2Int, ServiceSpecifierMap > {}; } + // this one maps from a String, which is the service specifier for our + // aggregate, to a unique id + + namespace { struct AggregateProperties : public rtl::Static< PropSeqArray, AggregateProperties > {}; } + // this one contains the properties which belong to all the unique ids + // in ServiceSpecifierMap + + namespace { struct AmbiguousPropertyIds : public rtl::Static< IntArrayArray, AmbiguousPropertyIds > {}; } + // the ids of the properties which we as well as our aggregate supply + // For such props, we let our base class handle them, and whenever such + // a prop is set, we forward this to our aggregate. + + // With this, we can ensure that two instances of this class share the + // same PropertySetInfo if and only if both aggregates have the same + // service specifier. + + + //-------------------------------------------------------------------- + OCommonGeometryControlModel::OCommonGeometryControlModel( Reference< XCloneable >& _rxAgg, const ::rtl::OUString& _rServiceSpecifier ) + :OGeometryControlModel_Base( _rxAgg ) + ,m_sServiceSpecifier( _rServiceSpecifier ) + ,m_nPropertyMapId( 0 ) + { + Reference< XPropertySetInfo > xPI; + if ( m_xAggregateSet.is() ) + xPI = m_xAggregateSet->getPropertySetInfo(); + if ( !xPI.is() ) + { + releaseAggregation(); + throw IllegalArgumentException(); + } + + HashMapString2Int &rMap = ServiceSpecifierMap::get(); + HashMapString2Int::iterator aPropMapIdPos = rMap.find( m_sServiceSpecifier ); + if ( rMap.end() == aPropMapIdPos ) + { + PropSeqArray &rAggProperties = AggregateProperties::get(); + m_nPropertyMapId = rAggProperties.size(); + rAggProperties.push_back( xPI->getProperties() ); + AmbiguousPropertyIds::get().push_back( IntArrayArray::value_type() ); + + rMap[ m_sServiceSpecifier ] = m_nPropertyMapId; + } + else + m_nPropertyMapId = aPropMapIdPos->second; + } + + //-------------------------------------------------------------------- + struct PropertyNameLess : public ::std::binary_function< Property, Property, bool > + { + bool operator()( const Property& _rLHS, const Property& _rRHS ) + { + return _rLHS.Name < _rRHS.Name ? true : false; + } + }; + + //-------------------------------------------------------------------- + struct PropertyNameEqual : public ::std::unary_function< Property, bool > + { + const ::rtl::OUString& m_rCompare; + PropertyNameEqual( const ::rtl::OUString& _rCompare ) : m_rCompare( _rCompare ) { } + + bool operator()( const Property& _rLHS ) + { + return _rLHS.Name == m_rCompare ? true : false; + } + }; + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper* OCommonGeometryControlModel::createArrayHelper( sal_Int32 _nId ) const + { + OSL_ENSURE( _nId == m_nPropertyMapId, "OCommonGeometryControlModel::createArrayHelper: invalid argument!" ); + OSL_ENSURE( _nId < (sal_Int32)AggregateProperties::get().size(), "OCommonGeometryControlModel::createArrayHelper: invalid status info (1)!" ); + OSL_ENSURE( _nId < (sal_Int32)AmbiguousPropertyIds::get().size(), "OCommonGeometryControlModel::createArrayHelper: invalid status info (2)!" ); + + // our own properties + Sequence< Property > aProps; + OPropertyContainer::describeProperties( aProps ); + + // the aggregate properties + Sequence< Property > aAggregateProps; + aAggregateProps = AggregateProperties::get()[ _nId ]; + + // look for duplicates, and remember them + IntArrayArray::value_type& rDuplicateIds = AmbiguousPropertyIds::get()[ _nId ]; + // for this, sort the aggregate properties + ::std::sort( + aAggregateProps.getArray(), + aAggregateProps.getArray() + aAggregateProps.getLength(), + PropertyNameLess() + ); + const Property* pAggProps = aAggregateProps.getConstArray(); + const Property* pAggPropsEnd = aAggregateProps.getConstArray() + aAggregateProps.getLength(); + + // now loop through our own props + const Property* pProp = aProps.getConstArray(); + const Property* pPropEnd = aProps.getConstArray() + aProps.getLength(); + while ( pProp < pPropEnd ) + { + // look for the current property in the properties of our aggregate + const Property* pAggPropPos = ::std::find_if( pAggProps, pAggPropsEnd, PropertyNameEqual( pProp->Name ) ); + if ( pAggPropPos != pAggPropsEnd ) + { // found a duplicate + // -> remove from the aggregate property sequence + ::comphelper::removeElementAt( aAggregateProps, pAggPropPos - pAggProps ); + // which means we have to adjust the pointers + pAggProps = aAggregateProps.getConstArray(), + pAggPropsEnd = aAggregateProps.getConstArray() + aAggregateProps.getLength(), + + // and additionally, remember the id of this property + rDuplicateIds.push_back( pProp->Handle ); + } + + ++pProp; + } + + // now, finally, sort the duplicates + ::std::sort( rDuplicateIds.begin(), rDuplicateIds.end(), ::std::less< sal_Int32 >() ); + + return new OPropertyArrayAggregationHelper(aProps, aAggregateProps); + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& SAL_CALL OCommonGeometryControlModel::getInfoHelper() + { + return *getArrayHelper( m_nPropertyMapId ); + } + + //-------------------------------------------------------------------- + OGeometryControlModel_Base* OCommonGeometryControlModel::createClone_Impl( Reference< XCloneable >& _rxAggregateInstance ) + { + return new OCommonGeometryControlModel( _rxAggregateInstance, m_sServiceSpecifier ); + } + + //-------------------------------------------------------------------- + Sequence< sal_Int8 > SAL_CALL OCommonGeometryControlModel::getImplementationId( ) throw (RuntimeException) + { + static ::cppu::OImplementationId * pId = NULL; + if ( !pId ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pId ) + { + static ::cppu::OImplementationId s_aId; + pId = &s_aId; + } + } + return pId->getImplementationId(); + } + + //-------------------------------------------------------------------- + struct Int32Equal : public ::std::unary_function< sal_Int32, bool > + { + sal_Int32 m_nCompare; + Int32Equal( sal_Int32 _nCompare ) : m_nCompare( _nCompare ) { } + + bool operator()( sal_Int32 _nLHS ) + { + return _nLHS == m_nCompare ? true : false; + } + }; + + //-------------------------------------------------------------------- + void SAL_CALL OCommonGeometryControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception ) + { + OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + + // look if this id is one we recognized as duplicate + IntArrayArray::value_type& rDuplicateIds = AmbiguousPropertyIds::get()[ m_nPropertyMapId ]; + + IntArrayArray::value_type::const_iterator aPos = ::std::find_if( + rDuplicateIds.begin(), + rDuplicateIds.end(), + Int32Equal( _nHandle ) + ); + + if ( rDuplicateIds.end() != aPos ) + { + // yes, it is such a property + ::rtl::OUString sPropName; + sal_Int16 nAttributes(0); + static_cast< OPropertyArrayAggregationHelper* >( getArrayHelper( m_nPropertyMapId ) )->fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle ); + + if ( m_xAggregateSet.is() && sPropName.getLength() ) + m_xAggregateSet->setPropertyValue( sPropName, _rValue ); + } + } + +//........................................................................ +// } // namespace toolkit +//........................................................................ diff --git a/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx b/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx new file mode 100644 index 000000000000..bdd7fb475afe --- /dev/null +++ b/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx @@ -0,0 +1,242 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treedatamodel.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "defaultgridcolumnmodel.hxx" +#include <comphelper/sequence.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <rtl/ref.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; + +#define COLUMNSELECTIONALLOWED ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnSelectionAllowed" )) + +namespace toolkit +{ + +/////////////////////////////////////////////////////////////////////// +// class DefaultGridColumnModel +/////////////////////////////////////////////////////////////////////// + +DefaultGridColumnModel::DefaultGridColumnModel() +: columns(std::vector< Reference< XGridColumn > >()) +{ +} + +//--------------------------------------------------------------------- + +DefaultGridColumnModel::~DefaultGridColumnModel() +{ +} + +//--------------------------------------------------------------------- + +void DefaultGridColumnModel::broadcast( broadcast_type eType, const GridColumnEvent& aEvent ) +{ + ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridColumnListener::static_type() ); + if( pIter ) + { + ::cppu::OInterfaceIteratorHelper aListIter(*pIter); + while(aListIter.hasMoreElements()) + { + XGridColumnListener* pListener = static_cast<XGridColumnListener*>(aListIter.next()); + switch( eType ) + { + case column_added: pListener->columnAdded(aEvent); break; + case column_removed: pListener->columnRemoved(aEvent); break; + case column_changed: pListener->columnChanged(aEvent); break; + } + } + } +} + +//--------------------------------------------------------------------- + +void DefaultGridColumnModel::broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridColumnEvent aEvent( xSource, name, oldValue, newValue, 0, NULL ); + broadcast( column_changed, aEvent); +} + +//--------------------------------------------------------------------- + +void DefaultGridColumnModel::broadcast_add( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridColumnEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, rColumn ); + broadcast( column_added, aEvent); +} + +//--------------------------------------------------------------------- + +void DefaultGridColumnModel::broadcast_remove( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridColumnEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, rColumn ); + broadcast( column_changed, aEvent); +} + +//--------------------------------------------------------------------- +// XDefaultGridColumnModel +//--------------------------------------------------------------------- +::sal_Bool SAL_CALL DefaultGridColumnModel::getColumnSelectionAllowed() throw (::com::sun::star::uno::RuntimeException) +{ + return selectionAllowed; +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridColumnModel::setColumnSelectionAllowed(::sal_Bool value) throw (::com::sun::star::uno::RuntimeException) +{ + sal_Bool oldValue = selectionAllowed; + selectionAllowed = value; + broadcast_changed( COLUMNSELECTIONALLOWED, Any(oldValue) , Any(selectionAllowed)); +} + +//--------------------------------------------------------------------- + +::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (::com::sun::star::uno::RuntimeException) +{ + return columns.size(); +} + +//--------------------------------------------------------------------- + +::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + columns.push_back(column); + + sal_Int32 index = columns.size() - 1; + broadcast_add(index, column ); + return index; +} + +//--------------------------------------------------------------------- + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns() throw (::com::sun::star::uno::RuntimeException) +{ + return comphelper::containerToSequence(columns); +} + +//--------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) +{ + if ( index >=0 && index < ((sal_Int32)columns.size())) + return columns[index]; + else + return Reference< XGridColumn >(); +} + +void SAL_CALL DefaultGridColumnModel::addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XGridColumnListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridColumnModel::removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XGridColumnListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- +// XComponent +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridColumnModel::dispose() throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::lang::EventObject aEvent; + aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) ); + BrdcstHelper.aLC.disposeAndClear( aEvent ); + +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridColumnModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XEventListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridColumnModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XEventListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- +// XServiceInfo +//--------------------------------------------------------------------- + +::rtl::OUString SAL_CALL DefaultGridColumnModel::getImplementationName( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.DefaultGridColumnModel" ) ); + return aImplName; +} + +//--------------------------------------------------------------------- + +sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return ServiceName.equalsAscii( szServiceName_DefaultGridColumnModel ); +} + +//--------------------------------------------------------------------- + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aServiceName( OUString::createFromAscii( szServiceName_DefaultGridColumnModel ) ); + static const Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +} + +Reference< XInterface > SAL_CALL DefaultGridColumnModel_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel ); +} + diff --git a/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx b/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx new file mode 100644 index 000000000000..b230188f9107 --- /dev/null +++ b/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx @@ -0,0 +1,96 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: griddatamodel.hxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/grid/XGridColumnModel.hpp> +#include <com/sun/star/awt/grid/XGridColumn.hpp> +#include <com/sun/star/awt/grid/GridColumnEvent.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> +#include <rtl/ref.hxx> +#include <vector> +#include <toolkit/helper/mutexandbroadcasthelper.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; + +namespace toolkit +{ + +enum broadcast_type { column_added, column_removed, column_changed}; + +class DefaultGridColumnModel : public ::cppu::WeakImplHelper2< XGridColumnModel, XServiceInfo >, + public MutexAndBroadcastHelper +{ +public: + DefaultGridColumnModel(); + virtual ~DefaultGridColumnModel(); + + // XGridColumnModel + + virtual ::sal_Bool SAL_CALL getColumnSelectionAllowed() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setColumnSelectionAllowed(::sal_Bool the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getColumnCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > SAL_CALL getColumns() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL getColumn(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException); + + // XComponent + virtual void SAL_CALL dispose( ) throw (RuntimeException); + virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + +private: + + void broadcast( broadcast_type eType, const GridColumnEvent& aEvent ); + void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ); + void broadcast_add( sal_Int32 index,const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ); + void broadcast_remove( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn ); + + std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > columns; + sal_Bool selectionAllowed; +}; + +} diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.cxx b/toolkit/source/controls/grid/defaultgriddatamodel.cxx new file mode 100644 index 000000000000..865be80f55a7 --- /dev/null +++ b/toolkit/source/controls/grid/defaultgriddatamodel.cxx @@ -0,0 +1,310 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treedatamodel.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "defaultgriddatamodel.hxx" +#include <comphelper/sequence.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <rtl/ref.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; + +#define ROWHEIGHT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeight" )) +#define ROWHEADERS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeaders" )) + +namespace toolkit +{ + +/////////////////////////////////////////////////////////////////////// +// class DefaultGridDataModel +/////////////////////////////////////////////////////////////////////// + +DefaultGridDataModel::DefaultGridDataModel() +: rowHeight(0), + rowHeaders(std::vector< ::rtl::OUString >()) +{ +} + +//--------------------------------------------------------------------- + +DefaultGridDataModel::~DefaultGridDataModel() +{ +} + +void DefaultGridDataModel::broadcast( broadcast_type eType, const GridDataEvent& aEvent ) +{ + ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridDataListener::static_type() ); + if( pIter ) + { + ::cppu::OInterfaceIteratorHelper aListIter(*pIter); + while(aListIter.hasMoreElements()) + { + XGridDataListener* pListener = static_cast<XGridDataListener*>(aListIter.next()); + switch( eType ) + { + case row_added: pListener->rowAdded(aEvent); break; + case row_removed: pListener->rowRemoved(aEvent); break; + case data_changed: pListener->dataChanged(aEvent); break; + } + } + } +} + +//--------------------------------------------------------------------- + +void DefaultGridDataModel::broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridDataEvent aEvent( xSource, name, oldValue, newValue, 0, ::rtl::OUString(), Sequence< ::rtl::OUString>() ); + broadcast( data_changed, aEvent); +} + +//--------------------------------------------------------------------- + +void DefaultGridDataModel::broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, rowData ); + broadcast( row_added, aEvent); +} + +//--------------------------------------------------------------------- + +void DefaultGridDataModel::broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ) +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, rowData ); + broadcast( row_removed, aEvent); +} + +//--------------------------------------------------------------------- + +//--------------------------------------------------------------------- +// XDefaultGridDataModel +//--------------------------------------------------------------------- +::sal_Int32 SAL_CALL DefaultGridDataModel::getRowHeight() throw (::com::sun::star::uno::RuntimeException) +{ + return rowHeight; +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::setRowHeight(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException) +{ + sal_Int32 oldValue = rowHeight; + rowHeight = value; + + broadcast_changed( ROWHEIGHT, Any(oldValue), Any(value) ); +} + +//--------------------------------------------------------------------- + +::sal_Int32 SAL_CALL DefaultGridDataModel::getRowCount() throw (::com::sun::star::uno::RuntimeException) +{ + return data.size(); +} + +//--------------------------------------------------------------------- + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL DefaultGridDataModel::getRowHeaders() throw (::com::sun::star::uno::RuntimeException) +{ + return comphelper::containerToSequence(rowHeaders); +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::setRowHeaders(const ::com::sun::star::uno::Sequence< ::rtl::OUString > & value) throw (::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Sequence< ::rtl::OUString > oldValue( comphelper::containerToSequence(rowHeaders) ); + + std::vector< rtl::OUString>::iterator iterator; + int i = 0; + int sequenceSize = value.getLength(); + + for(iterator = rowHeaders.begin(); iterator != rowHeaders.end(); iterator++) + { + if ( sequenceSize > i ) + *iterator = value[i]; + else + *iterator = ::rtl::OUString(); + i++; + } + + broadcast_changed( ROWHEADERS, Any(oldValue), Any(comphelper::containerToSequence(rowHeaders)) ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< ::rtl::OUString > & rRowdata) throw (::com::sun::star::uno::RuntimeException) +{ + // store header name + rowHeaders.push_back(headername); + + + // store row data + std::vector< rtl::OUString > newRow( + comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rRowdata)); + + data.push_back( newRow ); + + broadcast_add( data.size()-1, headername, rRowdata); + +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::removeRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) +{ + if ( index >= 0 && index <= getRowCount()-1) + { + /* if(Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectedIndex( index )) + { + ::com::sun::star::uno::Sequence<::sal_Int32> selectedRows = Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getSelection(); + selectedRow.erase(selectedRows.begin()+index); + }*/ + + ::rtl::OUString headerName( (::rtl::OUString) rowHeaders[index] ); + rowHeaders.erase(rowHeaders.begin() + index); + + Sequence< ::rtl::OUString >& rowData ( (Sequence< ::rtl::OUString >&)data[index] ); + data.erase(data.begin() + index); + broadcast_remove( index, headerName, rowData); + } + else + return; +} +//--------------------------------------------------------------------- +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > SAL_CALL DefaultGridDataModel::getData() throw (::com::sun::star::uno::RuntimeException) +{ + + std::vector< std::vector< ::rtl::OUString > >::iterator iterator; + std::vector< Sequence< ::rtl::OUString > > dummyContainer(0); + + + for(iterator = data.begin(); iterator != data.end(); iterator++) + { + Sequence< ::rtl::OUString > cols(comphelper::containerToSequence(*iterator)); + dummyContainer.push_back( cols ); + } + Sequence< Sequence< ::rtl::OUString > > dataSequence(comphelper::containerToSequence(dummyContainer)); + + return dataSequence; +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::addDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XGridDataListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::removeDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XGridDataListener::static_type(), xListener ); +} + +void SAL_CALL DefaultGridDataModel::removeAll() throw (RuntimeException) +{ + rowHeaders.clear(); + data.clear(); + broadcast_remove( -1, ::rtl::OUString(), 0); +} + +//--------------------------------------------------------------------- +// XComponent +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::dispose() throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::lang::EventObject aEvent; + aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) ); + BrdcstHelper.aLC.disposeAndClear( aEvent ); + +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XEventListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL DefaultGridDataModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XEventListener::static_type(), xListener ); +} +//--------------------------------------------------------------------- +// XServiceInfo +//--------------------------------------------------------------------- + +::rtl::OUString SAL_CALL DefaultGridDataModel::getImplementationName( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.DefaultGridDataModel" ) ); + return aImplName; +} + +//--------------------------------------------------------------------- + +sal_Bool SAL_CALL DefaultGridDataModel::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return ServiceName.equalsAscii( szServiceName_DefaultGridDataModel ); +} + +//--------------------------------------------------------------------- + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL DefaultGridDataModel::getSupportedServiceNames( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aServiceName( OUString::createFromAscii( szServiceName_DefaultGridDataModel ) ); + static const Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +} + +Reference< XInterface > SAL_CALL DefaultGridDataModel_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridDataModel ); +} + diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.hxx b/toolkit/source/controls/grid/defaultgriddatamodel.hxx new file mode 100644 index 000000000000..18000c9f5a71 --- /dev/null +++ b/toolkit/source/controls/grid/defaultgriddatamodel.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: griddatamodel.hxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/grid/XGridDataModel.hpp> +#include <com/sun/star/awt/grid/GridDataEvent.hpp> +#include <com/sun/star/awt/grid/XGridDataListener.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> +#include <rtl/ref.hxx> +#include <vector> +#include <toolkit/helper/mutexandbroadcasthelper.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; + +namespace toolkit +{ + +enum broadcast_type { row_added, row_removed, data_changed}; + +class DefaultGridDataModel : public ::cppu::WeakImplHelper2< XGridDataModel, XServiceInfo >, + public MutexAndBroadcastHelper +{ +public: + DefaultGridDataModel(); + virtual ~DefaultGridDataModel(); + + // XGridDataModel + virtual ::sal_Int32 SAL_CALL getRowHeight() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRowHeight(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getRowCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getRowHeaders() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRowHeaders(const ::com::sun::star::uno::Sequence< ::rtl::OUString > & value) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > SAL_CALL getData() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< ::rtl::OUString > & data) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeAll() throw (RuntimeException); + + // XComponent + virtual void SAL_CALL dispose( ) throw (RuntimeException); + virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + +private: + + void broadcast( broadcast_type eType, const GridDataEvent& aEvent ); + void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue ); + void broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ); + void broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rowData ); + + sal_Int32 rowHeight; + std::vector< std::vector < ::rtl::OUString > > data; + std::vector< ::rtl::OUString > rowHeaders; +}; + +} diff --git a/toolkit/source/controls/grid/gridcolumn.cxx b/toolkit/source/controls/grid/gridcolumn.cxx new file mode 100644 index 000000000000..8b398b4aed58 --- /dev/null +++ b/toolkit/source/controls/grid/gridcolumn.cxx @@ -0,0 +1,166 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treedatamodel.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "gridcolumn.hxx" +#include <comphelper/sequence.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <rtl/ref.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; + +namespace toolkit +{ + +/////////////////////////////////////////////////////////////////////// +// class GridColumn +/////////////////////////////////////////////////////////////////////// + +GridColumn::GridColumn() +: identifier(Any()) +{ +} + +//--------------------------------------------------------------------- + +GridColumn::~GridColumn() +{ +} + +//--------------------------------------------------------------------- + +//--------------------------------------------------------------------- +// XGridColumn +//--------------------------------------------------------------------- + +::com::sun::star::uno::Any SAL_CALL GridColumn::getIdentifier() throw (::com::sun::star::uno::RuntimeException) +{ + return identifier; +} + +//--------------------------------------------------------------------- + +void SAL_CALL GridColumn::setIdentifier(const ::com::sun::star::uno::Any & value) throw (::com::sun::star::uno::RuntimeException) +{ + value >>= identifier; +} + +//-------------------------------------------------------------------- + +::sal_Int32 SAL_CALL GridColumn::getColumnWidth() throw (::com::sun::star::uno::RuntimeException) +{ + return columnWidth; +} + +//-------------------------------------------------------------------- + +void SAL_CALL GridColumn::setColumnWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException) +{ + columnWidth = value; +} + +//-------------------------------------------------------------------- + +::rtl::OUString SAL_CALL GridColumn::getTitle() throw (::com::sun::star::uno::RuntimeException) +{ + return title; +} + +//-------------------------------------------------------------------- + +void SAL_CALL GridColumn::setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException) +{ + title = value; +} + +//--------------------------------------------------------------------- +// XComponent +//--------------------------------------------------------------------- + +void SAL_CALL GridColumn::dispose() throw (RuntimeException) +{ +} + +//--------------------------------------------------------------------- + +void SAL_CALL GridColumn::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + (void) xListener; +} + +//--------------------------------------------------------------------- + +void SAL_CALL GridColumn::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + (void) xListener; +} + +//--------------------------------------------------------------------- +// XServiceInfo +//--------------------------------------------------------------------- + +::rtl::OUString SAL_CALL GridColumn::getImplementationName( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.GridColumn" ) ); + return aImplName; +} + +//--------------------------------------------------------------------- + +sal_Bool SAL_CALL GridColumn::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return ServiceName.equalsAscii( szServiceName_GridColumn ); +} + +//--------------------------------------------------------------------- + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL GridColumn::getSupportedServiceNames( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aServiceName( OUString::createFromAscii( szServiceName_GridColumn ) ); + static const Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +} + +Reference< XInterface > SAL_CALL GridColumn_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::GridColumn ); +} + diff --git a/toolkit/source/controls/grid/gridcolumn.hxx b/toolkit/source/controls/grid/gridcolumn.hxx new file mode 100644 index 000000000000..a451054ce93f --- /dev/null +++ b/toolkit/source/controls/grid/gridcolumn.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: griddatamodel.hxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/grid/XGridColumn.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> +#include <rtl/ref.hxx> +#include <vector> +#include <toolkit/helper/mutexandbroadcasthelper.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; + +namespace toolkit +{ + +class GridColumn : public ::cppu::WeakImplHelper2< XGridColumn, XServiceInfo >, + public MutexAndBroadcastHelper +{ +public: + GridColumn(); + virtual ~GridColumn(); + + // XGridColumn + virtual ::com::sun::star::uno::Any SAL_CALL getIdentifier() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setIdentifier(const ::com::sun::star::uno::Any & value) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getColumnWidth() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setColumnWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTitle() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose( ) throw (RuntimeException); + virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + +private: + Any identifier; + sal_Int32 columnWidth; + ::rtl::OUString title; +}; + +} diff --git a/toolkit/source/controls/grid/gridcontrol.cxx b/toolkit/source/controls/grid/gridcontrol.cxx new file mode 100644 index 000000000000..c642d8a0dcce --- /dev/null +++ b/toolkit/source/controls/grid/gridcontrol.cxx @@ -0,0 +1,273 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: gridcontrol.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + +#include <gridcontrol.hxx> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/view/SelectionType.hpp> +#include <com/sun/star/awt/grid/XGridDataModel.hpp> +#include <com/sun/star/awt/grid/ScrollBarMode.hpp> +#include <toolkit/helper/unopropertyarrayhelper.hxx> +#include <toolkit/helper/property.hxx> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <comphelper/processfactory.hxx> +#include <osl/diagnose.h> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::view; + +namespace toolkit +{ +// ---------------------------------------------------- +// class UnoGridModel +// ---------------------------------------------------- +UnoGridModel::UnoGridModel() +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_SIZEABLE ); // resizeable + ImplRegisterProperty( BASEPROPERTY_HSCROLL ); + ImplRegisterProperty( BASEPROPERTY_VSCROLL ); + ImplRegisterProperty( BASEPROPERTY_GRID_SHOWROWHEADER ); + ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER ); + ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL ); + ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL ); + ImplRegisterProperty( BASEPROPERTY_GRID_SELECTIONMODE ); + +} + +UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) +: UnoControlModel( rModel ) +{ +} + +UnoControlModel* UnoGridModel::Clone() const +{ + return new UnoGridModel( *this ); +} + +OUString UnoGridModel::getServiceName() throw(RuntimeException) +{ + return OUString::createFromAscii( szServiceName_GridControlModel ); +} + +Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + switch( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_GridControl ) ); + case BASEPROPERTY_GRID_SELECTIONMODE: + return uno::makeAny( SelectionType(1) ); + default: + return UnoControlModel::ImplGetDefaultValue( nPropId ); + } + +} + +::cppu::IPropertyArrayHelper& UnoGridModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// XMultiPropertySet +Reference< XPropertySetInfo > UnoGridModel::getPropertySetInfo( ) throw(RuntimeException) +{ + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + +// ---------------------------------------------------- +// class UnoGridControl +// ---------------------------------------------------- +UnoGridControl::UnoGridControl() +: mSelectionMode(SelectionType(1)) +{ +} + +OUString UnoGridControl::GetComponentServiceName() +{ + return OUString::createFromAscii( "Grid" ); +} + +void SAL_CALL UnoGridControl::dispose( ) throw(RuntimeException) +{ + UnoControl::dispose(); +} + +void UnoGridControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoControlBase::createPeer( rxToolkit, rParentPeer ); + + Reference< XGridControl > xGrid( getPeer(), UNO_QUERY_THROW ); + + Reference<XGridDataListener> xListener ( getPeer(), UNO_QUERY_THROW ); + Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); + + Reference<XGridDataModel> xGridDataModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "GridDataModel" )), UNO_QUERY_THROW ); + xGridDataModel->addDataListener(xListener); +} + + +// ------------------------------------------------------------------- +// XGridControl +// ------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL UnoGridControl::getColumnModel() throw (::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); + Reference<XGridColumnModel> xGridColumnModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "ColumnModel" )), UNO_QUERY_THROW ); + + return xGridColumnModel; +} + +void SAL_CALL UnoGridControl::setColumnModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > & model) throw (::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); + xPropSet->setPropertyValue(OUString::createFromAscii( "ColumnModel" ), Any (model)); +} + +::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL UnoGridControl::getDataModel() throw (::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); + Reference<XGridDataModel> xGridDataModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "GridDataModel" )), UNO_QUERY_THROW ); + + return xGridDataModel; +} + +void SAL_CALL UnoGridControl::setDataModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > & model) throw (::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW ); + xPropSet->setPropertyValue(OUString::createFromAscii( "GridDataModel" ), Any(model)); +} + +::sal_Int32 UnoGridControl::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getItemIndexAtPoint( x, y ); +} + +/* +void SAL_CALL UnoGridControl::addMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->addMouseListener( listener ); +} + +void SAL_CALL UnoGridControl::removeMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->removeMouseListener( listener ); +} +*/ +// ------------------------------------------------------------------- +// XGridSelection +// ------------------------------------------------------------------- + +::sal_Int32 SAL_CALL UnoGridControl::getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getMinSelectionIndex(); +} + +::sal_Int32 SAL_CALL UnoGridControl::getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getMaxSelectionIndex(); +} + +void SAL_CALL UnoGridControl::insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->insertIndexIntervall( start, length); +} + +void SAL_CALL UnoGridControl::removeIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->removeIndexIntervall( start, length ); +} + +::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getSelection(); +} + +::sal_Bool SAL_CALL UnoGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectionEmpty(); +} + +::sal_Bool SAL_CALL UnoGridControl::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectedIndex( index ); +} + +void SAL_CALL UnoGridControl::selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectRow( y ); +} + +void SAL_CALL UnoGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->addSelectionListener( listener ); +} + +void SAL_CALL UnoGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->removeSelectionListener( listener ); +} +} + +Reference< XInterface > SAL_CALL GridControl_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridControl ); +} + +Reference< XInterface > SAL_CALL GridControlModel_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridModel ); +} diff --git a/toolkit/source/controls/grid/gridcontrol.hxx b/toolkit/source/controls/grid/gridcontrol.hxx new file mode 100644 index 000000000000..5648c812fbff --- /dev/null +++ b/toolkit/source/controls/grid/gridcontrol.hxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: gridcontrol.hxx,v $ + * $Revision: 1.3 $ + * + * 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 TOOLKIT_GRID_CONTROL_HXX +#define TOOLKIT_GRID_CONTROL_HXX + +#include <com/sun/star/awt/grid/XGridControl.hpp> +#include <com/sun/star/view/SelectionType.hpp> +#include <toolkit/controls/unocontrols.hxx> +#include <toolkit/controls/unocontrolmodel.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <toolkit/helper/listenermultiplexer.hxx> + +namespace toolkit { + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; + +// =================================================================== +// = UnoGridModel +// =================================================================== +class UnoGridModel : public UnoControlModel +{ +protected: + Any ImplGetDefaultValue( sal_uInt16 nPropId ) const; + ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); + +public: + UnoGridModel(); + UnoGridModel( const UnoGridModel& rModel ); + + UnoControlModel* Clone() const; + + // ::com::sun::star::beans::XMultiPropertySet + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::io::XPersistObject + ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + DECLIMPL_SERVICEINFO_DERIVED( UnoGridModel, UnoControlModel, szServiceName_GridControlModel ) +}; + + +// =================================================================== +// = UnoGridControl +// =================================================================== +class UnoGridControl : public ::cppu::ImplInheritanceHelper1< UnoControlBase, ::com::sun::star::awt::grid::XGridControl > +{ +public: + UnoGridControl(); + ::rtl::OUString GetComponentServiceName(); + + // ::com::sun::star::lang::XComponent + void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::XControl + void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::grid::XGridControl + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > SAL_CALL getColumnModel() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setColumnModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel > & model) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > SAL_CALL getDataModel() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDataModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > & model) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + //virtual void SAL_CALL addMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException); + //virtual void SAL_CALL removeMouseListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & listener) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::grid::XGridSelection + + virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insertIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeIndexIntervall(::sal_Int32 start, ::sal_Int32 length) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::lang::XServiceInfo + DECLIMPL_SERVICEINFO_DERIVED( UnoGridControl, UnoControlBase, szServiceName_GridControl ) + + using UnoControl::getPeer; +private: + ::com::sun::star::view::SelectionType mSelectionMode; +}; + +} // toolkit + +#endif // _TOOLKIT_TREE_CONTROL_HXX diff --git a/toolkit/source/controls/grid/makefile.mk b/toolkit/source/controls/grid/makefile.mk new file mode 100644 index 000000000000..7c904b3ef02e --- /dev/null +++ b/toolkit/source/controls/grid/makefile.mk @@ -0,0 +1,54 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# 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=grid + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/gridcontrol.obj\ + $(SLO)$/defaultgriddatamodel.obj\ + $(SLO)$/defaultgridcolumnmodel.obj\ + $(SLO)$/gridcolumn.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/toolkit/source/controls/makefile.mk b/toolkit/source/controls/makefile.mk new file mode 100644 index 000000000000..0194b96f634f --- /dev/null +++ b/toolkit/source/controls/makefile.mk @@ -0,0 +1,70 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.15 $ +# +# 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=controls + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/accessiblecontrolcontext.obj \ + $(SLO)$/geometrycontrolmodel.obj \ + $(SLO)$/eventcontainer.obj \ + $(SLO)$/stdtabcontroller.obj \ + $(SLO)$/stdtabcontrollermodel.obj \ + $(SLO)$/unocontrol.obj \ + $(SLO)$/unocontrolbase.obj \ + $(SLO)$/unocontrolcontainer.obj \ + $(SLO)$/unocontrolcontainermodel.obj \ + $(SLO)$/unocontrolmodel.obj \ + $(SLO)$/unocontrols.obj \ + $(SLO)$/formattedcontrol.obj \ + $(SLO)$/roadmapcontrol.obj \ + $(SLO)$/roadmapentry.obj \ + $(SLO)$/dialogcontrol.obj \ + $(SLO)$/tkscrollbar.obj \ + $(SLO)$/tkspinbutton.obj \ + $(SLO)$/tksimpleanimation.obj \ + $(SLO)$/tkthrobber.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/toolkit/source/controls/roadmapcontrol.cxx b/toolkit/source/controls/roadmapcontrol.cxx new file mode 100644 index 000000000000..da3a265130b8 --- /dev/null +++ b/toolkit/source/controls/roadmapcontrol.cxx @@ -0,0 +1,592 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: roadmapcontrol.cxx,v $ + * $Revision: 1.11 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + +#ifndef _TOOLKIT_ROADMAP_CONTROL_HXX +#include <toolkit/controls/roadmapcontrol.hxx> +#endif +#include <toolkit/helper/unopropertyarrayhelper.hxx> +#include <toolkit/helper/property.hxx> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <comphelper/processfactory.hxx> +#include <osl/diagnose.h> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::container; + +// ---------------------------------------------------- +// helper +// ---------------------------------------------------- + + static void lcl_knitImageComponents( const Reference< XControlModel >& _rxModel, + const Reference< XWindowPeer >& _rxPeer, + bool _bAdd ) + { + Reference< XImageProducer > xProducer( _rxModel, UNO_QUERY ); + if ( xProducer.is() ) + { + Reference< XImageConsumer > xConsumer( _rxPeer, UNO_QUERY ); + if ( xConsumer.is() ) + { + if ( _bAdd ) + { + xProducer->addConsumer( xConsumer ); + xProducer->startProduction(); + } + else + xProducer->removeConsumer( xConsumer ); + } + } + } + +static void lcl_throwIllegalArgumentException( ) +{ // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... + throw IllegalArgumentException(); +} + +static void lcl_throwIndexOutOfBoundsException( ) +{ // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... + throw IndexOutOfBoundsException(); +} + + // =================================================================== + // = UnoControlRoadmapModel + // =================================================================== + // ------------------------------------------------------------------- + UnoControlRoadmapModel::UnoControlRoadmapModel() : maContainerListeners( *this ) + { + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_IMAGEURL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_COMPLETE ); + ImplRegisterProperty( BASEPROPERTY_ACTIVATED ); + ImplRegisterProperty( BASEPROPERTY_CURRENTITEMID ); + ImplRegisterProperty( BASEPROPERTY_TABSTOP ); + ImplRegisterProperty( BASEPROPERTY_TEXT ); + } + + // ------------------------------------------------------------------- + ::rtl::OUString UnoControlRoadmapModel::getServiceName() throw(RuntimeException) + { + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmapModel ); + } + + + // ------------------------------------------------------------------- + Any UnoControlRoadmapModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const + { + Any aReturn; + switch (nPropId) + { + case BASEPROPERTY_COMPLETE: + aReturn <<= (sal_Bool) sal_True; + break; + case BASEPROPERTY_ACTIVATED: + aReturn <<= (sal_Bool) sal_True; + break; + case BASEPROPERTY_CURRENTITEMID: + aReturn <<= (sal_Int16) -1; + break; + case BASEPROPERTY_TEXT: + break; + case BASEPROPERTY_BORDER: + aReturn <<= (sal_Int16) 2; // No Border + break; + case BASEPROPERTY_DEFAULTCONTROL: + aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmap ) ); + break; + default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break; + } + + return aReturn; + } + + + Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstance( ) throw (Exception, ::com::sun::star::uno::RuntimeException) + { + ORoadmapEntry* pRoadmapItem = new ORoadmapEntry(); + Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem; + return xNewRoadmapItem; + } + + + Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstanceWithArguments( const Sequence< Any >& /*aArguments*/ ) throw (Exception, RuntimeException) + { + // Todo: implementation of the arguments handling + ORoadmapEntry* pRoadmapItem = new ORoadmapEntry(); + Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem; + return xNewRoadmapItem; + } + + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlRoadmapModel, UnoControlRoadmapModel_Base, UnoControlRoadmapModel_IBase ) + + + // ------------------------------------------------------------------- + ::com::sun::star::uno::Any SAL_CALL UnoControlRoadmapModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) + { + Any aRet = UnoControlRoadmapModel_Base::queryAggregation( rType ); + if ( !aRet.hasValue() ) + aRet = UnoControlRoadmapModel_IBase::queryInterface( rType ); + return aRet; + } + + + // ------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& UnoControlRoadmapModel::getInfoHelper() + { + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; + } + + + // beans::XMultiPropertySet + // ------------------------------------------------------------------- + Reference< XPropertySetInfo > UnoControlRoadmapModel::getPropertySetInfo( ) throw(RuntimeException) + { + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + + sal_Int32 SAL_CALL UnoControlRoadmapModel::getCount() throw(RuntimeException) + { + return maRoadmapItems.size(); + } + + Any SAL_CALL UnoControlRoadmapModel::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { + if (( Index >= (sal_Int32)maRoadmapItems.size()) || (Index < 0)) + lcl_throwIndexOutOfBoundsException( ); + Any aAny; + aAny = makeAny( maRoadmapItems.at( Index )); + return aAny; + } + + + + void UnoControlRoadmapModel::MakeRMItemValidation( sal_Int32 Index, Reference< XInterface > xRoadmapItem ) + { + if ((Index > (sal_Int32)maRoadmapItems.size()) || ( Index < 0 ) ) + lcl_throwIndexOutOfBoundsException( ); + if ( !xRoadmapItem.is() ) + lcl_throwIllegalArgumentException(); + Reference< XServiceInfo > xServiceInfo( xRoadmapItem, UNO_QUERY ); + sal_Bool bIsRoadmapItem = xServiceInfo->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.RoadmapItem" ) ); + if ( !bIsRoadmapItem ) + lcl_throwIllegalArgumentException(); + } + + + void UnoControlRoadmapModel::SetRMItemDefaultProperties( const sal_Int32 , Reference< XInterface > xRoadmapItem) + { + Any aAny; + Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY ); + Reference< XPropertySet > xProps( xRoadmapItem, UNO_QUERY ); + if ( xProps.is() ) + { + sal_Int32 LocID = 0; + Any aValue = xPropertySet->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) ); + aValue >>= LocID; + if (LocID < 0) // index may not be smaller than zero + { + aAny <<= GetUniqueID(); + xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "ID" ), aAny ); + } + } + } + + +// The performance of this method could certainly be improved. +// As long as only vectors with up to 10 elements are +// involved it should be sufficient + sal_Int32 UnoControlRoadmapModel::GetUniqueID() + { + Any aAny; + sal_Bool bIncrement = sal_True; + sal_Int32 CurID = 0; + sal_Int32 n_CurItemID = 0; + Reference< XInterface > CurRoadmapItem; + while ( bIncrement ) + { + bIncrement = sal_False; + for ( RoadmapItemHolderList::iterator i = maRoadmapItems.begin(); i < maRoadmapItems.end(); i++ ) + { + CurRoadmapItem = *i; + Reference< XPropertySet > xPropertySet( CurRoadmapItem, UNO_QUERY ); + aAny = xPropertySet->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) ); + aAny >>= n_CurItemID; + if (n_CurItemID == CurID) + { + bIncrement = sal_True; + CurID++; + break; + } + } + } + return CurID; + } + + + ContainerEvent UnoControlRoadmapModel::GetContainerEvent(sal_Int32 Index, Reference< XInterface > xRoadmapItem) + { + ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Element <<= xRoadmapItem; + aEvent.Accessor = makeAny(Index); + return aEvent; + } + + + sal_Int16 UnoControlRoadmapModel::GetCurrentItemID( Reference< XPropertySet > xPropertySet ) + { + Any aAny = xPropertySet->getPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ) ); + sal_Int16 n_CurrentItemID = 0; + aAny >>= n_CurrentItemID; + return n_CurrentItemID; + } + + + void SAL_CALL UnoControlRoadmapModel::insertByIndex( const sal_Int32 Index, const Any& _Element) + throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { + if ( ( Index >= ( (sal_Int32)maRoadmapItems.size() + 1 ) ) || (Index < 0)) + lcl_throwIndexOutOfBoundsException( ); + Reference< XInterface > xRoadmapItem; + _Element >>= xRoadmapItem; + MakeRMItemValidation( Index, xRoadmapItem); + SetRMItemDefaultProperties( Index, xRoadmapItem ); + maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); + ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); + maContainerListeners.elementInserted( aEvent ); + Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY ); + sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet ); + if ( Index <= n_CurrentItemID ) + { + Any aAny; + aAny <<= ( sal_Int16 ) ( n_CurrentItemID + 1 ); + xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); + } + } + + + + void SAL_CALL UnoControlRoadmapModel::removeByIndex( sal_Int32 Index) + throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { + if (( Index > (sal_Int32)maRoadmapItems.size()) || (Index < 0)) + lcl_throwIndexOutOfBoundsException( ); + Reference< XInterface > xRoadmapItem; + maRoadmapItems.erase( maRoadmapItems.begin() + Index ); + ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); + maContainerListeners.elementRemoved( aEvent ); + Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY ); + sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet ); + Any aAny; + if ( Index <= n_CurrentItemID ) + { + if ( n_CurrentItemID >= (sal_Int32)maRoadmapItems.size() ) + { + n_CurrentItemID = sal::static_int_cast< sal_Int16 >( + maRoadmapItems.size()-1); + if ( n_CurrentItemID < 0 ) + return; + aAny <<= n_CurrentItemID; + } + else if (Index == n_CurrentItemID) + aAny <<= ( sal_Int16 ) -1; + else if( Index < n_CurrentItemID) + aAny <<= ( sal_Int16 ) ( n_CurrentItemID - 1 ); + xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); + } + } + + + void SAL_CALL UnoControlRoadmapModel::replaceByIndex( const sal_Int32 Index, const Any& _Element) + throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { + Reference< XInterface > xRoadmapItem; + _Element >>= xRoadmapItem; + MakeRMItemValidation( Index, xRoadmapItem); + SetRMItemDefaultProperties( Index, xRoadmapItem ); + maRoadmapItems.erase( maRoadmapItems.begin() + Index ); + maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem); //push_back( xRoadmapItem ); + ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem); + maContainerListeners.elementReplaced( aEvent ); + } + + + Type SAL_CALL UnoControlRoadmapModel::getElementType() throw(RuntimeException) + { + Type aType = getCppuType( ( Reference< XPropertySet>* ) NULL ); + return aType; + } + + + sal_Bool SAL_CALL UnoControlRoadmapModel::hasElements() throw(RuntimeException) + { + return !maRoadmapItems.empty(); + } + + + void SAL_CALL UnoControlRoadmapModel::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) + { + maContainerListeners.addInterface( xListener ); + } + + void SAL_CALL UnoControlRoadmapModel::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) + { + maContainerListeners.removeInterface( xListener ); + } + + + void UnoControlRoadmapModel::addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException) + { + maImageListeners.push_back( xConsumer ); + } + + + void UnoControlRoadmapModel::removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException) + { + maImageListeners.remove( xConsumer ); + } + + + void UnoControlRoadmapModel::startProduction( ) throw (::com::sun::star::uno::RuntimeException) + { + Sequence<Any> aArgs(1); + aArgs.getArray()[0] = getPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEURL ) ); + Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + Reference< XImageProducer > xImageProducer( xMSF->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "com.sun.star.awt.ImageProducer" ), aArgs ), UNO_QUERY ); + if ( xImageProducer.is() ) + { + std::list< Reference< XImageConsumer > >::iterator aIter( maImageListeners.begin() ); + while ( aIter != maImageListeners.end() ) + { + xImageProducer->addConsumer( *aIter ); + aIter++; + } + xImageProducer->startProduction(); + } + } + + + + + // =================================================================== + // = UnoRoadmapControl + // =================================================================== + // ------------------------------------------------------------------- + UnoRoadmapControl::UnoRoadmapControl(): maItemListeners( *this ) + { + } + +IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase ) +IMPLEMENT_FORWARD_XINTERFACE2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase ) + + +sal_Bool SAL_CALL UnoRoadmapControl::setModel(const Reference< XControlModel >& _rModel) throw ( RuntimeException ) + { + + + // remove the peer as image consumer from the model + lcl_knitImageComponents( getModel(), getPeer(), false ); + + Reference< XContainer > xC( getModel(), UNO_QUERY ); + if ( xC.is() ) + xC->removeContainerListener( this ); + + sal_Bool bReturn = UnoControlBase::setModel( _rModel ); + + xC = xC.query( getModel()); + if ( xC.is() ) + xC->addContainerListener( this ); + + // add the peer as image consumer to the model + lcl_knitImageComponents( getModel(), getPeer(), true ); + + return bReturn; + } + + + // ------------------------------------------------------------------- + ::rtl::OUString UnoRoadmapControl::GetComponentServiceName() + { + return ::rtl::OUString::createFromAscii( "Roadmap" ); + } + + + + void SAL_CALL UnoRoadmapControl::createPeer( const Reference<XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) + { + // remove the peer as image consumer from the model + lcl_knitImageComponents( getModel(), getPeer(), false ); + + UnoControl::createPeer( rxToolkit, rParentPeer ); + + lcl_knitImageComponents( getModel(), getPeer(), true ); + + } + + + void UnoRoadmapControl::dispose() throw(RuntimeException) + { + EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maItemListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); + } + + + +void UnoRoadmapControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal ) +{ + sal_uInt16 nType = GetPropertyId( rPropName ); + if ( getPeer().is() && ( nType == BASEPROPERTY_IMAGEURL ) ) + { + Reference < XImageProducer > xImgProd( getModel(), UNO_QUERY ); + Reference < XImageConsumer > xImgCons( getPeer(), UNO_QUERY ); + + if ( xImgProd.is() && xImgCons.is() ) + { + xImgProd->startProduction(); + } + } + else + UnoControlBase::ImplSetPeerProperty( rPropName, rVal ); +} + + +void UnoRoadmapControl::elementInserted( const ContainerEvent& rEvent )throw(RuntimeException) +{ + Reference< XInterface > xRoadmapItem; + rEvent.Element >>= xRoadmapItem; + Reference< XPropertySet > xRoadmapPropertySet( xRoadmapItem, UNO_QUERY ); + if ( xRoadmapPropertySet.is() ) + xRoadmapPropertySet->addPropertyChangeListener( rtl::OUString(), this ); + + Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); + if ( xPeer.is() ) + { + xPeer->elementInserted( rEvent ); + Reference < XPropertySet > xPropertySet( xPeer, UNO_QUERY ); + if ( xPropertySet.is() ) + xPropertySet->addPropertyChangeListener( rtl::OUString(), this ); + } +} + + +void UnoRoadmapControl::elementRemoved( const ContainerEvent& rEvent )throw(RuntimeException) +{ + Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); + if ( xPeer.is() ) + xPeer->elementRemoved( rEvent ); + Reference< XInterface > xRoadmapItem; + rEvent.Element >>= xRoadmapItem; + Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY ); + if ( xPropertySet.is() ) + xPropertySet->removePropertyChangeListener( rtl::OUString(), this ); +} + + +void UnoRoadmapControl::elementReplaced( const ContainerEvent& rEvent )throw(RuntimeException) +{ + Reference< XContainerListener > xPeer(getPeer(), UNO_QUERY); + if ( xPeer.is() ) + xPeer->elementReplaced( rEvent ); +} + + +void SAL_CALL UnoRoadmapControl::itemStateChanged( const ItemEvent& rEvent ) throw (RuntimeException) +{ + sal_Int16 CurItemIndex = sal::static_int_cast< sal_Int16 >(rEvent.ItemId); + Any aAny; + aAny <<= CurItemIndex; + Reference< XControlModel > xModel( getModel( ), UNO_QUERY ); + Reference< XPropertySet > xPropertySet( xModel, UNO_QUERY ); + xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny ); + if ( maItemListeners.getLength() ) + maItemListeners.itemStateChanged( rEvent ); +} + + +void SAL_CALL UnoRoadmapControl::addItemListener( const Reference< XItemListener >& l ) throw (RuntimeException) +{ + maItemListeners.addInterface( l ); + if( getPeer().is() && maItemListeners.getLength() == 1 ) + { + Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY ); + xRoadmap->addItemListener( this ); + } +} + + +void SAL_CALL UnoRoadmapControl::removeItemListener( const Reference< XItemListener >& l ) throw (RuntimeException) +{ + if( getPeer().is() && maItemListeners.getLength() == 1 ) + { + Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY ); + xRoadmap->removeItemListener( this ); + } + + maItemListeners.removeInterface( l ); +} + + +void SAL_CALL UnoRoadmapControl::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException) +{ + Reference< XPropertyChangeListener > xPeer(getPeer(), UNO_QUERY); + if ( xPeer.is() ) + xPeer->propertyChange( evt ); +} + +} + diff --git a/toolkit/source/controls/roadmapentry.cxx b/toolkit/source/controls/roadmapentry.cxx new file mode 100644 index 000000000000..4fb0d44cf131 --- /dev/null +++ b/toolkit/source/controls/roadmapentry.cxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: roadmapentry.cxx,v $ + * $Revision: 1.5 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <toolkit/controls/roadmapentry.hxx> + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/OUString.hxx> +#endif + + +#include <com/sun/star/beans/PropertyAttribute.hpp> + + +ORoadmapEntry::ORoadmapEntry() : ORoadmapEntry_Base( ) + ,OPropertyContainer( GetBroadcastHelper() ) +{ + // registerProperty or registerMayBeVoidProperty or registerPropertyNoMember + + registerProperty( ::rtl::OUString::createFromAscii( "Label" ), RM_PROPERTY_ID_LABEL, + ::com::sun::star::beans::PropertyAttribute::BOUND | + ::com::sun::star::beans::PropertyAttribute::CONSTRAINED, + & m_sLabel, ::getCppuType( &m_sLabel ) ); + m_nID = -1; + registerProperty( ::rtl::OUString::createFromAscii( "ID" ), RM_PROPERTY_ID_ID, + ::com::sun::star::beans::PropertyAttribute::BOUND | + ::com::sun::star::beans::PropertyAttribute::CONSTRAINED, + & m_nID, ::getCppuType( &m_nID ) ); + m_bEnabled = sal_True; + registerProperty( ::rtl::OUString::createFromAscii( "Enabled" ), RM_PROPERTY_ID_ENABLED, + ::com::sun::star::beans::PropertyAttribute::BOUND | + ::com::sun::star::beans::PropertyAttribute::MAYBEDEFAULT, + & m_bEnabled, ::getCppuType( &m_bEnabled ) ); + + registerProperty( ::rtl::OUString::createFromAscii( "Interactive" ), RM_PROPERTY_ID_INTERACTIVE, + ::com::sun::star::beans::PropertyAttribute::BOUND | + ::com::sun::star::beans::PropertyAttribute::MAYBEDEFAULT, + & m_bInteractive, ::getCppuType( &m_bInteractive ) ); + + + // ... + + // Note that the list of registered properties has to be fixed: Different + // instances of this class have to register the same set of properties with + // the same attributes. + // + // This is because all instances of the class share the same PropertySetInfo + // which has been built from the registered property of _one_ instance. +} + +//-------------------------------------------------------------------------- +IMPLEMENT_FORWARD_XINTERFACE2( ORoadmapEntry, ORoadmapEntry_Base, ::comphelper::OPropertyContainer ); +IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORoadmapEntry, ORoadmapEntry_Base, ::comphelper::OPropertyContainer ); + // order matters: + // the first is the class name + // the second is the class which implements the ref-counting + // the third up to n-th (when using IMPLEMENT_FORWARD_*3 and so on) are other base classes + // whose XInterface and XTypeProvider implementations should be merged + +//-------------------------------------------------------------------------- +::com::sun::star::uno::Reference< ::com::sun::star:: beans::XPropertySetInfo > SAL_CALL + ORoadmapEntry::getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException) +{ + return ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >( + createPropertySetInfo( getInfoHelper() ) ); +} + +::rtl::OUString SAL_CALL ORoadmapEntry::getImplementationName( ) throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString aStr = ::rtl::OUString::createFromAscii("com.sun.star.comp.toolkit.RoadmapItem"); + return aStr; +} + +sal_Bool SAL_CALL ORoadmapEntry::supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException) +{ + return ServiceName.equals( ::rtl::OUString::createFromAscii( "com.sun.star.awt.RoadmapItem" ) ); +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ORoadmapEntry::getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Sequence< ::rtl::OUString > aRet(1); + ::rtl::OUString* pArray = aRet.getArray(); + pArray[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.RoadmapItem" ); + return aRet; +} +//-------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper& ORoadmapEntry::getInfoHelper() +{ + return *getArrayHelper(); +} + +//-------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper* ORoadmapEntry::createArrayHelper() const +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps; + // describes all properties which have been registered in the ctor + describeProperties( aProps ); + + return new ::cppu::OPropertyArrayHelper( aProps ); +} diff --git a/toolkit/source/controls/stdtabcontroller.cxx b/toolkit/source/controls/stdtabcontroller.cxx new file mode 100644 index 000000000000..c9a85f3f7eb7 --- /dev/null +++ b/toolkit/source/controls/stdtabcontroller.cxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: stdtabcontroller.cxx,v $ + * $Revision: 1.12 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XVclContainerPeer.hpp> + +#include <toolkit/controls/stdtabcontroller.hxx> +#include <toolkit/controls/stdtabcontrollermodel.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/macros.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <rtl/memory.h> +#include <rtl/uuid.h> + +#include <tools/debug.hxx> +#include <vcl/window.hxx> +#include <comphelper/sequence.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +// ---------------------------------------------------- +// class StdTabController +// ---------------------------------------------------- +StdTabController::StdTabController() +{ +} + +StdTabController::~StdTabController() +{ +} + +sal_Bool StdTabController::ImplCreateComponentSequence( + Sequence< Reference< XControl > >& rControls, + const Sequence< Reference< XControlModel > >& rModels, + Sequence< Reference< XWindow > >& rComponents, + Sequence< Any>* pTabStops, + sal_Bool bPeerComponent ) const +{ + sal_Bool bOK = sal_True; + + // nur die wirklich geforderten Controls + sal_Int32 nModels = rModels.getLength(); + if (nModels != rControls.getLength()) + { + Sequence< Reference< XControl > > aSeq( nModels ); + const Reference< XControlModel >* pModels = rModels.getConstArray(); + Reference< XControl > xCurrentControl; + + sal_Int32 nRealControls = 0; + for (sal_Int32 n = 0; n < nModels; ++n, ++pModels) + { + xCurrentControl = FindControl(rControls, *pModels); + if (xCurrentControl.is()) + aSeq.getArray()[nRealControls++] = xCurrentControl; + } + aSeq.realloc(nRealControls); + rControls = aSeq; + } +#ifdef DBG_UTIL + DBG_ASSERT( rControls.getLength() <= rModels.getLength(), "StdTabController:ImplCreateComponentSequence: inconsistence!" ); + // there may be less controls than models, but never more controls than models +#endif + + + const Reference< XControl > * pControls = rControls.getConstArray(); + sal_uInt32 nCtrls = rControls.getLength(); + rComponents.realloc( nCtrls ); + Reference< XWindow > * pComps = rComponents.getArray(); + Any* pTabs = NULL; + + + if ( pTabStops ) + { + *pTabStops = Sequence< Any>( nCtrls ); + pTabs = pTabStops->getArray(); + } + + for ( sal_uInt32 n = 0; bOK && ( n < nCtrls ); n++ ) + { + // Zum Model passendes Control suchen + Reference< XControl > xCtrl(pControls[n]); + if ( xCtrl.is() ) + { + if (bPeerComponent) + pComps[n] = Reference< XWindow > (xCtrl->getPeer(), UNO_QUERY); + else + pComps[n] = Reference< XWindow > (xCtrl, UNO_QUERY); + + // TabStop-Property + if ( pTabs ) + { + // opt: String fuer TabStop als Konstante + static const ::rtl::OUString aTabStopName( ::rtl::OUString::createFromAscii( "Tabstop" ) ); + + Reference< XPropertySet > xPSet( xCtrl->getModel(), UNO_QUERY ); + Reference< XPropertySetInfo > xInfo = xPSet->getPropertySetInfo(); + if( xInfo->hasPropertyByName( aTabStopName ) ) + *pTabs++ = xPSet->getPropertyValue( aTabStopName ); + else + ++pTabs; + } + } + else + { + DBG_TRACE( "ImplCreateComponentSequence: Control not found" ); + bOK = sal_False; + } + } + return bOK; +} + +void StdTabController::ImplActivateControl( sal_Bool bFirst ) const +{ + // HACK wegen #53688#, muss auf ein Interface abgebildet werden, wenn Controls Remote liegen koennen. + Reference< XTabController > xTabController(const_cast< ::cppu::OWeakObject* >(static_cast< const ::cppu::OWeakObject* >(this)), UNO_QUERY); + Sequence< Reference< XControl > > aCtrls = xTabController->getControls(); + const Reference< XControl > * pControls = aCtrls.getConstArray(); + sal_uInt32 nCount = aCtrls.getLength(); + + for ( sal_uInt32 n = bFirst ? 0 : nCount; bFirst ? ( n < nCount ) : n; ) + { + sal_uInt32 nCtrl = bFirst ? n++ : --n; + DBG_ASSERT( pControls[nCtrl].is(), "Control nicht im Container!" ); + if ( pControls[nCtrl].is() ) + { + Reference< XWindowPeer > xCP = pControls[nCtrl]->getPeer(); + if ( xCP.is() ) + { + VCLXWindow* pC = VCLXWindow::GetImplementation( xCP ); + if ( pC && pC->GetWindow() && ( pC->GetWindow()->GetStyle() & WB_TABSTOP ) ) + { + pC->GetWindow()->GrabFocus(); + break; + } + } + } + } +} + +// XInterface +Any StdTabController::queryAggregation( const Type & rType ) throw(RuntimeException) +{ + Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( XTabController*, this ), + SAL_STATIC_CAST( XServiceInfo*, this ), + SAL_STATIC_CAST( XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType )); +} + +// XTypeProvider +IMPL_XTYPEPROVIDER_START( StdTabController ) + getCppuType( ( Reference< XTabController>* ) NULL ), + getCppuType( ( Reference< XServiceInfo>* ) NULL ) +IMPL_XTYPEPROVIDER_END + +void StdTabController::setModel( const Reference< XTabControllerModel >& Model ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + mxModel = Model; +} + +Reference< XTabControllerModel > StdTabController::getModel( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return mxModel; +} + +void StdTabController::setContainer( const Reference< XControlContainer >& Container ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + mxControlContainer = Container; +} + +Reference< XControlContainer > StdTabController::getContainer( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return mxControlContainer; +} + +Sequence< Reference< XControl > > StdTabController::getControls( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + Sequence< Reference< XControl > > aSeq; + + if ( mxControlContainer.is() ) + { + Sequence< Reference< XControlModel > > aModels = mxModel->getControlModels(); + const Reference< XControlModel > * pModels = aModels.getConstArray(); + + Sequence< Reference< XControl > > xCtrls = mxControlContainer->getControls(); + + sal_uInt32 nCtrls = aModels.getLength(); + aSeq = Sequence< Reference< XControl > >( nCtrls ); + for ( sal_uInt32 n = 0; n < nCtrls; n++ ) + { + Reference< XControlModel > xCtrlModel = pModels[n]; + // Zum Model passendes Control suchen + Reference< XControl > xCtrl = FindControl( xCtrls, xCtrlModel ); + aSeq.getArray()[n] = xCtrl; + } + } + return aSeq; +} + +void StdTabController::autoTabOrder( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + DBG_ASSERT( mxControlContainer.is(), "autoTabOrder: No ControlContainer!" ); + if ( !mxControlContainer.is() ) + return; + + Sequence< Reference< XControlModel > > aSeq = mxModel->getControlModels(); + Sequence< Reference< XWindow > > aCompSeq; + + // vieleicht erhalte ich hier einen TabController, + // der schneller die Liste meiner Controls ermittelt + Reference< XTabController > xTabController(static_cast< ::cppu::OWeakObject* >(this), UNO_QUERY); + Sequence< Reference< XControl > > aControls = xTabController->getControls(); + + // #58317# Es sind ggf. noch nicht alle Controls fuer die Models im Container, + // dann kommt spaeter nochmal ein autoTabOrder... + if( !ImplCreateComponentSequence( aControls, aSeq, aCompSeq, NULL, sal_False ) ) + return; + + sal_uInt32 nCtrls = aCompSeq.getLength(); + Reference< XWindow > * pComponents = aCompSeq.getArray(); + + ComponentEntryList aCtrls; + sal_uInt32 n; + for ( n = 0; n < nCtrls; n++ ) + { + XWindow* pC = (XWindow*)pComponents[n].get(); + ComponentEntry* pE = new ComponentEntry; + pE->pComponent = pC; + awt::Rectangle aPosSize = pC->getPosSize(); + pE->aPos.X() = aPosSize.X; + pE->aPos.Y() = aPosSize.Y; + + sal_uInt16 nPos; + for ( nPos = 0; nPos < aCtrls.Count(); nPos++ ) + { + ComponentEntry* pEntry = aCtrls.GetObject( nPos ); + if ( pEntry->aPos.Y() >= pE->aPos.Y() ) + { + while ( pEntry && ( pEntry->aPos.Y() == pE->aPos.Y() ) + && ( pEntry->aPos.X() < pE->aPos.X() ) ) + { + pEntry = aCtrls.GetObject( ++nPos ); + } + break; + } + } + aCtrls.Insert( pE, nPos ); + } + + Sequence< Reference< XControlModel > > aNewSeq( nCtrls ); + for ( n = 0; n < nCtrls; n++ ) + { + ComponentEntry* pE = aCtrls.GetObject( n ); + Reference< XControl > xUC( pE->pComponent, UNO_QUERY ); + aNewSeq.getArray()[n] = xUC->getModel(); + delete pE; + } + aCtrls.Clear(); + + mxModel->setControlModels( aNewSeq ); +} + +void StdTabController::activateTabOrder( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + // Am Container die Tab-Reihenfolge aktivieren... + + Reference< XControl > xC( mxControlContainer, UNO_QUERY ); + Reference< XVclContainerPeer > xVclContainerPeer; + if ( xC.is() ) + xVclContainerPeer = xVclContainerPeer.query( xC->getPeer() ); + if ( !xC.is() || !xVclContainerPeer.is() ) + return; + + // vieleicht erhalte ich hier einen TabController, + // der schneller die Liste meiner Controls ermittelt + Reference< XTabController > xTabController(static_cast< ::cppu::OWeakObject* >(this), UNO_QUERY); + + // Flache Liste besorgen... + Sequence< Reference< XControlModel > > aModels = mxModel->getControlModels(); + Sequence< Reference< XWindow > > aCompSeq; + Sequence< Any> aTabSeq; + + // DG: Aus Optimierungsgruenden werden die Controls mittels getControls() geholt, + // dieses hoert sich zwar wiedersinning an, fuehrt aber im konkreten Fall (Forms) zu sichtbaren + // Geschwindigkeitsvorteilen + Sequence< Reference< XControl > > aControls = xTabController->getControls(); + + // #58317# Es sind ggf. noch nicht alle Controls fuer die Models im Container, + // dann kommt spaeter nochmal ein activateTabOrder... + if( !ImplCreateComponentSequence( aControls, aModels, aCompSeq, &aTabSeq, sal_True ) ) + return; + + xVclContainerPeer->setTabOrder( aCompSeq, aTabSeq, mxModel->getGroupControl() ); + + ::rtl::OUString aName; + Sequence< Reference< XControlModel > > aThisGroupModels; + Sequence< Reference< XWindow > > aControlComponents; + + sal_uInt32 nGroups = mxModel->getGroupCount(); + for ( sal_uInt32 nG = 0; nG < nGroups; nG++ ) + { + mxModel->getGroup( nG, aThisGroupModels, aName ); + + aControls = xTabController->getControls(); + // ImplCreateComponentSequence has a really strange semantics regarding it's first parameter: + // upon method entry, it expects a super set of the controls which it returns + // this means we need to completely fill this sequence with all available controls before + // calling into ImplCreateComponentSequence + + aControlComponents.realloc( 0 ); + + ImplCreateComponentSequence( aControls, aThisGroupModels, aControlComponents, NULL, sal_True ); + xVclContainerPeer->setGroup( aControlComponents ); + } +} + +void StdTabController::activateFirst( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ImplActivateControl( sal_True ); +} + +void StdTabController::activateLast( ) throw(RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ImplActivateControl( sal_False ); +} + + +Reference< XControl > StdTabController::FindControl( Sequence< Reference< XControl > >& rCtrls, + const Reference< XControlModel > & rxCtrlModel ) +{ + +/* + // MT: Funktioniert nicht mehr, weil ich nicht mehr bei mir angemeldet bin, + // weil DG das abfaengt. + + // #54677# Beim Laden eines HTML-Dokuments wird nach jedem Control ein + // activateTabOrder gerufen und jede Menge Zeit in dieser Methode verbraten. + // Die Anzahl dieser Schleifendurchlaufe steigt quadratisch, also versuchen + // das Control direkt vom Model zu erhalten. + // => Wenn genau ein Control als PropertyChangeListener angemeldet ist, + // dann muss das auch das richtige sein. + + UnoControlModel* pUnoCtrlModel = UnoControlModel::GetImplementation( rxCtrlModel ); + + + if ( pUnoCtrlModel ) + { + ListenerIterator aIt( pUnoCtrlModel->maPropertiesListeners ); + while( aIt.hasMoreElements() ) + { + XEventListener* pL = aIt.next(); + Reference< XControl > xC( pL, UNO_QUERY ); + if ( xC.is() ) + { + if( xC->getContext() == mxControlContainer ) + { + xCtrl = xC; + break; + } + } + } + } + if ( !xCtrl.is() && rxCtrlModel.is()) +*/ + DBG_ASSERT( rxCtrlModel.is(), "ImplFindControl - welches ?!" ); + + const Reference< XControl > * pCtrls = rCtrls.getConstArray(); + sal_Int32 nCtrls = rCtrls.getLength(); + for ( sal_Int32 n = 0; n < nCtrls; n++ ) + { + Reference< XControlModel > xModel(pCtrls[n].is() ? pCtrls[n]->getModel() : Reference< XControlModel > ()); + if ( (XControlModel*)xModel.get() == (XControlModel*)rxCtrlModel.get() ) + { + Reference< XControl > xCtrl( pCtrls[n] ); + ::comphelper::removeElementAt( rCtrls, n ); + return xCtrl; + } + } + return Reference< XControl > (); +} diff --git a/toolkit/source/controls/stdtabcontrollermodel.cxx b/toolkit/source/controls/stdtabcontrollermodel.cxx new file mode 100644 index 000000000000..5dee86da18e4 --- /dev/null +++ b/toolkit/source/controls/stdtabcontrollermodel.cxx @@ -0,0 +1,411 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: stdtabcontrollermodel.cxx,v $ + * $Revision: 1.6 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/io/XMarkableStream.hpp> + +#include <toolkit/controls/stdtabcontrollermodel.hxx> +#include <toolkit/helper/macros.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <toolkit/helper/property.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <rtl/memory.h> +#include <rtl/uuid.h> + +#include <tools/debug.hxx> + +#define UNOCONTROL_STREAMVERSION (short)2 + +// ---------------------------------------------------- +// class UnoControlModelEntryList +// ---------------------------------------------------- +UnoControlModelEntryList::UnoControlModelEntryList() +{ +} + +UnoControlModelEntryList::~UnoControlModelEntryList() +{ + Reset(); +} + +void UnoControlModelEntryList::Reset() +{ + for ( sal_uInt32 n = Count(); n; ) + DestroyEntry( --n ); +} + +void UnoControlModelEntryList::DestroyEntry( sal_uInt32 nEntry ) +{ + UnoControlModelEntry* pEntry = GetObject( nEntry ); + + if ( pEntry->bGroup ) + delete pEntry->pGroup; + else + delete pEntry->pxControl; + + Remove( nEntry ); + delete pEntry; +} + +// ---------------------------------------------------- +// class StdTabControllerModel +// ---------------------------------------------------- +StdTabControllerModel::StdTabControllerModel() +{ + mbGroupControl = sal_True; +} + +StdTabControllerModel::~StdTabControllerModel() +{ +} + +sal_uInt32 StdTabControllerModel::ImplGetControlCount( const UnoControlModelEntryList& rList ) const +{ + sal_uInt32 nCount = 0; + sal_uInt32 nEntries = rList.Count(); + for ( sal_uInt32 n = 0; n < nEntries; n++ ) + { + UnoControlModelEntry* pEntry = rList.GetObject( n ); + if ( pEntry->bGroup ) + nCount += ImplGetControlCount( *pEntry->pGroup ); + else + nCount++; + } + return nCount; +} + +void StdTabControllerModel::ImplGetControlModels( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > ** ppRefs, const UnoControlModelEntryList& rList ) const +{ + sal_uInt32 nEntries = rList.Count(); + for ( sal_uInt32 n = 0; n < nEntries; n++ ) + { + UnoControlModelEntry* pEntry = rList.GetObject( n ); + if ( pEntry->bGroup ) + ImplGetControlModels( ppRefs, *pEntry->pGroup ); + else + { + **ppRefs = *pEntry->pxControl; + (*ppRefs)++; + } + } +} + +void StdTabControllerModel::ImplSetControlModels( UnoControlModelEntryList& rList, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Controls ) const +{ + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = Controls.getConstArray(); + sal_uInt32 nControls = Controls.getLength(); + for ( sal_uInt32 n = 0; n < nControls; n++ ) + { + UnoControlModelEntry* pNewEntry = new UnoControlModelEntry; + pNewEntry->bGroup = sal_False; + pNewEntry->pxControl = new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > ; + *pNewEntry->pxControl = pRefs[n]; + rList.Insert( pNewEntry, LIST_APPEND ); + } +} + +sal_uInt32 StdTabControllerModel::ImplGetControlPos( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xCtrl, const UnoControlModelEntryList& rList ) const +{ + for ( sal_uInt32 n = rList.Count(); n; ) + { + UnoControlModelEntry* pEntry = rList.GetObject( --n ); + if ( !pEntry->bGroup && ( *pEntry->pxControl == xCtrl ) ) + return n; + } + return CONTROLPOS_NOTFOUND; +} + +void ImplWriteControls( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream > & OutStream, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& rCtrls ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY ); + DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" ); + + sal_uInt32 nStoredControls = 0; + sal_Int32 nDataBeginMark = xMark->createMark(); + + OutStream->writeLong( 0L ); // DataLen + OutStream->writeLong( 0L ); // nStoredControls + + sal_uInt32 nCtrls = rCtrls.getLength(); + for ( sal_uInt32 n = 0; n < nCtrls; n++ ) + { + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xI = rCtrls.getConstArray()[n]; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject > xPO( xI, ::com::sun::star::uno::UNO_QUERY ); + DBG_ASSERT( xPO.is(), "write: Control doesn't support XPersistObject" ); + if ( xPO.is() ) + { + OutStream->writeObject( xPO ); + nStoredControls++; + } + } + sal_Int32 nDataLen = xMark->offsetToMark( nDataBeginMark ); + xMark->jumpToMark( nDataBeginMark ); + OutStream->writeLong( nDataLen ); + OutStream->writeLong( nStoredControls ); + xMark->jumpToFurthest(); + xMark->deleteMark(nDataBeginMark); +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > ImplReadControls( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream > & InStream ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( InStream, ::com::sun::star::uno::UNO_QUERY ); + DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" ); + + sal_Int32 nDataBeginMark = xMark->createMark(); + + sal_Int32 nDataLen = InStream->readLong(); + sal_uInt32 nCtrls = InStream->readLong(); + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq( nCtrls ); + for ( sal_uInt32 n = 0; n < nCtrls; n++ ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject > xObj = InStream->readObject(); + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xI( xObj, ::com::sun::star::uno::UNO_QUERY ); + aSeq.getArray()[n] = xI; + } + + // Falls bereits mehr drinsteht als diese Version kennt: + xMark->jumpToMark( nDataBeginMark ); + InStream->skipBytes( nDataLen ); + xMark->deleteMark(nDataBeginMark); + return aSeq; +} + + +// ::com::sun::star::uno::XInterface +::com::sun::star::uno::Any StdTabControllerModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XTabControllerModel*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XServiceInfo*, this ), + SAL_STATIC_CAST( ::com::sun::star::io::XPersistObject*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( StdTabControllerModel ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject>* ) NULL ) +IMPL_XTYPEPROVIDER_END + +sal_Bool StdTabControllerModel::getGroupControl( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return mbGroupControl; +} + +void StdTabControllerModel::setGroupControl( sal_Bool GroupControl ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + mbGroupControl = GroupControl; +} + +void StdTabControllerModel::setControlModels( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Controls ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + maControls.Reset(); + ImplSetControlModels( maControls, Controls ); +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > StdTabControllerModel::getControlModels( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq( ImplGetControlCount( maControls ) ); + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = aSeq.getArray(); + ImplGetControlModels( &pRefs, maControls ); + return aSeq; +} + +void StdTabControllerModel::setGroup( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Group, const ::rtl::OUString& GroupName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + // Die Controls stehen eventuel flach in der Liste und werden jetzt gruppiert. + // Verschachtelte Gruppen sind erstmal nicht moeglich... + // Das erste Element der Gruppe welches auch schon in der flachen Liste + // stand bestimmt die Position der Gruppe. + + UnoControlModelEntry* pNewEntry = new UnoControlModelEntry; + pNewEntry->bGroup = sal_True; + pNewEntry->pGroup = new UnoControlModelEntryList; + pNewEntry->pGroup->SetName( GroupName ); + ImplSetControlModels( *pNewEntry->pGroup, Group ); + + sal_Bool bInserted = sal_False; + sal_uInt32 nElements = pNewEntry->pGroup->Count(); + for ( sal_uInt32 n = 0; n < nElements; n++ ) + { + UnoControlModelEntry* pEntry = pNewEntry->pGroup->GetObject( n ); + if ( !pEntry->bGroup ) + { + sal_uInt32 nPos = ImplGetControlPos( *pEntry->pxControl, maControls ); + // Eigentlich sollten alle Controls vorher in der flachen Liste stehen + DBG_ASSERT( nPos != CONTROLPOS_NOTFOUND, "setGroup - Element not found" ); + if ( nPos != CONTROLPOS_NOTFOUND ) + { + maControls.DestroyEntry( nPos ); + if ( !bInserted ) + { + maControls.Insert( pNewEntry, nPos ); + bInserted = sal_True; + } + } + } + } + if ( !bInserted ) + maControls.Insert( pNewEntry, LIST_APPEND ); +} + +sal_Int32 StdTabControllerModel::getGroupCount( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + // erstmal nur eine Ebene... + // Das Model und die Impl-Methoden arbeiten zwar rekursiv, aber das wird + // erstmal nich nach aussen gegeben. + + sal_Int32 nGroups = 0; + sal_uInt32 nEntries = maControls.Count(); + for ( sal_uInt32 n = 0; n < nEntries; n++ ) + { + UnoControlModelEntry* pEntry = maControls.GetObject( n ); + if ( pEntry->bGroup ) + nGroups++; + } + return nGroups; +} + +void StdTabControllerModel::getGroup( sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& rGroup, ::rtl::OUString& rName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq; + sal_uInt32 nG = 0; + sal_uInt32 nEntries = maControls.Count(); + for ( sal_uInt32 n = 0; n < nEntries; n++ ) + { + UnoControlModelEntry* pEntry = maControls.GetObject( n ); + if ( pEntry->bGroup ) + { + if ( nG == (sal_uInt32)nGroup ) + { + sal_uInt32 nCount = ImplGetControlCount( *pEntry->pGroup ); + aSeq = ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >( nCount ); + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = aSeq.getArray(); + ImplGetControlModels( &pRefs, *pEntry->pGroup ); + rName = pEntry->pGroup->GetName(); + break; + } + nG++; + } + } + rGroup = aSeq; +} + +void StdTabControllerModel::getGroupByName( const ::rtl::OUString& rName, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& rGroup ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_uInt32 nGroup = 0; + sal_uInt32 nEntries = maControls.Count(); + for ( sal_uInt32 n = 0; n < nEntries; n++ ) + { + UnoControlModelEntry* pEntry = maControls.GetObject( n ); + if ( pEntry->bGroup ) + { + if ( pEntry->pGroup->GetName() == rName ) + { + ::rtl::OUString Dummy; + getGroup( nGroup, rGroup, Dummy ); + break; + } + nGroup++; + } + } +} + + +// ::com::sun::star::io::XPersistObject +::rtl::OUString StdTabControllerModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_TabControllerModel ); +} + +void StdTabControllerModel::write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY ); + DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" ); + + OutStream->writeShort( UNOCONTROL_STREAMVERSION ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aCtrls = getControlModels(); + ImplWriteControls( OutStream, aCtrls ); + + sal_uInt32 nGroups = getGroupCount(); + OutStream->writeLong( nGroups ); + for ( sal_uInt32 n = 0; n < nGroups; n++ ) + { + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aGroupCtrls; + ::rtl::OUString aGroupName; + getGroup( n, aGroupCtrls, aGroupName ); + OutStream->writeUTF( aGroupName ); + ImplWriteControls( OutStream, aGroupCtrls ); + } +} + +void StdTabControllerModel::read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq = ImplReadControls( InStream ); + setControlModels( aSeq ); + + sal_uInt32 nGroups = InStream->readLong(); + for ( sal_uInt32 n = 0; n < nGroups; n++ ) + { + ::rtl::OUString aGroupName = InStream->readUTF(); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aCtrlSeq = ImplReadControls( InStream ); + setGroup( aCtrlSeq, aGroupName ); + } +} + + + + + diff --git a/toolkit/source/controls/tkscrollbar.cxx b/toolkit/source/controls/tkscrollbar.cxx new file mode 100644 index 000000000000..f2940526d320 --- /dev/null +++ b/toolkit/source/controls/tkscrollbar.cxx @@ -0,0 +1,297 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tkscrollbar.cxx,v $ + * $Revision: 1.9 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "toolkit/controls/tkscrollbar.hxx" +#include "toolkit/helper/property.hxx" +#include "toolkit/helper/unopropertyarrayhelper.hxx" +#include <cppuhelper/typeprovider.hxx> +#include <tools/debug.hxx> + +// for introspection +#include <toolkit/awt/vclxwindows.hxx> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using namespace ::com::sun::star; + + //==================================================================== + //= UnoControlScrollBarModel + //==================================================================== + //-------------------------------------------------------------------- + UnoControlScrollBarModel::UnoControlScrollBarModel() + { + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXScrollBar ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoControlScrollBarModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) + { + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlScrollBarModel ); + } + + //-------------------------------------------------------------------- + uno::Any UnoControlScrollBarModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const + { + switch ( nPropId ) + { + case BASEPROPERTY_LIVE_SCROLL: + return uno::makeAny( (sal_Bool)sal_False ); + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoControlScrollBar ) ); + + default: + return UnoControlModel::ImplGetDefaultValue( nPropId ); + } + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& UnoControlScrollBarModel::getInfoHelper() + { + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; + } + + //-------------------------------------------------------------------- + uno::Reference< beans::XPropertySetInfo > UnoControlScrollBarModel::getPropertySetInfo( ) throw(uno::RuntimeException) + { + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + + //==================================================================== + //= UnoControlScrollBarModel + //==================================================================== + UnoScrollBarControl::UnoScrollBarControl() + : maAdjustmentListeners( *this ) + { + } + + ::rtl::OUString UnoScrollBarControl::GetComponentServiceName() + { + return ::rtl::OUString::createFromAscii( "ScrollBar" ); + } + + // ::com::sun::star::uno::XInterface + uno::Any UnoScrollBarControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) + { + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XAdjustmentListener*, this ), + SAL_STATIC_CAST( awt::XScrollBar*, this ) ); + return (aRet.hasValue() ? aRet : UnoControlBase::queryAggregation( rType )); + } + + // ::com::sun::star::lang::XTypeProvider + IMPL_XTYPEPROVIDER_START( UnoScrollBarControl ) + getCppuType( ( uno::Reference< awt::XAdjustmentListener>* ) NULL ), + getCppuType( ( uno::Reference< awt::XScrollBar>* ) NULL ), + UnoControlBase::getTypes() + IMPL_XTYPEPROVIDER_END + + void UnoScrollBarControl::dispose() throw(uno::RuntimeException) + { + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maAdjustmentListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); + } + + void UnoScrollBarControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) + { + UnoControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + xScrollBar->addAdjustmentListener( this ); + } + + // ::com::sun::star::awt::XAdjustmentListener + void UnoScrollBarControl::adjustmentValueChanged( const ::com::sun::star::awt::AdjustmentEvent& rEvent ) throw(::com::sun::star::uno::RuntimeException) + { + switch ( rEvent.Type ) + { + case ::com::sun::star::awt::AdjustmentType_ADJUST_LINE: + case ::com::sun::star::awt::AdjustmentType_ADJUST_PAGE: + case ::com::sun::star::awt::AdjustmentType_ADJUST_ABS: + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + + if ( xScrollBar.is() ) + { + uno::Any aAny; + aAny <<= xScrollBar->getValue(); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SCROLLVALUE ), aAny, sal_False ); + } + } + break; + default: + { + DBG_ERROR( "UnoScrollBarControl::adjustmentValueChanged - unknown Type" ); + + } + } + + if ( maAdjustmentListeners.getLength() ) + maAdjustmentListeners.adjustmentValueChanged( rEvent ); + } + + // ::com::sun::star::awt::XScrollBar + void UnoScrollBarControl::addAdjustmentListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XAdjustmentListener > & l ) throw(::com::sun::star::uno::RuntimeException) + { + maAdjustmentListeners.addInterface( l ); + } + + void UnoScrollBarControl::removeAdjustmentListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XAdjustmentListener > & l ) throw(::com::sun::star::uno::RuntimeException) + { + maAdjustmentListeners.removeInterface( l ); + } + + void UnoScrollBarControl::setValue( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SCROLLVALUE ), uno::makeAny( n ), sal_True ); + } + + void UnoScrollBarControl::setValues( sal_Int32 nValue, sal_Int32 nVisible, sal_Int32 nMax ) throw(::com::sun::star::uno::RuntimeException) + { + uno::Any aAny; + aAny <<= nValue; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SCROLLVALUE ), aAny, sal_True ); + aAny <<= nVisible; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VISIBLESIZE ), aAny, sal_True ); + aAny <<= nMax; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SCROLLVALUE_MAX ), aAny, sal_True ); + } + + sal_Int32 UnoScrollBarControl::getValue() throw(::com::sun::star::uno::RuntimeException) + { + sal_Int32 n = 0; + if ( getPeer().is() ) + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + n = xScrollBar->getValue(); + } + return n; + } + + void UnoScrollBarControl::setMaximum( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SCROLLVALUE_MAX ), uno::makeAny( n ), sal_True ); + } + + sal_Int32 UnoScrollBarControl::getMaximum() throw(::com::sun::star::uno::RuntimeException) + { + sal_Int32 n = 0; + if ( getPeer().is() ) + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + n = xScrollBar->getMaximum(); + } + return n; + } + + void UnoScrollBarControl::setLineIncrement( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LINEINCREMENT ), uno::makeAny( n ), sal_True ); + } + + sal_Int32 UnoScrollBarControl::getLineIncrement() throw(::com::sun::star::uno::RuntimeException) + { + sal_Int32 n = 0; + if ( getPeer().is() ) + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + n = xScrollBar->getLineIncrement(); + } + return n; + } + + void UnoScrollBarControl::setBlockIncrement( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_BLOCKINCREMENT ), uno::makeAny( n ), sal_True ); + } + + sal_Int32 UnoScrollBarControl::getBlockIncrement() throw(::com::sun::star::uno::RuntimeException) + { + sal_Int32 n = 0; + if ( getPeer().is() ) + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + n = xScrollBar->getBlockIncrement(); + } + return n; + } + + void UnoScrollBarControl::setVisibleSize( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VISIBLESIZE ), uno::makeAny( n ), sal_True ); + } + + sal_Int32 UnoScrollBarControl::getVisibleSize() throw(::com::sun::star::uno::RuntimeException) + { + sal_Int32 n = 0; + if ( getPeer().is() ) + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + n = xScrollBar->getVisibleSize(); + } + return n; + } + + void UnoScrollBarControl::setOrientation( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_ORIENTATION ), uno::makeAny( n ), sal_True ); + } + + sal_Int32 UnoScrollBarControl::getOrientation() throw(::com::sun::star::uno::RuntimeException) + { + sal_Int32 n = 0; + if ( getPeer().is() ) + { + uno::Reference< awt::XScrollBar > xScrollBar( getPeer(), uno::UNO_QUERY ); + n = xScrollBar->getOrientation(); + } + return n; + } + + + +//........................................................................ +} // namespace toolkit +//........................................................................ + diff --git a/toolkit/source/controls/tksimpleanimation.cxx b/toolkit/source/controls/tksimpleanimation.cxx new file mode 100644 index 000000000000..8d83b3a953d9 --- /dev/null +++ b/toolkit/source/controls/tksimpleanimation.cxx @@ -0,0 +1,214 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tksimpleanimation.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "toolkit/controls/tksimpleanimation.hxx" +#include "toolkit/helper/property.hxx" +#include "toolkit/helper/unopropertyarrayhelper.hxx" +#include <cppuhelper/typeprovider.hxx> +#include <tools/debug.hxx> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using namespace ::com::sun::star; + + //==================================================================== + //= UnoSimpleAnimationControlModel + //==================================================================== + //-------------------------------------------------------------------- + UnoSimpleAnimationControlModel::UnoSimpleAnimationControlModel() + { + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_REPEAT ); + ImplRegisterProperty( BASEPROPERTY_STEP_TIME ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoSimpleAnimationControlModel::getServiceName() + throw( uno::RuntimeException ) + { + return ::rtl::OUString::createFromAscii( szServiceName_UnoSimpleAnimationControlModel ); + } + + //-------------------------------------------------------------------- + uno::Any UnoSimpleAnimationControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const + { + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoSimpleAnimationControl ) ); + + case BASEPROPERTY_STEP_TIME: + return uno::makeAny( (sal_Int32) 100 ); + + case BASEPROPERTY_REPEAT: + return uno::makeAny( (sal_Bool)sal_True ); + + default: + return UnoControlModel::ImplGetDefaultValue( nPropId ); + } + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& UnoSimpleAnimationControlModel::getInfoHelper() + { + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence< sal_Int32 > aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; + } + + //-------------------------------------------------------------------- + uno::Reference< beans::XPropertySetInfo > UnoSimpleAnimationControlModel::getPropertySetInfo( ) + throw( uno::RuntimeException ) + { + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL UnoSimpleAnimationControlModel::getImplementationName() + throw( uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.toolkit.UnoSimpleAnimationControlModel" ) ); + } + + //-------------------------------------------------------------------- + uno::Sequence< ::rtl::OUString > SAL_CALL UnoSimpleAnimationControlModel::getSupportedServiceNames() + throw( uno::RuntimeException ) + { + uno::Sequence< ::rtl::OUString > aServices( UnoControlModel::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_UnoSimpleAnimationControlModel ); + return aServices; + } + + //==================================================================== + //= UnoSimpleAnimationControl + //==================================================================== + //-------------------------------------------------------------------- + UnoSimpleAnimationControl::UnoSimpleAnimationControl() + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoSimpleAnimationControl::GetComponentServiceName() + { + return ::rtl::OUString::createFromAscii( "SimpleAnimation" ); + } + + //-------------------------------------------------------------------- + uno::Any UnoSimpleAnimationControl::queryAggregation( const uno::Type & rType ) + throw( uno::RuntimeException ) + { + uno::Any aRet = UnoControlBase::queryAggregation( rType ); + if ( !aRet.hasValue() ) + aRet = UnoSimpleAnimationControl_Base::queryInterface( rType ); + return aRet; + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoSimpleAnimationControl, UnoControlBase, UnoSimpleAnimationControl_Base ) + + //-------------------------------------------------------------------- + void UnoSimpleAnimationControl::dispose() throw( uno::RuntimeException ) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + + UnoControl::dispose(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL UnoSimpleAnimationControl::getImplementationName() + throw( uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.toolkit.UnoSimpleAnimationControl" ) ); + } + + //-------------------------------------------------------------------- + uno::Sequence< ::rtl::OUString > SAL_CALL UnoSimpleAnimationControl::getSupportedServiceNames() + throw( uno::RuntimeException ) + { + uno::Sequence< ::rtl::OUString > aServices( UnoControlBase::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_UnoSimpleAnimationControl ); + return aServices; + } + + //-------------------------------------------------------------------- + void UnoSimpleAnimationControl::createPeer( const uno::Reference< awt::XToolkit > &rxToolkit, + const uno::Reference< awt::XWindowPeer > &rParentPeer ) + throw( uno::RuntimeException ) + { + UnoControl::createPeer( rxToolkit, rParentPeer ); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSimpleAnimationControl::start() throw ( uno::RuntimeException ) + { + ::osl::MutexGuard aGuard( GetMutex() ); + + uno::Reference< XSimpleAnimation > xAnimation( getPeer(), uno::UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->start(); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSimpleAnimationControl::stop() throw ( uno::RuntimeException ) + { + ::osl::MutexGuard aGuard( GetMutex() ); + + uno::Reference< XSimpleAnimation > xAnimation( getPeer(), uno::UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->stop(); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSimpleAnimationControl::setImageList( const uno::Sequence< uno::Reference< graphic::XGraphic > >& ImageList ) + throw ( uno::RuntimeException ) + { + ::osl::MutexGuard aGuard( GetMutex() ); + + uno::Reference< XSimpleAnimation > xAnimation( getPeer(), uno::UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->setImageList( ImageList ); + } + +//........................................................................ +} // namespace toolkit +//........................................................................ + diff --git a/toolkit/source/controls/tkspinbutton.cxx b/toolkit/source/controls/tkspinbutton.cxx new file mode 100644 index 000000000000..138b849a190c --- /dev/null +++ b/toolkit/source/controls/tkspinbutton.cxx @@ -0,0 +1,353 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tkspinbutton.cxx,v $ + * $Revision: 1.6 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "toolkit/controls/tkspinbutton.hxx" +#include "toolkit/helper/property.hxx" +#include "toolkit/helper/unopropertyarrayhelper.hxx" +#include <com/sun/star/awt/ScrollBarOrientation.hpp> + + +#include <cppuhelper/typeprovider.hxx> +#include <tools/debug.hxx> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + + //==================================================================== + //= UnoSpinButtonModel + //==================================================================== + //-------------------------------------------------------------------- + UnoSpinButtonModel::UnoSpinButtonModel() + { + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_ORIENTATION ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_REPEAT ); + ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY ); + ImplRegisterProperty( BASEPROPERTY_SYMBOL_COLOR ); + ImplRegisterProperty( BASEPROPERTY_SPINVALUE ); + ImplRegisterProperty( BASEPROPERTY_SPINVALUE_MIN ); + ImplRegisterProperty( BASEPROPERTY_SPINVALUE_MAX ); + ImplRegisterProperty( BASEPROPERTY_SPININCREMENT ); + ImplRegisterProperty( BASEPROPERTY_TABSTOP ); + ImplRegisterProperty( BASEPROPERTY_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoSpinButtonModel::getServiceName( ) throw (RuntimeException) + { + return ::rtl::OUString::createFromAscii( szServiceName_UnoSpinButtonModel ); + } + + //-------------------------------------------------------------------- + Any UnoSpinButtonModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const + { + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoSpinButtonControl ) ); + + case BASEPROPERTY_BORDER: + return makeAny( (sal_Int16) 0 ); + + case BASEPROPERTY_REPEAT: + return makeAny( (sal_Bool)sal_True ); + + default: + return UnoControlModel::ImplGetDefaultValue( nPropId ); + } + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& UnoSpinButtonModel::getInfoHelper() + { + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; + } + + //-------------------------------------------------------------------- + Reference< XPropertySetInfo > UnoSpinButtonModel::getPropertySetInfo( ) throw(RuntimeException) + { + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL UnoSpinButtonModel::getImplementationName( ) throw(RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.toolkit.UnoSpinButtonModel" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL UnoSpinButtonModel::getSupportedServiceNames() throw(RuntimeException) + { + Sequence< ::rtl::OUString > aServices( UnoControlModel::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_UnoSpinButtonModel ); + return aServices; + } + + //==================================================================== + //= UnoSpinButtonControl + //==================================================================== + //-------------------------------------------------------------------- + UnoSpinButtonControl::UnoSpinButtonControl() + :maAdjustmentListeners( *this ) + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoSpinButtonControl::GetComponentServiceName() + { + return ::rtl::OUString::createFromAscii( "SpinButton" ); + } + + //-------------------------------------------------------------------- + Any UnoSpinButtonControl::queryAggregation( const Type & rType ) throw(RuntimeException) + { + Any aRet = UnoControlBase::queryAggregation( rType ); + if ( !aRet.hasValue() ) + aRet = UnoSpinButtonControl_Base::queryInterface( rType ); + return aRet; + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoSpinButtonControl, UnoControlBase, UnoSpinButtonControl_Base ) + + //-------------------------------------------------------------------- + void UnoSpinButtonControl::dispose() throw(RuntimeException) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + if ( maAdjustmentListeners.getLength() ) + { + Reference< XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + xSpinnable->removeAdjustmentListener( this ); + + EventObject aDisposeEvent; + aDisposeEvent.Source = *this; + + aGuard.clear(); + maAdjustmentListeners.disposeAndClear( aDisposeEvent ); + } + + UnoControl::dispose(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL UnoSpinButtonControl::getImplementationName( ) throw(RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.toolkit.UnoSpinButtonControl" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL UnoSpinButtonControl::getSupportedServiceNames() throw(RuntimeException) + { + Sequence< ::rtl::OUString > aServices( UnoControlBase::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_UnoSpinButtonControl ); + return aServices; + } + + //-------------------------------------------------------------------- + void UnoSpinButtonControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) + { + UnoControl::createPeer( rxToolkit, rParentPeer ); + + Reference < XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + xSpinnable->addAdjustmentListener( this ); + } + + //-------------------------------------------------------------------- + void UnoSpinButtonControl::adjustmentValueChanged( const AdjustmentEvent& rEvent ) throw(RuntimeException) + { + switch ( rEvent.Type ) + { + case AdjustmentType_ADJUST_LINE: + case AdjustmentType_ADJUST_PAGE: + case AdjustmentType_ADJUST_ABS: + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE ), makeAny( rEvent.Value ), sal_False ); + break; + default: + DBG_ERROR( "UnoSpinButtonControl::adjustmentValueChanged - unknown Type" ); + } + + if ( maAdjustmentListeners.getLength() ) + { + AdjustmentEvent aEvent( rEvent ); + aEvent.Source = *this; + maAdjustmentListeners.adjustmentValueChanged( aEvent ); + } + } + + //-------------------------------------------------------------------- + void UnoSpinButtonControl::addAdjustmentListener( const Reference< XAdjustmentListener > & listener ) throw(RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + maAdjustmentListeners.addInterface( listener ); + } + + //-------------------------------------------------------------------- + void UnoSpinButtonControl::removeAdjustmentListener( const Reference< XAdjustmentListener > & listener ) throw(RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + maAdjustmentListeners.removeInterface( listener ); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSpinButtonControl::setValue( sal_Int32 value ) throw (RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE ), makeAny( value ), sal_True ); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSpinButtonControl::setValues( sal_Int32 minValue, sal_Int32 maxValue, sal_Int32 currentValue ) throw (RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE_MIN ), makeAny( minValue ), sal_True ); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE_MAX ), makeAny( maxValue ), sal_True ); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE ), makeAny( currentValue ), sal_True ); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL UnoSpinButtonControl::getValue( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + sal_Int32 nValue = 0; + + Reference< XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + nValue = xSpinnable->getValue(); + + return nValue; + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSpinButtonControl::setMinimum( sal_Int32 minValue ) throw (RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE_MIN ), makeAny( minValue ), sal_True ); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSpinButtonControl::setMaximum( sal_Int32 maxValue ) throw (RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPINVALUE_MAX ), makeAny( maxValue ), sal_True ); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL UnoSpinButtonControl::getMinimum( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + sal_Int32 nMin = 0; + + Reference< XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + nMin = xSpinnable->getMinimum(); + + return nMin; + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL UnoSpinButtonControl::getMaximum( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + sal_Int32 nMax = 0; + + Reference< XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + nMax = xSpinnable->getMaximum(); + + return nMax; + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSpinButtonControl::setSpinIncrement( sal_Int32 spinIncrement ) throw (RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SPININCREMENT ), makeAny( spinIncrement ), sal_True ); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL UnoSpinButtonControl::getSpinIncrement( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + sal_Int32 nIncrement = 0; + + Reference< XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + nIncrement = xSpinnable->getSpinIncrement(); + + return nIncrement; + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoSpinButtonControl::setOrientation( sal_Int32 orientation ) throw (NoSupportException, RuntimeException) + { + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_ORIENTATION ), makeAny( orientation ), sal_True ); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL UnoSpinButtonControl::getOrientation( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( GetMutex() ); + sal_Int32 nOrientation = ScrollBarOrientation::HORIZONTAL; + + Reference< XSpinValue > xSpinnable( getPeer(), UNO_QUERY ); + if ( xSpinnable.is() ) + nOrientation = xSpinnable->getOrientation(); + + return nOrientation; + } + +//........................................................................ +} // namespace toolkit +//........................................................................ + diff --git a/toolkit/source/controls/tkthrobber.cxx b/toolkit/source/controls/tkthrobber.cxx new file mode 100644 index 000000000000..153a19bf38c9 --- /dev/null +++ b/toolkit/source/controls/tkthrobber.cxx @@ -0,0 +1,193 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tkthrobber.cxx,v $ + * $Revision: 1.5 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include "toolkit/controls/tkthrobber.hxx" +#include "toolkit/helper/property.hxx" +#include "toolkit/helper/unopropertyarrayhelper.hxx" +#include <cppuhelper/typeprovider.hxx> +#include <tools/debug.hxx> + +//........................................................................ +namespace toolkit +{ +//........................................................................ + + using namespace ::com::sun::star; + + //==================================================================== + //= UnoThrobberControlModel + //==================================================================== + //-------------------------------------------------------------------- + UnoThrobberControlModel::UnoThrobberControlModel() + { + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoThrobberControlModel::getServiceName( ) throw ( uno::RuntimeException ) + { + return ::rtl::OUString::createFromAscii( szServiceName_UnoThrobberControlModel ); + } + + //-------------------------------------------------------------------- + uno::Any UnoThrobberControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const + { + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoThrobberControl ) ); + default: + return UnoControlModel::ImplGetDefaultValue( nPropId ); + } + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& UnoThrobberControlModel::getInfoHelper() + { + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence< sal_Int32 > aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; + } + + //-------------------------------------------------------------------- + uno::Reference< beans::XPropertySetInfo > UnoThrobberControlModel::getPropertySetInfo() + throw( uno::RuntimeException ) + { + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL UnoThrobberControlModel::getImplementationName() + throw( uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.toolkit.UnoThrobberControlModel" ) ); + } + + //-------------------------------------------------------------------- + uno::Sequence< ::rtl::OUString > SAL_CALL UnoThrobberControlModel::getSupportedServiceNames() + throw( uno::RuntimeException ) + { + uno::Sequence< ::rtl::OUString > aServices( UnoControlModel::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_UnoThrobberControlModel ); + return aServices; + } + + //==================================================================== + //= UnoThrobberControl + //==================================================================== + //-------------------------------------------------------------------- + UnoThrobberControl::UnoThrobberControl() + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString UnoThrobberControl::GetComponentServiceName() + { + return ::rtl::OUString::createFromAscii( "Throbber" ); + } + + //-------------------------------------------------------------------- + uno::Any UnoThrobberControl::queryAggregation( const uno::Type & rType ) throw( uno::RuntimeException ) + { + uno::Any aRet = UnoControlBase::queryAggregation( rType ); + if ( !aRet.hasValue() ) + aRet = UnoThrobberControl_Base::queryInterface( rType ); + return aRet; + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoThrobberControl, UnoControlBase, UnoThrobberControl_Base ) + + //-------------------------------------------------------------------- + void UnoThrobberControl::dispose() throw( uno::RuntimeException ) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + + UnoControl::dispose(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL UnoThrobberControl::getImplementationName() + throw( uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.toolkit.UnoThrobberControl" ) ); + } + + //-------------------------------------------------------------------- + uno::Sequence< ::rtl::OUString > SAL_CALL UnoThrobberControl::getSupportedServiceNames() + throw( uno::RuntimeException ) + { + uno::Sequence< ::rtl::OUString > aServices( UnoControlBase::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_UnoThrobberControl ); + return aServices; + } + + //-------------------------------------------------------------------- + void UnoThrobberControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, + const uno::Reference< awt::XWindowPeer > & rParentPeer ) + throw( uno::RuntimeException ) + { + UnoControl::createPeer( rxToolkit, rParentPeer ); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoThrobberControl::start() throw ( uno::RuntimeException ) + { + ::osl::MutexGuard aGuard( GetMutex() ); + + uno::Reference< XThrobber > xAnimation( getPeer(), uno::UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->start(); + } + + //-------------------------------------------------------------------- + void SAL_CALL UnoThrobberControl::stop() throw ( uno::RuntimeException ) + { + ::osl::MutexGuard aGuard( GetMutex() ); + + uno::Reference< XThrobber > xAnimation( getPeer(), uno::UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->stop(); + } + +//........................................................................ +} // namespace toolkit +//........................................................................ + diff --git a/toolkit/source/controls/tree/makefile.mk b/toolkit/source/controls/tree/makefile.mk new file mode 100644 index 000000000000..89e6f87d9fde --- /dev/null +++ b/toolkit/source/controls/tree/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# 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=tree + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/treecontrol.obj\ + $(SLO)$/treedatamodel.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/toolkit/source/controls/tree/treecontrol.cxx b/toolkit/source/controls/tree/treecontrol.cxx new file mode 100644 index 000000000000..2949954bb13c --- /dev/null +++ b/toolkit/source/controls/tree/treecontrol.cxx @@ -0,0 +1,505 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treecontrol.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + +#ifndef _TOOLKIT_TREE_CONTROL_HXX +#include <treecontrol.hxx> +#endif + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/view/SelectionType.hpp> +#include <com/sun/star/awt/tree/XTreeDataModel.hpp> +#include <toolkit/helper/unopropertyarrayhelper.hxx> +#include <toolkit/helper/property.hxx> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <comphelper/processfactory.hxx> +#include <osl/diagnose.h> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt::tree; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::view; + +namespace toolkit +{ +// ---------------------------------------------------- +// class UnoTreeModel +// ---------------------------------------------------- +UnoTreeModel::UnoTreeModel() +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_TREE_SELECTIONTYPE ); + ImplRegisterProperty( BASEPROPERTY_TREE_EDITABLE ); + ImplRegisterProperty( BASEPROPERTY_TREE_DATAMODEL ); + ImplRegisterProperty( BASEPROPERTY_TREE_ROOTDISPLAYED ); + ImplRegisterProperty( BASEPROPERTY_TREE_SHOWSHANDLES ); + ImplRegisterProperty( BASEPROPERTY_TREE_SHOWSROOTHANDLES ); + ImplRegisterProperty( BASEPROPERTY_TREE_ROWHEIGHT ); + ImplRegisterProperty( BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING ); +} + +UnoTreeModel::UnoTreeModel( const UnoTreeModel& rModel ) +: UnoControlModel( rModel ) +{ +} + +UnoControlModel* UnoTreeModel::Clone() const +{ + return new UnoTreeModel( *this ); +} + +OUString UnoTreeModel::getServiceName() throw(RuntimeException) +{ + return OUString::createFromAscii( szServiceName_TreeControlModel ); +} + +Any UnoTreeModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + switch( nPropId ) + { + case BASEPROPERTY_TREE_SELECTIONTYPE: + return Any( SelectionType_NONE ); + case BASEPROPERTY_TREE_ROWHEIGHT: + return Any( sal_Int32( 0 ) ); + case BASEPROPERTY_TREE_DATAMODEL: + return Any( Reference< XTreeDataModel >( 0 ) ); + case BASEPROPERTY_TREE_EDITABLE: + case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: + return Any( sal_False ); + case BASEPROPERTY_TREE_ROOTDISPLAYED: + case BASEPROPERTY_TREE_SHOWSROOTHANDLES: + case BASEPROPERTY_TREE_SHOWSHANDLES: + return Any( sal_True ); + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_TreeControl ) ); + default: + return UnoControlModel::ImplGetDefaultValue( nPropId ); + } +} + +::cppu::IPropertyArrayHelper& UnoTreeModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// XMultiPropertySet +Reference< XPropertySetInfo > UnoTreeModel::getPropertySetInfo( ) throw(RuntimeException) +{ + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + +// ---------------------------------------------------- +// class UnoTreeControl +// ---------------------------------------------------- +UnoTreeControl::UnoTreeControl() +: maSelectionListeners( *this ) +, maTreeExpansionListeners( *this ) +, maTreeEditListeners( *this ) +{ +} + +OUString UnoTreeControl::GetComponentServiceName() +{ + return OUString::createFromAscii( "Tree" ); +} + +// ------------------------------------------------------------------- +// ::com::sun::star::view::XSelectionSupplier +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->select( rSelection ); +} + +// ------------------------------------------------------------------- + +Any SAL_CALL UnoTreeControl::getSelection() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getSelection(); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) +{ + maSelectionListeners.addInterface( xListener ); + if( getPeer().is() && (maSelectionListeners.getLength() == 1) ) + { + // maSelectionListeners acts as a proxy, + // add it to the peer if this is the first listener added to that proxy + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addSelectionChangeListener(&maSelectionListeners); + } +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) +{ + if( getPeer().is() && (maSelectionListeners.getLength() == 1) ) + { + // maSelectionListeners acts as a proxy, + // remove it from the peer if this is the last listener removed from that proxy + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeSelectionChangeListener(&maSelectionListeners); + } + maSelectionListeners.removeInterface( xListener ); +} + +// ------------------------------------------------------------------- +// ::com::sun::star::view::XMultiSelectionSupplier +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->addSelection(rSelection); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeSelection(rSelection); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::clearSelection() throw (RuntimeException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->clearSelection(); +} + +// ------------------------------------------------------------------- + +sal_Int32 SAL_CALL UnoTreeControl::getSelectionCount() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getSelectionCount(); +} + +// ------------------------------------------------------------------- + +Reference< XEnumeration > SAL_CALL UnoTreeControl::createSelectionEnumeration() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->createSelectionEnumeration(); +} + +// ------------------------------------------------------------------- + +Reference< XEnumeration > SAL_CALL UnoTreeControl::createReverseSelectionEnumeration() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->createReverseSelectionEnumeration(); +} + +// -------------------------------------------------------------------- +// XTreeControl +// -------------------------------------------------------------------- + +OUString SAL_CALL UnoTreeControl::getDefaultExpandedGraphicURL() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getDefaultExpandedGraphicURL(); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::setDefaultExpandedGraphicURL( const OUString& _defaultexpansiongraphicurl ) throw (RuntimeException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->setDefaultExpandedGraphicURL(_defaultexpansiongraphicurl); +} + +// ------------------------------------------------------------------- + +OUString SAL_CALL UnoTreeControl::getDefaultCollapsedGraphicURL() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getDefaultCollapsedGraphicURL(); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::setDefaultCollapsedGraphicURL( const OUString& _defaultcollapsedgraphicurl ) throw (RuntimeException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->setDefaultCollapsedGraphicURL(_defaultcollapsedgraphicurl); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeExpanded(xNode); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeCollapsed(xNode); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->makeNodeVisible(xNode); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeVisible(xNode); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->expandNode(xNode); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->collapseNode(xNode); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) +{ + maTreeExpansionListeners.addInterface( xListener ); + if( getPeer().is() && (maTreeExpansionListeners.getLength() == 1) ) + { + // maSelectionListeners acts as a proxy, + // add it to the peer if this is the first listener added to that proxy + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addTreeExpansionListener(&maTreeExpansionListeners); + } +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) +{ + if( getPeer().is() && (maTreeExpansionListeners.getLength() == 1) ) + { + // maSelectionListeners acts as a proxy, + // remove it from the peer if this is the last listener removed from that proxy + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeTreeExpansionListener(&maTreeExpansionListeners); + } + maTreeExpansionListeners.removeInterface( xListener ); +} + +// ------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL UnoTreeControl::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getNodeForLocation(x,y); +} + +// ------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL UnoTreeControl::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getClosestNodeForLocation(x,y); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::isEditing( ) throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isEditing(); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL UnoTreeControl::stopEditing() throw (RuntimeException) +{ + return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->stopEditing(); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::cancelEditing() throw (RuntimeException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->cancelEditing(); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException) +{ + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->startEditingAtNode(xNode); +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) +{ + maTreeEditListeners.addInterface( xListener ); + if( getPeer().is() && (maTreeEditListeners.getLength() == 1) ) + { + // maSelectionListeners acts as a proxy, + // add it to the peer if this is the first listener added to that proxy + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addTreeEditListener(&maTreeEditListeners); + } +} + +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) +{ + if( getPeer().is() && (maTreeEditListeners.getLength() == 1) ) + { + // maSelectionListeners acts as a proxy, + // remove it from the peer if this is the last listener removed from that proxy + Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); + Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeTreeEditListener(&maTreeEditListeners); + } + maTreeEditListeners.removeInterface( xListener ); +} + +// ------------------------------------------------------------------- +// XComponent +// ------------------------------------------------------------------- + +void SAL_CALL UnoTreeControl::dispose( ) throw(RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = static_cast< ::cppu::OWeakObject* >(this); + maSelectionListeners.disposeAndClear( aEvt ); + maTreeExpansionListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); +} + +void UnoTreeControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoControlBase::createPeer( rxToolkit, rParentPeer ); + + Reference< XTreeControl > xTree( getPeer(), UNO_QUERY_THROW ); + if( maSelectionListeners.getLength() ) + xTree->addSelectionChangeListener( &maSelectionListeners ); + if( maTreeExpansionListeners.getLength() ) + xTree->addTreeExpansionListener( &maTreeExpansionListeners ); +} + +} + +Reference< XInterface > SAL_CALL TreeControl_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoTreeControl ); +} + +Reference< XInterface > SAL_CALL TreeControlModel_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoTreeModel ); +} + +void SAL_CALL TreeEditListenerMultiplexer::nodeEditing( const Reference< XTreeNode >& Node ) throw (RuntimeException, ::com::sun::star::util::VetoException) +{ + ::cppu::OInterfaceIteratorHelper aIt( *this ); + while( aIt.hasMoreElements() ) + { + Reference< XTreeEditListener > xListener(static_cast< XTreeEditListener* >( aIt.next() ) ); + try + { + xListener->nodeEditing( Node ); + } + catch( DisposedException& e ) + { + OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" ); + if ( e.Context == xListener || !e.Context.is() ) + aIt.remove(); + } + catch( RuntimeException& e ) + { + (void)e; + DISPLAY_EXCEPTION( TreeEditListenerMultiplexer, nodeEditing, e ) + } + } +} + +void SAL_CALL TreeEditListenerMultiplexer::nodeEdited( const Reference< XTreeNode >& Node, const OUString& NewText ) throw (RuntimeException) +{ + ::cppu::OInterfaceIteratorHelper aIt( *this ); + while( aIt.hasMoreElements() ) + { + Reference< XTreeEditListener > xListener( static_cast< XTreeEditListener* >( aIt.next() ) ); + try + { + xListener->nodeEdited( Node, NewText ); + } + catch( DisposedException& e ) + { + OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" ); + if ( e.Context == xListener || !e.Context.is() ) + aIt.remove(); + } + catch( RuntimeException& e ) + { + (void)e; + DISPLAY_EXCEPTION( TreeEditListenerMultiplexer, nodeEdited, e ) + } + } +} diff --git a/toolkit/source/controls/tree/treecontrol.hxx b/toolkit/source/controls/tree/treecontrol.hxx new file mode 100644 index 000000000000..0e7f33b5a912 --- /dev/null +++ b/toolkit/source/controls/tree/treecontrol.hxx @@ -0,0 +1,139 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treecontrol.hxx,v $ + * $Revision: 1.3 $ + * + * 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 TOOLKIT_TREE_CONTROL_HXX +#define TOOLKIT_TREE_CONTROL_HXX + +#include <com/sun/star/awt/tree/XTreeControl.hpp> +#include <toolkit/controls/unocontrols.hxx> +#include <toolkit/controls/unocontrolmodel.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <toolkit/helper/listenermultiplexer.hxx> + +namespace toolkit { + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; + +// =================================================================== +// = UnoTreeModel +// =================================================================== +class UnoTreeModel : public UnoControlModel +{ +protected: + Any ImplGetDefaultValue( sal_uInt16 nPropId ) const; + ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); + +public: + UnoTreeModel(); + UnoTreeModel( const UnoTreeModel& rModel ); + + UnoControlModel* Clone() const; + + // ::com::sun::star::beans::XMultiPropertySet + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::io::XPersistObject + ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + DECLIMPL_SERVICEINFO_DERIVED( UnoTreeModel, UnoControlModel, szServiceName_TreeControlModel ) +}; + + +// =================================================================== +// = UnoTreeControl +// =================================================================== +class UnoTreeControl : public ::cppu::ImplInheritanceHelper1< UnoControlBase, ::com::sun::star::awt::tree::XTreeControl > +{ +public: + UnoTreeControl(); + ::rtl::OUString GetComponentServiceName(); + + // ::com::sun::star::lang::XComponent + void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::XControl + void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::view::XSelectionSupplier + virtual ::sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& xSelection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::view::XMultiSelectionSupplier + virtual ::sal_Bool SAL_CALL addSelection( const ::com::sun::star::uno::Any& Selection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSelection( const ::com::sun::star::uno::Any& Selection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getSelectionCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createSelectionEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createReverseSelectionEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::XTreeControl + virtual ::rtl::OUString SAL_CALL getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultExpandedGraphicURL( const ::rtl::OUString& _defaultexpandedgraphicurl ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultCollapsedGraphicURL( const ::rtl::OUString& _defaultcollapsedgraphicurl ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isNodeExpanded( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isNodeCollapsed( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL makeNodeVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isNodeVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL expandNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL collapseNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addTreeExpansionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeExpansionListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeTreeExpansionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeExpansionListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getNodeForLocation( ::sal_Int32 x, ::sal_Int32 y ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getClosestNodeForLocation( ::sal_Int32 x, ::sal_Int32 y ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isEditing( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL stopEditing( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancelEditing( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL startEditingAtNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addTreeEditListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeEditListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeTreeEditListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeEditListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::lang::XServiceInfo + DECLIMPL_SERVICEINFO_DERIVED( UnoTreeControl, UnoControlBase, szServiceName_TreeControl ) + + using UnoControl::getPeer; +private: + TreeSelectionListenerMultiplexer maSelectionListeners; + TreeExpansionListenerMultiplexer maTreeExpansionListeners; + TreeEditListenerMultiplexer maTreeEditListeners; +}; + +} // toolkit + +#endif // _TOOLKIT_TREE_CONTROL_HXX diff --git a/toolkit/source/controls/tree/treedatamodel.cxx b/toolkit/source/controls/tree/treedatamodel.cxx new file mode 100644 index 000000000000..65969fc486b0 --- /dev/null +++ b/toolkit/source/controls/tree/treedatamodel.cxx @@ -0,0 +1,676 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treedatamodel.cxx,v $ + * $Revision: 1.4 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/tree/XMutableTreeDataModel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> +#include <rtl/ref.hxx> +#include <toolkit/helper/mutexandbroadcasthelper.hxx> +#include <toolkit/helper/servicenames.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::awt::tree; +using namespace ::com::sun::star::lang; + +namespace toolkit +{ + + enum broadcast_type { nodes_changed, nodes_inserted, nodes_removed, structure_changed }; + +class MutableTreeNode; +class MutableTreeDataModel; + +typedef rtl::Reference< MutableTreeNode > MutableTreeNodeRef; +typedef std::vector< MutableTreeNodeRef > TreeNodeVector; +typedef rtl::Reference< MutableTreeDataModel > MutableTreeDataModelRef; + +static void implThrowIllegalArgumentException() throw( IllegalArgumentException ) +{ + throw IllegalArgumentException(); +} + +class MutableTreeDataModel : public ::cppu::WeakAggImplHelper2< XMutableTreeDataModel, XServiceInfo >, + public MutexAndBroadcastHelper +{ +public: + MutableTreeDataModel(); + virtual ~MutableTreeDataModel(); + + void broadcast( broadcast_type eType, const Reference< XTreeNode >& xParentNode, const Reference< XTreeNode >* pNodes, sal_Int32 nNodes ); + + // XMutableTreeDataModel + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XMutableTreeNode > SAL_CALL createNode( const ::com::sun::star::uno::Any& DisplayValue, ::sal_Bool ChildsOnDemand ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRoot( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XMutableTreeNode >& RootNode ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XTreeDataModel + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getRoot( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addTreeDataModelListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModelListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeTreeDataModelListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModelListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose( ) throw (RuntimeException); + virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException); + virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + +private: + bool mbDisposed; + Reference< XTreeNode > mxRootNode; +}; + +class MutableTreeNode: public ::cppu::WeakAggImplHelper2< XMutableTreeNode, XServiceInfo > +{ + friend class MutableTreeDataModel; + +public: + MutableTreeNode( const MutableTreeDataModelRef& xModel, const Any& rValue, sal_Bool bChildsOnDemand ); + virtual ~MutableTreeNode(); + + void setParent( MutableTreeNode* pParent ); + void broadcast_changes(); + void broadcast_changes(const Reference< XTreeNode >& xNode, bool bNew); + + // XMutableTreeNode + virtual ::com::sun::star::uno::Any SAL_CALL getDataValue() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDataValue( const ::com::sun::star::uno::Any& _datavalue ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL appendChild( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XMutableTreeNode >& ChildNode ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insertChildByIndex( ::sal_Int32 Index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XMutableTreeNode >& ChildNode ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeChildByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setHasChildrenOnDemand( ::sal_Bool ChildrenOnDemand ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDisplayValue( const ::com::sun::star::uno::Any& Value ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setNodeGraphicURL( const ::rtl::OUString& URL ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setExpandedGraphicURL( const ::rtl::OUString& URL ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCollapsedGraphicURL( const ::rtl::OUString& URL ) throw (::com::sun::star::uno::RuntimeException); + + // XTreeNode + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getChildAt( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getIndex( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasChildrenOnDemand( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getDisplayValue( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getNodeGraphicURL( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getExpandedGraphicURL( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getCollapsedGraphicURL( ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + static MutableTreeNode* getImplementation( const Reference< XTreeNode >& xNode, bool bThrows ) throw (IllegalArgumentException); + Reference< XTreeNode > getReference( MutableTreeNode* pNode ) + { + return Reference< XTreeNode >( pNode ); + } + +private: + TreeNodeVector maChilds; + Any maDisplayValue; + Any maDataValue; + sal_Bool mbHasChildsOnDemand; + ::osl::Mutex maMutex; + MutableTreeNode* mpParent; + MutableTreeDataModelRef mxModel; + OUString maNodeGraphicURL; + OUString maExpandedGraphicURL; + OUString maCollapsedGraphicURL; + bool mbIsInserted; +}; + +/////////////////////////////////////////////////////////////////////// +// class MutableTreeDataModel +/////////////////////////////////////////////////////////////////////// + +MutableTreeDataModel::MutableTreeDataModel() +: mbDisposed( false ) +{ +} + +//--------------------------------------------------------------------- + +MutableTreeDataModel::~MutableTreeDataModel() +{ +} + +//--------------------------------------------------------------------- + +void MutableTreeDataModel::broadcast( broadcast_type eType, const Reference< XTreeNode >& xParentNode, const Reference< XTreeNode >* pNodes, sal_Int32 nNodes ) +{ + ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XTreeDataModelListener::static_type() ); + if( pIter ) + { + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + const Sequence< Reference< XTreeNode > > aNodes( pNodes, nNodes ); + TreeDataModelEvent aEvent( xSource, aNodes, xParentNode ); + + ::cppu::OInterfaceIteratorHelper aListIter(*pIter); + while(aListIter.hasMoreElements()) + { + XTreeDataModelListener* pListener = static_cast<XTreeDataModelListener*>(aListIter.next()); + switch( eType ) + { + case nodes_changed: pListener->treeNodesChanged(aEvent); break; + case nodes_inserted: pListener->treeNodesInserted(aEvent); break; + case nodes_removed: pListener->treeNodesRemoved(aEvent); break; + case structure_changed: pListener->treeStructureChanged(aEvent); break; + } + } + } +} + +//--------------------------------------------------------------------- +// XMutableTreeDataModel +//--------------------------------------------------------------------- + +Reference< XMutableTreeNode > SAL_CALL MutableTreeDataModel::createNode( const Any& aValue, sal_Bool bChildsOnDemand ) throw (RuntimeException) +{ + return new MutableTreeNode( this, aValue, bChildsOnDemand ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeDataModel::setRoot( const Reference< XMutableTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException) +{ + if( !xNode.is() ) + throw IllegalArgumentException(); + + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + if( xNode != mxRootNode ) + { + if( mxRootNode.is() ) + { + MutableTreeNodeRef xOldImpl( dynamic_cast< MutableTreeNode* >( mxRootNode.get() ) ); + if( xOldImpl.is() ) + xOldImpl->mbIsInserted = false; + } + + MutableTreeNodeRef xImpl( dynamic_cast< MutableTreeNode* >( xNode.get() ) ); + if( !xImpl.is() || xImpl->mbIsInserted ) + throw IllegalArgumentException(); + + xImpl->mbIsInserted = true; + mxRootNode.set(xImpl.get()); + + Reference< XTreeNode > xParentNode; + broadcast( structure_changed, xParentNode, &mxRootNode, 1 ); + } +} + +//--------------------------------------------------------------------- +// XTreeDataModel +//--------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL MutableTreeDataModel::getRoot( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return mxRootNode; +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeDataModel::addTreeDataModelListener( const Reference< XTreeDataModelListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XTreeDataModelListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeDataModel::removeTreeDataModelListener( const Reference< XTreeDataModelListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XTreeDataModelListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- +// XComponent +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeDataModel::dispose() throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if( !mbDisposed ) + { + mbDisposed = true; + ::com::sun::star::lang::EventObject aEvent; + aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) ); + BrdcstHelper.aLC.disposeAndClear( aEvent ); + } +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeDataModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.addListener( XEventListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeDataModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + BrdcstHelper.removeListener( XEventListener::static_type(), xListener ); +} + +//--------------------------------------------------------------------- +// XServiceInfo +//--------------------------------------------------------------------- + +OUString SAL_CALL MutableTreeDataModel::getImplementationName( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.MutableTreeDataModel" ) ); + return aImplName; +} + +//--------------------------------------------------------------------- + +sal_Bool SAL_CALL MutableTreeDataModel::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return ServiceName.equalsAscii( szServiceName_MutableTreeDataModel ); +} + +//--------------------------------------------------------------------- + +Sequence< OUString > SAL_CALL MutableTreeDataModel::getSupportedServiceNames( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + static const OUString aServiceName( OUString::createFromAscii( szServiceName_MutableTreeDataModel ) ); + static const Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +/////////////////////////////////////////////////////////////////////// +// class MutabelTreeNode +/////////////////////////////////////////////////////////////////////// + +MutableTreeNode::MutableTreeNode( const MutableTreeDataModelRef& xModel, const Any& rValue, sal_Bool bChildsOnDemand ) +: maDisplayValue( rValue ) +, mbHasChildsOnDemand( bChildsOnDemand ) +, mpParent( 0 ) +, mxModel( xModel ) +, mbIsInserted( false ) +{ +} + +//--------------------------------------------------------------------- + +MutableTreeNode::~MutableTreeNode() +{ + TreeNodeVector::iterator aIter( maChilds.begin() ); + while( aIter != maChilds.end() ) + (*aIter++)->setParent(0); +} + +//--------------------------------------------------------------------- + +void MutableTreeNode::setParent( MutableTreeNode* pParent ) +{ + mpParent = pParent; +} + +//--------------------------------------------------------------------- + +MutableTreeNode* MutableTreeNode::getImplementation( const Reference< XTreeNode >& xNode, bool bThrows ) throw (IllegalArgumentException) +{ + MutableTreeNode* pImpl = dynamic_cast< MutableTreeNode* >( xNode.get() ); + if( bThrows && !pImpl ) + implThrowIllegalArgumentException(); + + return pImpl; +} + +//--------------------------------------------------------------------- + +void MutableTreeNode::broadcast_changes() +{ + if( mxModel.is() ) + { + Reference< XTreeNode > xParent( getReference( mpParent ) ); + Reference< XTreeNode > xNode( getReference( this ) ); + mxModel->broadcast( nodes_changed, xParent, &xNode, 1 ); + } +} + +//--------------------------------------------------------------------- + +void MutableTreeNode::broadcast_changes(const Reference< XTreeNode >& xNode, bool bNew) +{ + if( mxModel.is() ) + { + Reference< XTreeNode > xParent( getReference( this ) ); + mxModel->broadcast( bNew ? nodes_inserted : nodes_removed, xParent, &xNode, 1 ); + } +} + +//--------------------------------------------------------------------- +// XMutableTreeNode +//--------------------------------------------------------------------- + +Any SAL_CALL MutableTreeNode::getDataValue() throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return maDataValue; +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::setDataValue( const Any& _datavalue ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + maDataValue = _datavalue; +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::appendChild( const Reference< XMutableTreeNode >& xChildNode ) throw (IllegalArgumentException, RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + Reference< XTreeNode > xNode( xChildNode.get() ); + MutableTreeNodeRef xImpl( dynamic_cast< MutableTreeNode* >( xNode.get() ) ); + + if( !xImpl.is() || xImpl->mbIsInserted || (this == xImpl.get()) ) + throw IllegalArgumentException(); + + maChilds.push_back( xImpl ); + xImpl->setParent(this); + xImpl->mbIsInserted = true; + + broadcast_changes( xNode, true ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::insertChildByIndex( sal_Int32 nChildIndex, const Reference< XMutableTreeNode >& xChildNode ) throw (IllegalArgumentException, IndexOutOfBoundsException, RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + + if( (nChildIndex < 0) || (nChildIndex > (sal_Int32)maChilds.size()) ) + throw IndexOutOfBoundsException(); + + Reference< XTreeNode > xNode( xChildNode.get() ); + MutableTreeNodeRef xImpl( dynamic_cast< MutableTreeNode* >( xNode.get() ) ); + if( !xImpl.is() || xImpl->mbIsInserted || (this == xImpl.get()) ) + throw IllegalArgumentException(); + + xImpl->mbIsInserted = true; + + TreeNodeVector::iterator aIter( maChilds.begin() ); + while( (nChildIndex-- > 0) && (aIter != maChilds.end()) ) + aIter++; + + maChilds.insert( aIter, xImpl ); + xImpl->setParent( this ); + + broadcast_changes( xNode, true ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::removeChildByIndex( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + + MutableTreeNodeRef xImpl; + + if( (nChildIndex >= 0) && (nChildIndex < (sal_Int32)maChilds.size()) ) + { + TreeNodeVector::iterator aIter( maChilds.begin() ); + while( nChildIndex-- && (aIter != maChilds.end()) ) + aIter++; + + if( aIter != maChilds.end() ) + { + xImpl = (*aIter); + maChilds.erase( aIter ); + } + } + + if( !xImpl.is() ) + throw IndexOutOfBoundsException(); + + xImpl->setParent(0); + xImpl->mbIsInserted = false; + + broadcast_changes( getReference( xImpl.get() ), false ); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::setHasChildrenOnDemand( sal_Bool bChildsOnDemand ) throw (RuntimeException) +{ + bool bChanged; + + { + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + bChanged = mbHasChildsOnDemand != bChildsOnDemand; + mbHasChildsOnDemand = bChildsOnDemand; + } + + if( bChanged ) + broadcast_changes(); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::setDisplayValue( const Any& aValue ) throw (RuntimeException) +{ + { + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + maDisplayValue = aValue; + } + + broadcast_changes(); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::setNodeGraphicURL( const OUString& rURL ) throw (RuntimeException) +{ + bool bChanged; + + { + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + bChanged = maNodeGraphicURL != rURL; + maNodeGraphicURL = rURL; + } + + if( bChanged ) + broadcast_changes(); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::setExpandedGraphicURL( const OUString& rURL ) throw (RuntimeException) +{ + bool bChanged; + + { + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + bChanged = maExpandedGraphicURL != rURL; + maExpandedGraphicURL = rURL; + } + + if( bChanged ) + broadcast_changes(); +} + +//--------------------------------------------------------------------- + +void SAL_CALL MutableTreeNode::setCollapsedGraphicURL( const OUString& rURL ) throw (RuntimeException) +{ + bool bChanged; + + { + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + bChanged = maCollapsedGraphicURL != rURL; + maCollapsedGraphicURL = rURL; + } + + if( bChanged ) + broadcast_changes(); +} + +//--------------------------------------------------------------------- +// XTreeNode +//--------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL MutableTreeNode::getChildAt( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException,RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + + if( (nChildIndex < 0) || (nChildIndex >= (sal_Int32)maChilds.size()) ) + throw IndexOutOfBoundsException(); + return getReference( maChilds[nChildIndex].get() ); +} + +//--------------------------------------------------------------------- + +sal_Int32 SAL_CALL MutableTreeNode::getChildCount( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return (sal_Int32)maChilds.size(); +} + +//--------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL MutableTreeNode::getParent( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return getReference( mpParent ); +} + +//--------------------------------------------------------------------- + +sal_Int32 SAL_CALL MutableTreeNode::getIndex( const Reference< XTreeNode >& xNode ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + + MutableTreeNodeRef xImpl( MutableTreeNode::getImplementation( xNode, false ) ); + if( xImpl.is() ) + { + sal_Int32 nChildCount = maChilds.size(); + while( nChildCount-- ) + { + if( maChilds[nChildCount] == xImpl ) + return nChildCount; + } + } + + return -1; +} + +//--------------------------------------------------------------------- + +sal_Bool SAL_CALL MutableTreeNode::hasChildrenOnDemand( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return mbHasChildsOnDemand; +} + +//--------------------------------------------------------------------- + +Any SAL_CALL MutableTreeNode::getDisplayValue( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return maDisplayValue; +} + +//--------------------------------------------------------------------- + +OUString SAL_CALL MutableTreeNode::getNodeGraphicURL( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return maNodeGraphicURL; +} + +//--------------------------------------------------------------------- + +OUString SAL_CALL MutableTreeNode::getExpandedGraphicURL( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return maExpandedGraphicURL; +} + +//--------------------------------------------------------------------- + +OUString SAL_CALL MutableTreeNode::getCollapsedGraphicURL( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return maCollapsedGraphicURL; +} + +//--------------------------------------------------------------------- +// XServiceInfo +//--------------------------------------------------------------------- + +OUString SAL_CALL MutableTreeNode::getImplementationName( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.MutableTreeNode" ) ); + return aImplName; +} + +//--------------------------------------------------------------------- + +sal_Bool SAL_CALL MutableTreeNode::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.awt.tree.MutableTreeNode" ) ); +} + +//--------------------------------------------------------------------- + +Sequence< OUString > SAL_CALL MutableTreeNode::getSupportedServiceNames( ) throw (RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( maMutex ); + static const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.tree.MutableTreeNode" ) ); + static const Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +} + +Reference< XInterface > SAL_CALL MutableTreeDataModel_CreateInstance( const Reference< XMultiServiceFactory >& ) +{ + return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::MutableTreeDataModel ); +} diff --git a/toolkit/source/controls/unocontrol.cxx b/toolkit/source/controls/unocontrol.cxx new file mode 100644 index 000000000000..21876feb072b --- /dev/null +++ b/toolkit/source/controls/unocontrol.cxx @@ -0,0 +1,1540 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontrol.cxx,v $ + * $Revision: 1.54.42.1 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/VclWindowPeerAttribute.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#ifndef _COM_SUN_STAR_LAN_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/resource/XStringResourceResolver.hpp> +#include <toolkit/controls/unocontrol.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <rtl/memory.h> +#include <rtl/uuid.h> +#include <vos/mutex.hxx> +#include <tools/string.hxx> +#include <tools/table.hxx> +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/urlobj.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <comphelper/stl_types.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> +#include <toolkit/controls/accessiblecontrolcontext.hxx> +#include <comphelper/container.hxx> + +#include <algorithm> +#include <set> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; + +using ::com::sun::star::accessibility::XAccessibleContext; +using ::com::sun::star::accessibility::XAccessible; + +struct LanguageDependentProp +{ + const char* pPropName; + sal_Int32 nPropNameLength; +}; + +static const LanguageDependentProp aLanguageDependentProp[] = +{ + { "Text", 4 }, + { "Label", 5 }, + { "Title", 5 }, + { "HelpText", 8 }, + { "CurrencySymbol", 14 }, + { "StringItemList", 14 }, + { 0, 0 } +}; + +WorkWindow* lcl_GetDefaultWindow() +{ + static WorkWindow* pW = NULL; + if ( !pW ) + { + pW = new WorkWindow( NULL, 0 ); + pW->EnableChildTransparentMode(); + } + return pW; +} + +static Sequence< ::rtl::OUString> lcl_ImplGetPropertyNames( const Reference< XMultiPropertySet > & rxModel ) +{ + Sequence< ::rtl::OUString> aNames; + Reference< XPropertySetInfo > xPSInf = rxModel->getPropertySetInfo(); + DBG_ASSERT( xPSInf.is(), "UpdateFromModel: No PropertySetInfo!" ); + if ( xPSInf.is() ) + { + Sequence< Property> aProps = xPSInf->getProperties(); + sal_Int32 nLen = aProps.getLength(); + aNames = Sequence< ::rtl::OUString>( nLen ); + ::rtl::OUString* pNames = aNames.getArray(); + const Property* pProps = aProps.getConstArray(); + for ( sal_Int32 n = 0; n < nLen; ++n, ++pProps, ++pNames) + *pNames = pProps->Name; + } + return aNames; +} + +// ==================================================== +class VclListenerLock +{ +private: + VCLXWindow* m_pLockWindow; + +public: + inline VclListenerLock( VCLXWindow* _pLockWindow ) + :m_pLockWindow( _pLockWindow ) + { + if ( m_pLockWindow ) + m_pLockWindow->suspendVclEventListening( ); + } + inline ~VclListenerLock( ) + { + if ( m_pLockWindow ) + m_pLockWindow->resumeVclEventListening( ); + } + +private: + VclListenerLock(); // never implemented + VclListenerLock( const VclListenerLock& ); // never implemented + VclListenerLock& operator=( const VclListenerLock& ); // never implemented +}; + +typedef ::std::map< ::rtl::OUString, sal_Int32 > MapString2Int; +struct UnoControl_Data +{ + MapString2Int aSuspendedPropertyNotifications; + /// true if and only if our model has a property ResourceResolver + bool bLocalizationSupport; + + UnoControl_Data() + :aSuspendedPropertyNotifications() + ,bLocalizationSupport( false ) + { + } +}; + +// ---------------------------------------------------- +// class UnoControl +// ---------------------------------------------------- +DBG_NAME( UnoControl ) +UnoControl::UnoControl() + : maDisposeListeners( *this ) + , maWindowListeners( *this ) + , maFocusListeners( *this ) + , maKeyListeners( *this ) + , maMouseListeners( *this ) + , maMouseMotionListeners( *this ) + , maPaintListeners( *this ) + , maModeChangeListeners( GetMutex() ) + , mpData( new UnoControl_Data ) +{ + DBG_CTOR( UnoControl, NULL ); + mbDisposePeer = sal_True; + mbRefeshingPeer = sal_False; + mbCreatingPeer = sal_False; + mbCreatingCompatiblePeer = sal_False; + mbDesignMode = sal_False; +} + +UnoControl::~UnoControl() +{ + DELETEZ( mpData ); + DBG_DTOR( UnoControl, NULL ); +} + +::rtl::OUString UnoControl::GetComponentServiceName() +{ + return ::rtl::OUString(); +} + +Reference< XWindowPeer > UnoControl::ImplGetCompatiblePeer( sal_Bool bAcceptExistingPeer ) +{ + DBG_ASSERT( !mbCreatingCompatiblePeer, "ImplGetCompatiblePeer - rekursive?" ); + + mbCreatingCompatiblePeer = sal_True; + + Reference< XWindowPeer > xCompatiblePeer; + + if ( bAcceptExistingPeer ) + xCompatiblePeer = getPeer(); + + if ( !xCompatiblePeer.is() ) + { + // Peer unsichtbar erzeugen... + sal_Bool bVis = maComponentInfos.bVisible; + if( bVis ) + maComponentInfos.bVisible = sal_False; + + Reference< XWindowPeer > xCurrentPeer = getPeer(); + setPeer( NULL ); + + // queryInterface ourself, to allow aggregation + Reference< XControl > xMe; + OWeakAggObject::queryInterface( ::getCppuType( &xMe ) ) >>= xMe; + + WorkWindow* pWW; + { + osl::Guard< vos::IMutex > aGuard( Application::GetSolarMutex() ); + pWW = lcl_GetDefaultWindow(); + } + try + { + xMe->createPeer( NULL, pWW->GetComponentInterface( sal_True ) ); + } + catch( const Exception& ) + { + mbCreatingCompatiblePeer = sal_False; + throw; + } + xCompatiblePeer = getPeer(); + setPeer( xCurrentPeer ); + + if ( xCompatiblePeer.is() && mxGraphics.is() ) + { + Reference< XView > xPeerView( xCompatiblePeer, UNO_QUERY ); + if ( xPeerView.is() ) + xPeerView->setGraphics( mxGraphics ); + } + + if( bVis ) + maComponentInfos.bVisible = sal_True; + } + + mbCreatingCompatiblePeer = sal_False; + + return xCompatiblePeer; +} + +bool UnoControl::ImplCheckLocalize( ::rtl::OUString& _rPossiblyLocalizable ) +{ + if ( !mpData->bLocalizationSupport + || ( _rPossiblyLocalizable.getLength() == 0 ) + || ( _rPossiblyLocalizable[0] != '&' ) + // TODO: make this reasonable. At the moment, everything which by accident starts with a & is considered + // localizable, which is probably wrong. + ) + return false; + + try + { + Reference< XPropertySet > xPropSet( mxModel, UNO_QUERY_THROW ); + Reference< resource::XStringResourceResolver > xStringResourceResolver( + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ), + UNO_QUERY + ); + if ( xStringResourceResolver.is() ) + { + ::rtl::OUString aLocalizationKey( _rPossiblyLocalizable.copy( 1 ) ); + _rPossiblyLocalizable = xStringResourceResolver->resolveString( aLocalizationKey ); + return true; + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return false; +} + +void UnoControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal ) +{ + // since a change made in propertiesChange, we can't be sure that this is called with an valid getPeer(), + // this assumption may be false in some (seldom) multi-threading scenarios (cause propertiesChange + // releases our mutex before calling here in) + // That's why this additional check + + if ( mxVclWindowPeer.is() ) + { + Any aConvertedValue( rVal ); + + if ( mpData->bLocalizationSupport ) + { + // We now support a mapping for language dependent properties. This is the + // central method to implement it. + if (( rPropName.equalsAsciiL( "Text", 4 )) || + ( rPropName.equalsAsciiL( "Label", 5 )) || + ( rPropName.equalsAsciiL( "Title", 5 )) || + ( rPropName.equalsAsciiL( "HelpText", 8 )) || + ( rPropName.equalsAsciiL( "CurrencySymbol", 14 )) || + ( rPropName.equalsAsciiL( "StringItemList", 14 )) ) + { + ::rtl::OUString aValue; + uno::Sequence< rtl::OUString > aSeqValue; + if ( aConvertedValue >>= aValue ) + { + if ( ImplCheckLocalize( aValue ) ) + aConvertedValue <<= aValue; + } + else if ( aConvertedValue >>= aSeqValue ) + { + for ( sal_Int32 i = 0; i < aSeqValue.getLength(); i++ ) + ImplCheckLocalize( aSeqValue[i] ); + aConvertedValue <<= aSeqValue; + } + } + } + + mxVclWindowPeer->setProperty( rPropName, aConvertedValue ); + } +} + +void UnoControl::PrepareWindowDescriptor( WindowDescriptor& ) +{ +} + +Reference< XWindow > UnoControl::getParentPeer() const +{ + Reference< XWindow > xPeer; + if( mxContext.is() ) + { + Reference< XControl > xContComp( mxContext, UNO_QUERY ); + if ( xContComp.is() ) + { + Reference< XWindowPeer > xP = xContComp->getPeer(); + if ( xP.is() ) + xP->queryInterface( ::getCppuType((const Reference< XWindow >*)0) ) >>= xPeer; + } + } + return xPeer; +} + +void UnoControl::updateFromModel() +{ + // Alle standard Properties werden ausgelesen und in das Peer uebertragen + if( getPeer().is() ) + { + Reference< XMultiPropertySet > xPropSet( mxModel, UNO_QUERY ); + if( xPropSet.is() ) + { + Sequence< ::rtl::OUString> aNames = lcl_ImplGetPropertyNames( xPropSet ); + xPropSet->firePropertiesChangeEvent( aNames, this ); + } + } +} + + +// XTypeProvider +IMPL_IMPLEMENTATION_ID( UnoControl ) + +void UnoControl::disposeAccessibleContext() +{ + Reference< XComponent > xContextComp( maAccessibleContext.get(), UNO_QUERY ); + if ( xContextComp.is() ) + { + maAccessibleContext = NULL; + try + { + xContextComp->removeEventListener( this ); + xContextComp->dispose(); + } + catch( const Exception& ) + { + DBG_ERROR( "UnoControl::disposeAccessibleContext: could not dispose my AccessibleContext!" ); + } + } +} + +void UnoControl::dispose( ) throw(RuntimeException) +{ + Reference< XWindowPeer > xPeer; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if( mbDisposePeer ) + { + xPeer = mxPeer; + } + setPeer( NULL ); + } + if( xPeer.is() ) + { + xPeer->dispose(); + } + + // dispose and release our AccessibleContext + disposeAccessibleContext(); + + EventObject aDisposeEvent; + aDisposeEvent.Source = static_cast< XAggregation* >( this ); + + maDisposeListeners.disposeAndClear( aDisposeEvent ); + maWindowListeners.disposeAndClear( aDisposeEvent ); + maFocusListeners.disposeAndClear( aDisposeEvent ); + maKeyListeners.disposeAndClear( aDisposeEvent ); + maMouseListeners.disposeAndClear( aDisposeEvent ); + maMouseMotionListeners.disposeAndClear( aDisposeEvent ); + maPaintListeners.disposeAndClear( aDisposeEvent ); + maModeChangeListeners.disposeAndClear( aDisposeEvent ); + + // Model wieder freigeben + setModel( Reference< XControlModel > () ); + setContext( Reference< XInterface > () ); +} + +void UnoControl::addEventListener( const Reference< XEventListener >& rxListener ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + maDisposeListeners.addInterface( rxListener ); +} + +void UnoControl::removeEventListener( const Reference< XEventListener >& rxListener ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + maDisposeListeners.removeInterface( rxListener ); +} + +sal_Bool UnoControl::requiresNewPeer( const ::rtl::OUString& /* _rPropertyName */ ) const +{ + return sal_False; +} + +// XPropertiesChangeListener +void UnoControl::propertiesChange( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException) +{ + Sequence< PropertyChangeEvent > aEvents( rEvents ); + { + ::osl::MutexGuard aGuard( GetMutex() ); + + if ( !mpData->aSuspendedPropertyNotifications.empty() ) + { + // strip the property which we are currently updating (somewhere up the stack) + PropertyChangeEvent* pEvents = aEvents.getArray(); + PropertyChangeEvent* pEventsEnd = pEvents + aEvents.getLength(); + for ( ; pEvents < pEventsEnd; ) + if ( mpData->aSuspendedPropertyNotifications.find( pEvents->PropertyName ) != mpData->aSuspendedPropertyNotifications.end() ) + { + if ( pEvents != pEventsEnd ) + ::std::copy( pEvents + 1, pEventsEnd, pEvents ); + --pEventsEnd; + } + else + ++pEvents; + aEvents.realloc( pEventsEnd - aEvents.getConstArray() ); + + if ( !aEvents.getLength() ) + return; + } + } + + ImplModelPropertiesChanged( aEvents ); +} + +void UnoControl::ImplLockPropertyChangeNotification( const ::rtl::OUString& rPropertyName, bool bLock ) +{ + MapString2Int::iterator pos = mpData->aSuspendedPropertyNotifications.find( rPropertyName ); + if ( bLock ) + { + if ( pos == mpData->aSuspendedPropertyNotifications.end() ) + pos = mpData->aSuspendedPropertyNotifications.insert( MapString2Int::value_type( rPropertyName, 0 ) ).first; + ++pos->second; + } + else + { + OSL_ENSURE( pos != mpData->aSuspendedPropertyNotifications.end(), "UnoControl::ImplLockPropertyChangeNotification: property not locked!" ); + if ( pos != mpData->aSuspendedPropertyNotifications.end() ) + { + OSL_ENSURE( pos->second > 0, "UnoControl::ImplLockPropertyChangeNotification: invalid suspension counter!" ); + if ( 0 == --pos->second ) + mpData->aSuspendedPropertyNotifications.erase( pos ); + } + } +} + +void UnoControl::ImplLockPropertyChangeNotifications( const Sequence< ::rtl::OUString >& rPropertyNames, bool bLock ) +{ + for ( const ::rtl::OUString* pPropertyName = rPropertyNames.getConstArray(); + pPropertyName != rPropertyNames.getConstArray() + rPropertyNames.getLength(); + ++pPropertyName + ) + ImplLockPropertyChangeNotification( *pPropertyName, bLock ); +} + +void UnoControl::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) +{ + ::osl::ClearableGuard< ::osl::Mutex > aGuard( GetMutex() ); + + if( getPeer().is() ) + { + DECLARE_STL_VECTOR( PropertyValue, PropertyValueVector); + PropertyValueVector aPeerPropertiesToSet; + sal_Int32 nIndependentPos = 0; + bool bResourceResolverSet( false ); + // position where to insert the independent properties into aPeerPropertiesToSet, + // dependent ones are inserted at the end of the vector + + sal_Bool bNeedNewPeer = sal_False; + // some properties require a re-creation of the peer, 'cause they can't be changed on the fly + + Reference< XControlModel > xOwnModel( getModel(), UNO_QUERY ); + // our own model for comparison + Reference< XPropertySet > xPS( xOwnModel, UNO_QUERY ); + Reference< XPropertySetInfo > xPSI( xPS->getPropertySetInfo(), UNO_QUERY ); + OSL_ENSURE( xPSI.is(), "UnoControl::ImplModelPropertiesChanged: should have property set meta data!" ); + + const PropertyChangeEvent* pEvents = rEvents.getConstArray(); + + sal_Int32 nLen = rEvents.getLength(); + aPeerPropertiesToSet.reserve(nLen); + + for( sal_Int32 i = 0; i < nLen; ++i, ++pEvents ) + { + Reference< XControlModel > xModel( pEvents->Source, UNO_QUERY ); + sal_Bool bOwnModel = xModel.get() == xOwnModel.get(); + if ( !bOwnModel ) + continue; + + // Detect changes on our resource resolver which invalidates + // automatically some language dependent properties. + if ( pEvents->PropertyName.equalsAsciiL( "ResourceResolver", 16 )) + { + Reference< resource::XStringResourceResolver > xStrResolver; + if ( pEvents->NewValue >>= xStrResolver ) + bResourceResolverSet = xStrResolver.is(); + } + + sal_uInt16 nPType = GetPropertyId( pEvents->PropertyName ); + if ( mbDesignMode && mbDisposePeer && !mbRefeshingPeer && !mbCreatingPeer ) + { + // if we're in design mode, then some properties can change which + // require creating a *new* peer (since these properties cannot + // be switched at existing peers) + if ( nPType ) + bNeedNewPeer = ( nPType == BASEPROPERTY_BORDER ) + || ( nPType == BASEPROPERTY_MULTILINE ) + || ( nPType == BASEPROPERTY_DROPDOWN ) + || ( nPType == BASEPROPERTY_HSCROLL ) + || ( nPType == BASEPROPERTY_VSCROLL ) + || ( nPType == BASEPROPERTY_AUTOHSCROLL ) + || ( nPType == BASEPROPERTY_AUTOVSCROLL ) + || ( nPType == BASEPROPERTY_ORIENTATION ) + || ( nPType == BASEPROPERTY_SPIN ) + || ( nPType == BASEPROPERTY_ALIGN ) + || ( nPType == BASEPROPERTY_PAINTTRANSPARENT ); + else + bNeedNewPeer = requiresNewPeer( pEvents->PropertyName ); + + if ( bNeedNewPeer ) + break; + } + + if ( nPType && ( nLen > 1 ) && DoesDependOnOthers( nPType ) ) + { + // Properties die von anderen abhaengen erst hinterher einstellen, + // weil sie von anderen Properties abhaengig sind, die aber erst spaeter + // eingestellt werden, z.B. VALUE nach VALUEMIN/MAX. + aPeerPropertiesToSet.push_back(PropertyValue(pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE)); + } + else + { + if ( bResourceResolverSet ) + { + // The resource resolver property change should be one of the first ones. + // All language dependent properties are dependent on this property. + // As BASEPROPERTY_NATIVE_WIDGET_LOOK is not dependent on resource + // resolver. We don't need to handle a special order for these two props. + aPeerPropertiesToSet.insert( + aPeerPropertiesToSet.begin(), + PropertyValue( pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE ) ); + ++nIndependentPos; + } + else if ( nPType == BASEPROPERTY_NATIVE_WIDGET_LOOK ) + { + // since *a lot* of other properties might be overruled by this one, we need + // a special handling: + // NativeWidgetLook needs to be set first: If it is set to ON, all other + // properties describing the look (e.g. BackgroundColor) are ignored, anyway. + // If it is switched OFF, then we need to do it first because else it will + // overrule other look-related properties, and re-initialize them from system + // defaults. + aPeerPropertiesToSet.insert( + aPeerPropertiesToSet.begin(), + PropertyValue( pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE ) ); + ++nIndependentPos; + } + else + { + aPeerPropertiesToSet.insert(aPeerPropertiesToSet.begin() + nIndependentPos, + PropertyValue(pEvents->PropertyName, 0, pEvents->NewValue, PropertyState_DIRECT_VALUE)); + ++nIndependentPos; + } + } + } + + Reference< XWindow > xParent = getParentPeer(); + Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY ); + // call createPeer via a interface got from queryInterface, so the aggregating class can intercept it + + DBG_ASSERT( !bNeedNewPeer || xParent.is(), "Need new peer, but don't have a parent!" ); + + // Check if we have to update language dependent properties + if ( !bNeedNewPeer && bResourceResolverSet ) + { + // Add language dependent properties into the peer property set. + // Our resource resolver has been changed and we must be sure + // that language dependent props use the new resolver. + const LanguageDependentProp* pLangDepProp = aLanguageDependentProp; + while ( pLangDepProp->pPropName != 0 ) + { + bool bMustBeInserted( true ); + for ( sal_uInt32 i = 0; i < aPeerPropertiesToSet.size(); i++ ) + { + if ( aPeerPropertiesToSet[i].Name.equalsAsciiL( + pLangDepProp->pPropName, pLangDepProp->nPropNameLength )) + { + bMustBeInserted = false; + break; + } + } + + if ( bMustBeInserted ) + { + // Add language dependent props at the end + ::rtl::OUString aPropName( ::rtl::OUString::createFromAscii( pLangDepProp->pPropName )); + if ( xPSI.is() && xPSI->hasPropertyByName( aPropName ) ) + { + aPeerPropertiesToSet.push_back( + PropertyValue( aPropName, 0, xPS->getPropertyValue( aPropName ), PropertyState_DIRECT_VALUE ) ); + } + } + + ++pLangDepProp; + } + } + aGuard.clear(); + + // clear the guard before creating a new peer - as usual, our peer implementations use the SolarMutex + // #82300# - 2000-12-21 - fs@openoffice.org + if (bNeedNewPeer && xParent.is()) + { + NAMESPACE_VOS(OGuard) aVclGuard( Application::GetSolarMutex() ); + // and now this is the final withdrawal: + // With 83561, I have no other idea than locking the SolarMutex here .... + // I really hate the fact that VCL is not theadsafe .... + // #83561# - 2001-03-01 - fs@openoffice.org + + // Funktioniert beim Container nicht! + getPeer()->dispose(); + mxPeer.clear(); + mxVclWindowPeer = NULL; + mbRefeshingPeer = sal_True; + Reference< XWindowPeer > xP( xParent, UNO_QUERY ); + xThis->createPeer( Reference< XToolkit > (), xP ); + mbRefeshingPeer = sal_False; + aPeerPropertiesToSet.clear(); + } + + // lock the multiplexing of VCL events to our UNO listeners + // this is for compatibility reasons: in OOo 1.0.x, changes which were done at the + // model did not cause the listeners of the controls/peers to be called + // Since the implementations for the listeners changed a lot towards 1.1, this + // would not be the case anymore, if we would not do this listener-lock below + // #i14703# - 2003-05-23 - fs@openoffice.org + Window* pVclPeer = VCLUnoHelper::GetWindow( getPeer() ); + VCLXWindow* pPeer = pVclPeer ? pVclPeer->GetWindowPeer() : NULL; + VclListenerLock aNoVclEventMultiplexing( pPeer ); + + // setting peer properties may result in an attemp to acquire the solar mutex, 'cause the peers + // usually don't have an own mutex but use the SolarMutex instead. + // To prevent deadlocks resulting from this, we do this without our own mutex locked + // 2000-11-03 - fs@openoffice.org + PropertyValueVectorIterator aEnd = aPeerPropertiesToSet.end(); + for ( PropertyValueVectorIterator aLoop = aPeerPropertiesToSet.begin(); + aLoop != aEnd; + ++aLoop + ) + { + ImplSetPeerProperty( aLoop->Name, aLoop->Value ); + } + } +} + +void UnoControl::disposing( const EventObject& rEvt ) throw(RuntimeException) +{ + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + // bei "Multible Inheritance" nicht unterschiedliche Typen vergleichen. + + if ( maAccessibleContext.get() == rEvt.Source ) + { + // just in case the context is disposed, but not released - ensure that we do not re-use it in the future + maAccessibleContext = NULL; + } + else if( mxModel.get() == Reference< XControlModel >(rEvt.Source,UNO_QUERY).get() ) + { + // #62337# if the model dies, it does not make sense for us to live ... + Reference< XControl > xThis = this; + + aGuard.clear(); + xThis->dispose(); + + DBG_ASSERT( !mxModel.is(), "UnoControl::disposing: invalid dispose behaviour!" ); + mxModel.clear(); + } +} + + +void SAL_CALL UnoControl::setOutputSize( const awt::Size& aSize ) throw (RuntimeException) +{ + Reference< XWindow2 > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + xPeerWindow = xPeerWindow.query( getPeer() ); + } + + if ( xPeerWindow.is() ) + xPeerWindow->setOutputSize( aSize ); +} + +namespace +{ + template < typename RETVALTYPE > + RETVALTYPE lcl_askPeer( const uno::Reference< awt::XWindowPeer >& _rxPeer, RETVALTYPE (SAL_CALL XWindow2::*_pMethod)(), RETVALTYPE _aDefault ) + { + RETVALTYPE aReturn( _aDefault ); + + Reference< XWindow2 > xPeerWindow( _rxPeer, UNO_QUERY ); + if ( xPeerWindow.is() ) + aReturn = (xPeerWindow.get()->*_pMethod)(); + + return aReturn; + } +} + +awt::Size SAL_CALL UnoControl::getOutputSize( ) throw (RuntimeException) +{ + return lcl_askPeer( getPeer(), &XWindow2::getOutputSize, awt::Size() ); +} + +::sal_Bool SAL_CALL UnoControl::isVisible( ) throw (RuntimeException) +{ + return lcl_askPeer( getPeer(), &XWindow2::isVisible, maComponentInfos.bVisible ); +} + +::sal_Bool SAL_CALL UnoControl::isActive( ) throw (RuntimeException) +{ + return lcl_askPeer( getPeer(), &XWindow2::isActive, sal_False ); +} + +::sal_Bool SAL_CALL UnoControl::isEnabled( ) throw (RuntimeException) +{ + return lcl_askPeer( getPeer(), &XWindow2::isEnabled, maComponentInfos.bEnable ); +} + +::sal_Bool SAL_CALL UnoControl::hasFocus( ) throw (RuntimeException) +{ + return lcl_askPeer( getPeer(), &XWindow2::hasFocus, sal_False ); +} + +// XWindow +void UnoControl::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) throw(RuntimeException) +{ + Reference< XWindow > xWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + + if ( Flags & awt::PosSize::X ) + maComponentInfos.nX = X; + if ( Flags & awt::PosSize::Y ) + maComponentInfos.nY = Y; + if ( Flags & awt::PosSize::WIDTH ) + maComponentInfos.nWidth = Width; + if ( Flags & awt::PosSize::HEIGHT ) + maComponentInfos.nHeight = Height; + maComponentInfos.nFlags |= Flags; + + xWindow = xWindow.query( getPeer() ); + } + + if( xWindow.is() ) + xWindow->setPosSize( X, Y, Width, Height, Flags ); +} + +awt::Rectangle UnoControl::getPosSize( ) throw(RuntimeException) +{ + awt::Rectangle aRect( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight); + Reference< XWindow > xWindow; + + { + ::osl::MutexGuard aGuard( GetMutex() ); + xWindow = xWindow.query( getPeer() ); + } + + if( xWindow.is() ) + aRect = xWindow->getPosSize(); + return aRect; +} + +void UnoControl::setVisible( sal_Bool bVisible ) throw(RuntimeException) +{ + Reference< XWindow > xWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + + // Visible status ist Sache der View + maComponentInfos.bVisible = bVisible; + xWindow = xWindow.query( getPeer() ); + } + if ( xWindow.is() ) + xWindow->setVisible( bVisible ); +} + +void UnoControl::setEnable( sal_Bool bEnable ) throw(RuntimeException) +{ + Reference< XWindow > xWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + + // Enable status ist Sache der View + maComponentInfos.bEnable = bEnable; + xWindow = xWindow.query( getPeer() ); + } + if ( xWindow.is() ) + xWindow->setEnable( bEnable ); +} + +void UnoControl::setFocus( ) throw(RuntimeException) +{ + Reference< XWindow > xWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + xWindow = xWindow.query( getPeer() ); + } + if ( xWindow.is() ) + xWindow->setFocus(); +} + +void UnoControl::addWindowListener( const Reference< XWindowListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + maWindowListeners.addInterface( rxListener ); + if ( maWindowListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + } + if ( xPeerWindow.is() ) + xPeerWindow->addWindowListener( &maWindowListeners ); +} + +void UnoControl::removeWindowListener( const Reference< XWindowListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( maWindowListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + maWindowListeners.removeInterface( rxListener ); + } + if ( xPeerWindow.is() ) + xPeerWindow->removeWindowListener( &maWindowListeners ); +} + +void UnoControl::addFocusListener( const Reference< XFocusListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + maFocusListeners.addInterface( rxListener ); + if ( maFocusListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + } + if ( xPeerWindow.is() ) + xPeerWindow->addFocusListener( &maFocusListeners ); +} + +void UnoControl::removeFocusListener( const Reference< XFocusListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( maFocusListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + maFocusListeners.removeInterface( rxListener ); + } + if ( xPeerWindow.is() ) + xPeerWindow->removeFocusListener( &maFocusListeners ); +} + +void UnoControl::addKeyListener( const Reference< XKeyListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + maKeyListeners.addInterface( rxListener ); + if ( maKeyListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + } + if ( xPeerWindow.is() ) + xPeerWindow->addKeyListener( &maKeyListeners); +} + +void UnoControl::removeKeyListener( const Reference< XKeyListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( maKeyListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + maKeyListeners.removeInterface( rxListener ); + } + if ( xPeerWindow.is() ) + xPeerWindow->removeKeyListener( &maKeyListeners); +} + +void UnoControl::addMouseListener( const Reference< XMouseListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + maMouseListeners.addInterface( rxListener ); + if ( maMouseListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + } + if ( xPeerWindow.is() ) + xPeerWindow->addMouseListener( &maMouseListeners); +} + +void UnoControl::removeMouseListener( const Reference< XMouseListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( maMouseListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + maMouseListeners.removeInterface( rxListener ); + } + if ( xPeerWindow.is() ) + xPeerWindow->removeMouseListener( &maMouseListeners ); +} + +void UnoControl::addMouseMotionListener( const Reference< XMouseMotionListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + maMouseMotionListeners.addInterface( rxListener ); + if ( maMouseMotionListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + } + if ( xPeerWindow.is() ) + xPeerWindow->addMouseMotionListener( &maMouseMotionListeners); +} + +void UnoControl::removeMouseMotionListener( const Reference< XMouseMotionListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( maMouseMotionListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + maMouseMotionListeners.removeInterface( rxListener ); + } + if ( xPeerWindow.is() ) + xPeerWindow->removeMouseMotionListener( &maMouseMotionListeners ); +} + +void UnoControl::addPaintListener( const Reference< XPaintListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + maPaintListeners.addInterface( rxListener ); + if ( maPaintListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + } + if ( xPeerWindow.is() ) + xPeerWindow->addPaintListener( &maPaintListeners); +} + +void UnoControl::removePaintListener( const Reference< XPaintListener >& rxListener ) throw(RuntimeException) +{ + Reference< XWindow > xPeerWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( maPaintListeners.getLength() == 1 ) + xPeerWindow = xPeerWindow.query( getPeer() ); + maPaintListeners.removeInterface( rxListener ); + } + if ( xPeerWindow.is() ) + xPeerWindow->removePaintListener( &maPaintListeners ); +} + +// XView +sal_Bool UnoControl::setGraphics( const Reference< XGraphics >& rDevice ) throw(RuntimeException) +{ + Reference< XView > xView; + { + ::osl::MutexGuard aGuard( GetMutex() ); + + mxGraphics = rDevice; + xView = xView.query( getPeer() ); + } + return xView.is() ? xView->setGraphics( rDevice ) : sal_True; +} + +Reference< XGraphics > UnoControl::getGraphics( ) throw(RuntimeException) +{ + return mxGraphics; +} + +awt::Size UnoControl::getSize( ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + return awt::Size( maComponentInfos.nWidth, maComponentInfos.nHeight ); +} + +void UnoControl::draw( sal_Int32 x, sal_Int32 y ) throw(RuntimeException) +{ + Reference< XWindowPeer > xDrawPeer; + Reference< XView > xDrawPeerView; + + bool bDisposeDrawPeer( false ); + { + ::osl::MutexGuard aGuard( GetMutex() ); + + xDrawPeer = ImplGetCompatiblePeer( sal_True ); + bDisposeDrawPeer = xDrawPeer.is() && ( xDrawPeer != getPeer() ); + + xDrawPeerView.set( xDrawPeer, UNO_QUERY ); + DBG_ASSERT( xDrawPeerView.is(), "UnoControl::draw: no peer!" ); + } + + if ( xDrawPeerView.is() ) + { + Reference< XVclWindowPeer > xWindowPeer; + xWindowPeer.set( xDrawPeer, UNO_QUERY ); + if ( xWindowPeer.is() ) + xWindowPeer->setDesignMode( mbDesignMode ); + xDrawPeerView->draw( x, y ); + } + + if ( bDisposeDrawPeer ) + xDrawPeer->dispose(); +} + +void UnoControl::setZoom( float fZoomX, float fZoomY ) throw(RuntimeException) +{ + Reference< XView > xView; + { + ::osl::MutexGuard aGuard( GetMutex() ); + + maComponentInfos.nZoomX = fZoomX; + maComponentInfos.nZoomY = fZoomY; + + xView = xView.query( getPeer() ); + } + if ( xView.is() ) + xView->setZoom( fZoomX, fZoomY ); +} + +// XControl +void UnoControl::setContext( const Reference< XInterface >& rxContext ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + mxContext = rxContext; +} + +Reference< XInterface > UnoControl::getContext( ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + return mxContext; +} + +void UnoControl::peerCreated() +{ + Reference< XWindow > xWindow( getPeer(), UNO_QUERY ); + if ( !xWindow.is() ) + return; + + if ( maWindowListeners.getLength() ) + xWindow->addWindowListener( &maWindowListeners ); + + if ( maFocusListeners.getLength() ) + xWindow->addFocusListener( &maFocusListeners ); + + if ( maKeyListeners.getLength() ) + xWindow->addKeyListener( &maKeyListeners ); + + if ( maMouseListeners.getLength() ) + xWindow->addMouseListener( &maMouseListeners ); + + if ( maMouseMotionListeners.getLength() ) + xWindow->addMouseMotionListener( &maMouseMotionListeners ); + + if ( maPaintListeners.getLength() ) + xWindow->addPaintListener( &maPaintListeners ); +} + +void UnoControl::createPeer( const Reference< XToolkit >& rxToolkit, const Reference< XWindowPeer >& rParentPeer ) throw(RuntimeException) +{ + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + + if ( !mxModel.is() ) + { + RuntimeException aException; + aException.Message = ::rtl::OUString::createFromAscii( "createPeer: no model!" ); + aException.Context = (XAggregation*)(::cppu::OWeakAggObject*)this; + throw( aException ); + } + + if( !getPeer().is() ) + { + mbCreatingPeer = sal_True; + + WindowClass eType; + Reference< XToolkit > xToolkit = rxToolkit; + if( rParentPeer.is() && mxContext.is() ) + { + // kein TopWindow + if ( !xToolkit.is() ) + xToolkit = rParentPeer->getToolkit(); + Any aAny = OWeakAggObject::queryInterface( ::getCppuType((const Reference< XControlContainer>*)0) ); + Reference< XControlContainer > xC; + aAny >>= xC; + if( xC.is() ) + // Es ist ein Container + eType = WindowClass_CONTAINER; + else + eType = WindowClass_SIMPLE; + } + else + { // Nur richtig, wenn es sich um ein Top Window handelt + if( rParentPeer.is() ) + { + if ( !xToolkit.is() ) + xToolkit = rParentPeer->getToolkit(); + eType = WindowClass_CONTAINER; + } + else + { + if ( !xToolkit.is() ) + xToolkit = VCLUnoHelper::CreateToolkit(); + eType = WindowClass_TOP; + } + } + WindowDescriptor aDescr; + aDescr.Type = eType; + aDescr.WindowServiceName = GetComponentServiceName(); + aDescr.Parent = rParentPeer; + aDescr.Bounds = getPosSize(); + aDescr.WindowAttributes = 0; + + // Border + Reference< XPropertySet > xPSet( mxModel, UNO_QUERY ); + Reference< XPropertySetInfo > xInfo = xPSet->getPropertySetInfo(); + + Any aVal; + ::rtl::OUString aPropName = GetPropertyName( BASEPROPERTY_BORDER ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Int16 n = sal_Int16(); + if ( aVal >>= n ) + { + if ( n ) + aDescr.WindowAttributes |= WindowAttribute::BORDER; + else + aDescr.WindowAttributes |= VclWindowPeerAttribute::NOBORDER; + } + } + + // DESKTOP_AS_PARENT + if ( aDescr.Type == WindowClass_TOP ) + { + aPropName = GetPropertyName( BASEPROPERTY_DESKTOP_AS_PARENT ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.ParentIndex = -1; + } + } + // Moveable + aPropName = GetPropertyName( BASEPROPERTY_MOVEABLE ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= WindowAttribute::MOVEABLE; + } + + // Closeable + aPropName = GetPropertyName( BASEPROPERTY_CLOSEABLE ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= WindowAttribute::CLOSEABLE; + } + + // Dropdown + aPropName = GetPropertyName( BASEPROPERTY_DROPDOWN ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= VclWindowPeerAttribute::DROPDOWN; + } + + // Spin + aPropName = GetPropertyName( BASEPROPERTY_SPIN ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= VclWindowPeerAttribute::SPIN; + } + + // HScroll + aPropName = GetPropertyName( BASEPROPERTY_HSCROLL ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= VclWindowPeerAttribute::HSCROLL; + } + + // VScroll + aPropName = GetPropertyName( BASEPROPERTY_VSCROLL ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= VclWindowPeerAttribute::VSCROLL; + } + + // AutoHScroll + aPropName = GetPropertyName( BASEPROPERTY_AUTOHSCROLL ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= VclWindowPeerAttribute::AUTOHSCROLL; + } + + // AutoVScroll + aPropName = GetPropertyName( BASEPROPERTY_AUTOVSCROLL ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b) + aDescr.WindowAttributes |= VclWindowPeerAttribute::AUTOVSCROLL; + } + + //added for issue79712 + //NoLabel + aPropName = GetPropertyName( BASEPROPERTY_NOLABEL ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>=b ) && b ) + aDescr.WindowAttributes |= VclWindowPeerAttribute::NOLABEL; + } + //issue79712 ends + + // Align + aPropName = GetPropertyName( BASEPROPERTY_ALIGN ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + aVal = xPSet->getPropertyValue( aPropName ); + sal_Int16 n = sal_Int16(); + if ( aVal >>= n ) + { + if ( n == PROPERTY_ALIGN_LEFT ) + aDescr.WindowAttributes |= VclWindowPeerAttribute::LEFT; + else if ( n == PROPERTY_ALIGN_CENTER ) + aDescr.WindowAttributes |= VclWindowPeerAttribute::CENTER; + else + aDescr.WindowAttributes |= VclWindowPeerAttribute::RIGHT; + } + } + + // Ableitungen die Moeglichkeit geben die Attribute zu manipulieren + PrepareWindowDescriptor(aDescr); + + // create the peer + setPeer( xToolkit->createWindow( aDescr ) ); + + // release the mutex guard (and work with copies of our members) + // this is necessary as our peer may lock the SolarMutex (actually, all currently known peers do), so calling + // into the peer with our own mutex locked may cause deadlocks + // (We _really_ need peers which do not use the SolarMutex. It's really pissing me off that from time to + // time deadlocks pop up because the low-level components like our peers use a mutex which ususally + // is locked at the top of the stack (it protects the global message looping). This is always dangerous, and + // can not always be solved by tampering with other mutexes. + // Unfortunately, the VCL used in the peers is not threadsafe, and by definition needs a locked SolarMutex.) + // 82300 - 12/21/00 - FS + UnoControlComponentInfos aComponentInfos(maComponentInfos); + sal_Bool bDesignMode(mbDesignMode); + + Reference< XGraphics > xGraphics( mxGraphics ); + Reference< XView > xView ( getPeer(), UNO_QUERY ); + Reference< XWindow > xWindow ( getPeer(), UNO_QUERY ); + + aGuard.clear(); + + // the updateFromModel is done without a locked mutex, too. + // The reason is that the only thing this method does is firing property changes, and this in general has + // to be done without locked mutexes (as every notification to external listeners). + // 82300 - 12/21/00 - FS + updateFromModel(); + + xView->setZoom( aComponentInfos.nZoomX, aComponentInfos.nZoomY ); + + setPosSize( aComponentInfos.nX, aComponentInfos.nY, aComponentInfos.nWidth, aComponentInfos.nHeight, aComponentInfos.nFlags ); + + if( aComponentInfos.bVisible && !bDesignMode ) + // Erst nach dem setzen der Daten anzeigen + xWindow->setVisible( aComponentInfos.bVisible ); + + if( !aComponentInfos.bEnable ) + xWindow->setEnable( aComponentInfos.bEnable ); + + xView->setGraphics( xGraphics ); + + peerCreated(); + + mbCreatingPeer = sal_False; + } +} + +Reference< XWindowPeer > UnoControl::getPeer() throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + return mxPeer; +} + +sal_Bool UnoControl::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + Reference< XMultiPropertySet > xPropSet( mxModel, UNO_QUERY ); + + // query for the XPropertiesChangeListener - our delegator is allowed to overwrite this interface + Reference< XPropertiesChangeListener > xListener; + queryInterface( ::getCppuType( &xListener ) ) >>= xListener; + + if( xPropSet.is() ) + xPropSet->removePropertiesChangeListener( xListener ); + + mpData->bLocalizationSupport = false; + mxModel = rxModel; + + if( mxModel.is() ) + { + try + { + xPropSet.set( mxModel, UNO_QUERY_THROW ); + Reference< XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), UNO_SET_THROW ); + + Sequence< ::rtl::OUString> aNames = lcl_ImplGetPropertyNames( xPropSet ); + xPropSet->addPropertiesChangeListener( aNames, xListener ); + + mpData->bLocalizationSupport = xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + mxModel.clear(); + } + } + + return mxModel.is(); +} + +Reference< XControlModel > UnoControl::getModel( ) throw(RuntimeException) +{ + return mxModel; +} + +Reference< XView > UnoControl::getView( ) throw(RuntimeException) +{ + return static_cast< XView* >( this ); +} + +void UnoControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException) +{ + ModeChangeEvent aModeChangeEvent; + + Reference< XWindow > xWindow; + { + ::osl::MutexGuard aGuard( GetMutex() ); + if ( bOn == mbDesignMode ) + return; + + // remember this + mbDesignMode = bOn; + xWindow = xWindow.query( getPeer() ); + // dispose our current AccessibleContext, if we have one + // (changing the design mode implies having a new implementation for this context, + // so the old one must be declared DEFUNC) + disposeAccessibleContext(); + + aModeChangeEvent.Source = *this; + aModeChangeEvent.NewMode = ::rtl::OUString::createFromAscii( mbDesignMode ? "design" : "alive" ); + } + + // ajust the visibility of our window + if ( xWindow.is() ) + xWindow->setVisible( !bOn ); + + // and notify our mode listeners + maModeChangeListeners.notifyEach( &XModeChangeListener::modeChanged, aModeChangeEvent ); +} + +sal_Bool UnoControl::isDesignMode( ) throw(RuntimeException) +{ + return mbDesignMode; +} + +sal_Bool UnoControl::isTransparent( ) throw(RuntimeException) +{ + return sal_False; +} + +// XServiceInfo +::rtl::OUString UnoControl::getImplementationName( ) throw(RuntimeException) +{ + DBG_ERROR( "This method should be overloaded!" ); + return ::rtl::OUString(); +} + +sal_Bool UnoControl::supportsService( const ::rtl::OUString& rServiceName ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); + const ::rtl::OUString* pArray = aSNL.getConstArray(); + const ::rtl::OUString* pArrayEnd = aSNL.getConstArray(); + for (; pArray != pArrayEnd; ++pArray ) + if( *pArray == rServiceName ) + break; + + return pArray != pArrayEnd; +} + +Sequence< ::rtl::OUString > UnoControl::getSupportedServiceNames( ) throw(RuntimeException) +{ + ::rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) ); + return Sequence< ::rtl::OUString >( &sName, 1 ); +} + +// ------------------------------------------------------------------------ +Reference< XAccessibleContext > SAL_CALL UnoControl::getAccessibleContext( ) throw (RuntimeException) +{ + // creation of the context will certainly require the SolarMutex ... + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( GetMutex() ); + + Reference< XAccessibleContext > xCurrentContext( maAccessibleContext.get(), UNO_QUERY ); + if ( !xCurrentContext.is() ) + { + if ( !mbDesignMode ) + { // in alive mode, use the AccessibleContext of the peer + Reference< XAccessible > xPeerAcc( getPeer(), UNO_QUERY ); + if ( xPeerAcc.is() ) + xCurrentContext = xPeerAcc->getAccessibleContext( ); + } + else + // in design mode, use a fallback + xCurrentContext = ::toolkit::OAccessibleControlContext::create( this ); + + DBG_ASSERT( xCurrentContext.is(), "UnoControl::getAccessibleContext: invalid context (invalid peer?)!" ); + maAccessibleContext = xCurrentContext; + + // get notified when the context is disposed + Reference< XComponent > xContextComp( xCurrentContext, UNO_QUERY ); + if ( xContextComp.is() ) + xContextComp->addEventListener( this ); + // In an ideal world, this is not necessary - there the object would be released as soon as it has been + // disposed, and thus our weak reference would be empty, too. + // But 'til this ideal world comes (means 'til we do never have any refcount/lifetime bugs anymore), we + // need to listen for disposal and reset our weak reference then. + } + + return xCurrentContext; +} + +void SAL_CALL UnoControl::addModeChangeListener( const Reference< XModeChangeListener >& _rxListener ) throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + maModeChangeListeners.addInterface( _rxListener ); +} + +void SAL_CALL UnoControl::removeModeChangeListener( const Reference< XModeChangeListener >& _rxListener ) throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + maModeChangeListeners.removeInterface( _rxListener ); +} + +void SAL_CALL UnoControl::addModeChangeApproveListener( const Reference< XModeChangeApproveListener >& ) throw (NoSupportException, RuntimeException) +{ + throw NoSupportException( ); +} + +void SAL_CALL UnoControl::removeModeChangeApproveListener( const Reference< XModeChangeApproveListener >& ) throw (NoSupportException, RuntimeException) +{ + throw NoSupportException( ); +} + diff --git a/toolkit/source/controls/unocontrolbase.cxx b/toolkit/source/controls/unocontrolbase.cxx new file mode 100644 index 000000000000..b59b8e05b9d9 --- /dev/null +++ b/toolkit/source/controls/unocontrolbase.cxx @@ -0,0 +1,288 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontrolbase.cxx,v $ + * $Revision: 1.10 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/XLayoutConstrains.hpp> +#include <com/sun/star/awt/XTextLayoutConstrains.hpp> + +#include <toolkit/controls/unocontrolbase.hxx> +#include <toolkit/helper/property.hxx> + +#include <tools/debug.hxx> + +// ---------------------------------------------------- +// class UnoControlBase +// ---------------------------------------------------- + +sal_Bool UnoControlBase::ImplHasProperty( sal_uInt16 nPropId ) +{ + ::rtl::OUString aPropName( GetPropertyName( nPropId ) ); + return ImplHasProperty( aPropName ); +} + +sal_Bool UnoControlBase::ImplHasProperty( const ::rtl::OUString& aPropertyName ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY ); + if ( !xPSet.is() ) + return sal_False; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = xPSet->getPropertySetInfo(); + if ( !xInfo.is() ) + return sal_False; + + return xInfo->hasPropertyByName( aPropertyName ); +} + +void UnoControlBase::ImplSetPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues, sal_Bool bUpdateThis ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet > xMPS( mxModel, ::com::sun::star::uno::UNO_QUERY ); + if ( !mxModel.is() ) + return; + + DBG_ASSERT( xMPS.is(), "UnoControlBase::ImplSetPropertyValues: no multi property set interface!" ); + if ( xMPS.is() ) + { + if ( !bUpdateThis ) + ImplLockPropertyChangeNotifications( aPropertyNames, true ); + + try + { + xMPS->setPropertyValues( aPropertyNames, aValues ); + } + catch( const ::com::sun::star::uno::Exception& ) + { + if ( !bUpdateThis ) + ImplLockPropertyChangeNotifications( aPropertyNames, false ); + } + if ( !bUpdateThis ) + ImplLockPropertyChangeNotifications( aPropertyNames, false ); + } + else + { + int dummy = 0; + (void)dummy; + } +} + +void UnoControlBase::ImplSetPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue, sal_Bool bUpdateThis ) +{ + // Model ggf. schon abgemeldet, aber ein Event schlaegt noch zu... + if ( mxModel.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY ); + if ( !bUpdateThis ) + ImplLockPropertyChangeNotification( aPropertyName, true ); + + try + { + xPSet->setPropertyValue( aPropertyName, aValue ); + } + catch( const com::sun::star::uno::Exception& ) + { + if ( !bUpdateThis ) + ImplLockPropertyChangeNotification( aPropertyName, false ); + throw; + } + if ( !bUpdateThis ) + ImplLockPropertyChangeNotification( aPropertyName, false ); + } +} + +::com::sun::star::uno::Any UnoControlBase::ImplGetPropertyValue( const ::rtl::OUString& aPropertyName ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPSet( mxModel, ::com::sun::star::uno::UNO_QUERY ); + if ( xPSet.is() ) + return xPSet->getPropertyValue( aPropertyName ); + else + return ::com::sun::star::uno::Any(); +} + +sal_Bool UnoControlBase::ImplGetPropertyValue_BOOL( sal_uInt16 nProp ) +{ + sal_Bool b = sal_False; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= b; + } + return b; +} + +sal_Int16 UnoControlBase::ImplGetPropertyValue_INT16( sal_uInt16 nProp ) +{ + sal_Int16 n = 0; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= n; + } + return n; +} + +sal_uInt16 UnoControlBase::ImplGetPropertyValue_UINT16( sal_uInt16 nProp ) +{ + sal_uInt16 n = 0; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= n; + } + return n; +} + +sal_Int32 UnoControlBase::ImplGetPropertyValue_INT32( sal_uInt16 nProp ) +{ + sal_Int32 n = 0; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= n; + } + return n; +} + +sal_uInt32 UnoControlBase::ImplGetPropertyValue_UINT32( sal_uInt16 nProp ) +{ + sal_uInt32 n = 0; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= n; + } + return n; +} + +double UnoControlBase::ImplGetPropertyValue_DOUBLE( sal_uInt16 nProp ) +{ + double n = 0; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= n; + } + return n; +} + +::rtl::OUString UnoControlBase::ImplGetPropertyValue_UString( sal_uInt16 nProp ) +{ + ::rtl::OUString aStr; + if ( mxModel.is() ) + { + ::com::sun::star::uno::Any aVal = ImplGetPropertyValue( GetPropertyName( nProp ) ); + aVal >>= aStr; + } + return aStr; +} + +::com::sun::star::awt::Size UnoControlBase::Impl_getMinimumSize() +{ + ::com::sun::star::awt::Size aSz; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xP = ImplGetCompatiblePeer( sal_True ); + DBG_ASSERT( xP.is(), "Layout: No Peer!" ); + if ( xP.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY ); + if ( xL.is() ) + aSz = xL->getMinimumSize(); + + if ( !getPeer().is() || ( getPeer() != xP ) ) + xP->dispose(); + } + return aSz; +} + +::com::sun::star::awt::Size UnoControlBase::Impl_getPreferredSize() +{ + ::com::sun::star::awt::Size aSz; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xP = ImplGetCompatiblePeer( sal_True ); + DBG_ASSERT( xP.is(), "Layout: No Peer!" ); + if ( xP.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY ); + if ( xL.is() ) + aSz = xL->getPreferredSize(); + + if ( !getPeer().is() || ( getPeer() != xP ) ) + xP->dispose(); + } + return aSz; +} + +::com::sun::star::awt::Size UnoControlBase::Impl_calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) +{ + ::com::sun::star::awt::Size aSz; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xP = ImplGetCompatiblePeer( sal_True ); + DBG_ASSERT( xP.is(), "Layout: No Peer!" ); + if ( xP.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY ); + if ( xL.is() ) + aSz = xL->calcAdjustedSize( rNewSize ); + + if ( !getPeer().is() || ( getPeer() != xP ) ) + xP->dispose(); + } + return aSz; +} + +::com::sun::star::awt::Size UnoControlBase::Impl_getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) +{ + ::com::sun::star::awt::Size aSz; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xP = ImplGetCompatiblePeer( sal_True ); + DBG_ASSERT( xP.is(), "Layout: No Peer!" ); + if ( xP.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY ); + if ( xL.is() ) + aSz = xL->getMinimumSize( nCols, nLines ); + + if ( !getPeer().is() || ( getPeer() != xP ) ) + xP->dispose(); + } + return aSz; +} + +void UnoControlBase::Impl_getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xP = ImplGetCompatiblePeer( sal_True ); + DBG_ASSERT( xP.is(), "Layout: No Peer!" ); + if ( xP.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains > xL( xP, ::com::sun::star::uno::UNO_QUERY ); + if ( xL.is() ) + xL->getColumnsAndLines( nCols, nLines ); + + if ( !getPeer().is() || ( getPeer() != xP ) ) + xP->dispose(); + } +} + + + diff --git a/toolkit/source/controls/unocontrolcontainer.cxx b/toolkit/source/controls/unocontrolcontainer.cxx new file mode 100644 index 000000000000..e7695b8fb819 --- /dev/null +++ b/toolkit/source/controls/unocontrolcontainer.cxx @@ -0,0 +1,837 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontrolcontainer.cxx,v $ + * $Revision: 1.20 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + + +#include <com/sun/star/awt/XVclContainerPeer.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> + +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/implbase1.hxx> +#include <rtl/memory.h> +#include <rtl/uuid.h> + +#include <toolkit/controls/unocontrolcontainer.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <comphelper/sequence.hxx> + +#include <tools/debug.hxx> +#include <tools/list.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> + +#include <limits> +#include <map> +#include <boost/shared_ptr.hpp> + +using namespace ::com::sun::star; + +extern WorkWindow* lcl_GetDefaultWindow(); + +// ---------------------------------------------------- +// class UnoControlHolder +// ---------------------------------------------------- +struct UnoControlHolder +{ + uno::Reference< awt::XControl > mxControl; + ::rtl::OUString msName; + +public: + UnoControlHolder( const ::rtl::OUString& rName, const uno::Reference< awt::XControl > & rControl ) + : mxControl( rControl ), + msName( rName ) + { + } + + inline const ::rtl::OUString& getName() const { return msName; } + inline const uno::Reference< awt::XControl >& getControl() const { return mxControl; } +}; + +//DECLARE_LIST( UnoControlHolderList, UnoControlHolder* ); + +class UnoControlHolderList +{ +public: + typedef sal_Int32 ControlIdentifier; +private: + typedef ::boost::shared_ptr< UnoControlHolder > ControlInfo; + typedef ::std::map< ControlIdentifier, ControlInfo > ControlMap; + +private: + ControlMap maControls; + +public: + UnoControlHolderList(); + ~UnoControlHolderList(); + + /** adds a control with the given name to the list + @param _rxControl + the control to add. Must not be <NULL/> + @param _pBName + the name of the control, or <NULL/> if an automatic name should be generated + @return + the identifier of the newly added control + */ + ControlIdentifier addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ); + + /** returns the number of controls in the list + */ + inline size_t size() const { return maControls.size(); } + + /** determines whether or not the list is empty + */ + inline bool empty() const { return maControls.empty(); } + + /** retrieves all controls currently in the list + @return + the number of controls in the list + */ + size_t getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const; + + /** retrieves all identifiers of all controls currently in the list + @return + the number of controls in the list + */ + size_t getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const; + + /** returns the first control which is registered under the given name + */ + uno::Reference< awt::XControl > + getControlForName( const ::rtl::OUString& _rName ) const; + + /** returns the identifier which a control is registered for, or -1 if the control + isn't registered + */ + ControlIdentifier + getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl ); + + /** retrieves the control for a given id + @param _nIdentifier + the identifier for the control + @param _out_rxControl + takes the XControl upon successful return + @return + <TRUE/> if and only if a control with the given id is part of the list + */ + bool getControlForIdentifier( ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const; + + /** removes a control from the list, given by id + @param _nId + The identifier of the control to remove. + */ + void removeControlById( ControlIdentifier _nId ); + + /** replaces a control from the list with another one + @param _nId + The identifier of the control to replace + @param _rxNewControl + the new control to put into the list + */ + void replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl ); + +private: + /** adds a control + @param _rxControl + the control to add to the container + @param _pName + pointer to the name of the control. Might be <NULL/>, in this case, a name is generated. + @return + the identifier of the newly inserted control + */ + ControlIdentifier impl_addControl( + const uno::Reference< awt::XControl >& _rxControl, + const ::rtl::OUString* _pName + ); + + /** finds a free identifier + @throw uno::RuntimeException + if no free identifier can be found + */ + ControlIdentifier impl_getFreeIdentifier_throw(); + + /** finds a free name + @throw uno::RuntimeException + if no free name can be found + */ + ::rtl::OUString impl_getFreeName_throw(); +}; + +//------------------------------------------------------------------------ +UnoControlHolderList::UnoControlHolderList() +{ +} + +//------------------------------------------------------------------------ +UnoControlHolderList::~UnoControlHolderList() +{ +} + +//------------------------------------------------------------------------ +UnoControlHolderList::ControlIdentifier UnoControlHolderList::addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ) +{ + return impl_addControl( _rxControl, _pName ); +} + +//------------------------------------------------------------------------ +size_t UnoControlHolderList::getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const +{ + _out_rControls.realloc( maControls.size() ); + uno::Reference< awt::XControl >* pControls = _out_rControls.getArray(); + for ( ControlMap::const_iterator loop = maControls.begin(); + loop != maControls.end(); + ++loop, ++pControls + ) + *pControls = loop->second->getControl(); + return maControls.size(); +} + +//------------------------------------------------------------------------ +size_t UnoControlHolderList::getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const +{ + _out_rIdentifiers.realloc( maControls.size() ); + sal_Int32* pIndentifiers = _out_rIdentifiers.getArray(); + for ( ControlMap::const_iterator loop = maControls.begin(); + loop != maControls.end(); + ++loop, ++pIndentifiers + ) + *pIndentifiers = loop->first; + return maControls.size(); +} + +//------------------------------------------------------------------------ +uno::Reference< awt::XControl > UnoControlHolderList::getControlForName( const ::rtl::OUString& _rName ) const +{ + for ( ControlMap::const_iterator loop = maControls.begin(); + loop != maControls.end(); + ++loop + ) + if ( loop->second->getName() == _rName ) + return loop->second->getControl(); + return uno::Reference< awt::XControl >(); +} + +//------------------------------------------------------------------------ +UnoControlHolderList::ControlIdentifier UnoControlHolderList::getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl ) +{ + for ( ControlMap::iterator loop = maControls.begin(); + loop != maControls.end(); + ++loop + ) + { + if ( loop->second->getControl().get() == _rxControl.get() ) + return loop->first; + } + return -1; +} + +//------------------------------------------------------------------------ +bool UnoControlHolderList::getControlForIdentifier( UnoControlHolderList::ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const +{ + ControlMap::const_iterator pos = maControls.find( _nIdentifier ); + if ( pos == maControls.end() ) + return false; + _out_rxControl = pos->second->getControl(); + return true; +} + +//------------------------------------------------------------------------ +void UnoControlHolderList::removeControlById( UnoControlHolderList::ControlIdentifier _nId ) +{ + ControlMap::iterator pos = maControls.find( _nId ); + DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::removeControlById: invalid id!" ); + if ( pos == maControls.end() ) + return; + + maControls.erase( pos ); +} + +//------------------------------------------------------------------------ +void UnoControlHolderList::replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl ) +{ + DBG_ASSERT( _rxNewControl.is(), "UnoControlHolderList::replaceControlById: invalid new control!" ); + + ControlMap::iterator pos = maControls.find( _nId ); + DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::replaceControlById: invalid id!" ); + if ( pos == maControls.end() ) + return; + + pos->second.reset( new UnoControlHolder( pos->second->getName(), _rxNewControl ) ); +} + +//------------------------------------------------------------------------ +UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ) +{ + DBG_ASSERT( _rxControl.is(), "UnoControlHolderList::impl_addControl: invalid control!" ); + + ::rtl::OUString sName = _pName ? *_pName : impl_getFreeName_throw(); + sal_Int32 nId = impl_getFreeIdentifier_throw(); + + maControls[ nId ] = ControlInfo( new UnoControlHolder( sName, _rxControl ) ); + return nId; +} + +//------------------------------------------------------------------------ +UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_getFreeIdentifier_throw() +{ + for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId ) + { + ControlMap::const_iterator existent = maControls.find( candidateId ); + if ( existent == maControls.end() ) + return candidateId; + } + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL ); +} + +//------------------------------------------------------------------------ +::rtl::OUString UnoControlHolderList::impl_getFreeName_throw() +{ + ::rtl::OUString name( RTL_CONSTASCII_USTRINGPARAM( "control_" ) ); + for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId ) + { + ::rtl::OUString candidateName( name + ::rtl::OUString::valueOf( candidateId ) ); + ControlMap::const_iterator loop = maControls.begin(); + for ( ; loop != maControls.end(); ++loop ) + { + if ( loop->second->getName() == candidateName ) + break; + } + if ( loop == maControls.end() ) + return candidateName; + } + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL ); +} +// ---------------------------------------------------- +// Function to set the controls' visibility according +// to the dialog's "Step" property +// ---------------------------------------------------- +void implUpdateVisibility +( + sal_Int32 nDialogStep, + uno::Reference< awt::XControlContainer > xControlContainer +) +{ + uno::Sequence< uno::Reference< awt::XControl > > + aCtrls = xControlContainer->getControls(); + const uno::Reference< awt::XControl >* pCtrls = aCtrls.getConstArray(); + sal_uInt32 nCtrls = aCtrls.getLength(); + sal_Bool bCompleteVisible = (nDialogStep == 0); + for( sal_uInt32 n = 0; n < nCtrls; n++ ) + { + uno::Reference< awt::XControl > xControl = pCtrls[ n ]; + + sal_Bool bVisible = bCompleteVisible; + if( !bVisible ) + { + uno::Reference< awt::XControlModel > xModel( xControl->getModel() ); + uno::Reference< beans::XPropertySet > xPSet + ( xModel, uno::UNO_QUERY ); + uno::Reference< beans::XPropertySetInfo > + xInfo = xPSet->getPropertySetInfo(); + ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); + sal_Int32 nControlStep = 0; + if ( xInfo->hasPropertyByName( aPropName ) ) + { + uno::Any aVal = xPSet->getPropertyValue( aPropName ); + aVal >>= nControlStep; + } + bVisible = (nControlStep == 0) || (nControlStep == nDialogStep); + } + + uno::Reference< awt::XWindow> xWindow + ( xControl, uno::UNO_QUERY ); + if( xWindow.is() ) + xWindow->setVisible( bVisible ); + } +} + + +// ---------------------------------------------------- +// class DialogStepChangedListener +// ---------------------------------------------------- +typedef ::cppu::WeakImplHelper1< beans::XPropertyChangeListener > PropertyChangeListenerHelper; + +class DialogStepChangedListener: public PropertyChangeListenerHelper +{ +private: + uno::Reference< awt::XControlContainer > mxControlContainer; + +public: + DialogStepChangedListener( uno::Reference< awt::XControlContainer > xControlContainer ) + : mxControlContainer( xControlContainer ) {} + + // XEventListener + virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw( uno::RuntimeException); + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const beans::PropertyChangeEvent& evt ) throw( uno::RuntimeException); + +}; + +void SAL_CALL DialogStepChangedListener::disposing( const lang::EventObject& /*_rSource*/) + throw( uno::RuntimeException) +{ + mxControlContainer.clear(); +} + +void SAL_CALL DialogStepChangedListener::propertyChange( const beans::PropertyChangeEvent& evt ) + throw( uno::RuntimeException) +{ + // evt.PropertyName HAS to be "Step" because we only use the listener for that + sal_Int32 nDialogStep = 0; + evt.NewValue >>= nDialogStep; + implUpdateVisibility( nDialogStep, mxControlContainer ); +} + +// ---------------------------------------------------- +// class UnoControlContainer +// ---------------------------------------------------- +UnoControlContainer::UnoControlContainer() : maCListeners( *this ) +{ + mpControls = new UnoControlHolderList; +} + +UnoControlContainer::UnoControlContainer( uno::Reference< awt::XWindowPeer > xP ) + : maCListeners( *this ) +{ + setPeer( xP ); + mbDisposePeer = sal_False; + mpControls = new UnoControlHolderList; +} + +UnoControlContainer::~UnoControlContainer() +{ + DELETEZ( mpControls ); +} + +void UnoControlContainer::ImplActivateTabControllers() +{ + sal_uInt32 nCount = maTabControllers.getLength(); + for ( sal_uInt32 n = 0; n < nCount; n++ ) + { + maTabControllers.getArray()[n]->setContainer( this ); + maTabControllers.getArray()[n]->activateTabOrder(); + } +} + +// lang::XComponent +void UnoControlContainer::dispose( ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + lang::EventObject aDisposeEvent; + aDisposeEvent.Source = static_cast< uno::XAggregation* >( this ); + + // DG: zuerst der Welt mitteilen, dass der Container wegfliegt. Dieses ist um einiges + // schneller wenn die Welt sowohl an den Controls als auch am Container horcht + maDisposeListeners.disposeAndClear( aDisposeEvent ); + maCListeners.disposeAndClear( aDisposeEvent ); + + + uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls(); + uno::Reference< awt::XControl >* pCtrls = aCtrls.getArray(); + uno::Reference< awt::XControl >* pCtrlsEnd = pCtrls + aCtrls.getLength(); + + for( ; pCtrls < pCtrlsEnd; ++pCtrls ) + { + removingControl( *pCtrls ); + // Control wegwerfen + (*pCtrls)->dispose(); + } + + + // alle Strukturen entfernen + DELETEZ( mpControls ); + mpControls = new UnoControlHolderList; + + UnoControlBase::dispose(); +} + +// lang::XEventListener +void UnoControlContainer::disposing( const lang::EventObject& _rEvt ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + uno::Reference< awt::XControl > xControl( _rEvt.Source, uno::UNO_QUERY ); + if ( xControl.is() ) + removeControl( xControl ); + + UnoControlBase::disposing( _rEvt ); +} + +// container::XContainer +void UnoControlContainer::addContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + maCListeners.addInterface( rxListener ); +} + +void UnoControlContainer::removeContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + maCListeners.removeInterface( rxListener ); +} + + +::sal_Int32 SAL_CALL UnoControlContainer::insert( const uno::Any& _rElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + uno::Reference< awt::XControl > xControl; + if ( !( _rElement >>= xControl ) || !xControl.is() ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ), + *this, + 1 + ); + + return impl_addControl( xControl, NULL ); +} + +void SAL_CALL UnoControlContainer::removeByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + uno::Reference< awt::XControl > xControl; + if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) ) + throw container::NoSuchElementException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ), + *this + ); + + impl_removeControl( _nIdentifier, xControl, NULL ); +} + +void SAL_CALL UnoControlContainer::replaceByIdentifer( ::sal_Int32 _nIdentifier, const uno::Any& _rElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + uno::Reference< awt::XControl > xExistentControl; + if ( !mpControls->getControlForIdentifier( _nIdentifier, xExistentControl ) ) + throw container::NoSuchElementException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ), + *this + ); + + uno::Reference< awt::XControl > xNewControl; + if ( !( _rElement >>= xNewControl ) ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ), + *this, + 1 + ); + + removingControl( xExistentControl ); + + mpControls->replaceControlById( _nIdentifier, xNewControl ); + + addingControl( xNewControl ); + + impl_createControlPeerIfNecessary( xNewControl ); + + if ( maCListeners.getLength() ) + { + container::ContainerEvent aEvent; + aEvent.Source = *this; + aEvent.Accessor <<= _nIdentifier; + aEvent.Element <<= xNewControl; + aEvent.ReplacedElement <<= xExistentControl; + maCListeners.elementReplaced( aEvent ); + } +} + +uno::Any SAL_CALL UnoControlContainer::getByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + uno::Reference< awt::XControl > xControl; + if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) ) + throw container::NoSuchElementException(); + return uno::makeAny( xControl ); +} + +uno::Sequence< ::sal_Int32 > SAL_CALL UnoControlContainer::getIdentifiers( ) throw (uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + uno::Sequence< ::sal_Int32 > aIdentifiers; + mpControls->getIdentifiers( aIdentifiers ); + return aIdentifiers; +} + +// container::XElementAccess +uno::Type SAL_CALL UnoControlContainer::getElementType( ) throw (uno::RuntimeException) +{ + return awt::XControlModel::static_type(); +} + +::sal_Bool SAL_CALL UnoControlContainer::hasElements( ) throw (uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return !mpControls->empty(); +} + +// awt::XControlContainer +void UnoControlContainer::setStatusText( const ::rtl::OUString& rStatusText ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + // In der Parenthierarchie nach unten gehen + uno::Reference< awt::XControlContainer > xContainer( mxContext, uno::UNO_QUERY ); + if( xContainer.is() ) + xContainer->setStatusText( rStatusText ); +} + +uno::Sequence< uno::Reference< awt::XControl > > UnoControlContainer::getControls( ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + uno::Sequence< uno::Reference< awt::XControl > > aControls; + mpControls->getControls( aControls ); + return aControls; +} + +uno::Reference< awt::XControl > UnoControlContainer::getControl( const ::rtl::OUString& rName ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + return mpControls->getControlForName( rName ); +} + +void UnoControlContainer::addingControl( const uno::Reference< awt::XControl >& _rxControl ) +{ + if ( _rxControl.is() ) + { + uno::Reference< uno::XInterface > xThis; + OWeakAggObject::queryInterface( ::getCppuType( static_cast< uno::Reference< uno::XInterface >* >( NULL ) ) ) >>= xThis; + + _rxControl->setContext( xThis ); + _rxControl->addEventListener( this ); + } +} + +void UnoControlContainer::impl_createControlPeerIfNecessary( const uno::Reference< awt::XControl >& _rxControl ) +{ + OSL_PRECOND( _rxControl.is(), "UnoControlContainer::impl_createControlPeerIfNecessary: invalid control, this will crash!" ); + + // if the container already has a peer, then also create a peer for the control + uno::Reference< awt::XWindowPeer > xMyPeer( getPeer() ); + + if( xMyPeer.is() ) + { + _rxControl->createPeer( NULL, xMyPeer ); + ImplActivateTabControllers(); + } + +} + +sal_Int32 UnoControlContainer::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + UnoControlHolderList::ControlIdentifier id = mpControls->addControl( _rxControl, _pName ); + + addingControl( _rxControl ); + + impl_createControlPeerIfNecessary( _rxControl ); + + if ( maCListeners.getLength() ) + { + container::ContainerEvent aEvent; + aEvent.Source = *this; + _pName ? ( aEvent.Accessor <<= *_pName ) : ( aEvent.Accessor <<= (sal_Int32)id ); + aEvent.Element <<= _rxControl; + maCListeners.elementInserted( aEvent ); + } + + return id; +} + +void UnoControlContainer::addControl( const ::rtl::OUString& rName, const uno::Reference< awt::XControl >& rControl ) throw(uno::RuntimeException) +{ + if ( rControl.is() ) + impl_addControl( rControl, &rName ); +} + +void UnoControlContainer::removingControl( const uno::Reference< awt::XControl >& _rxControl ) +{ + if ( _rxControl.is() ) + { + _rxControl->removeEventListener( this ); + _rxControl->setContext( NULL ); + } +} + +void UnoControlContainer::impl_removeControl( sal_Int32 _nId, const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pNameAccessor ) +{ +#ifdef DBG_UTIL + { + uno::Reference< awt::XControl > xControl; + bool bHas = mpControls->getControlForIdentifier( _nId, xControl ); + DBG_ASSERT( bHas && xControl == _rxControl, "UnoControlContainer::impl_removeControl: inconsistency in the parameters!" ); + } +#endif + removingControl( _rxControl ); + + mpControls->removeControlById( _nId ); + + if ( maCListeners.getLength() ) + { + container::ContainerEvent aEvent; + aEvent.Source = *this; + _pNameAccessor ? ( aEvent.Accessor <<= *_pNameAccessor ) : ( aEvent.Accessor <<= _nId ); + aEvent.Element <<= _rxControl; + maCListeners.elementRemoved( aEvent ); + } +} + +void UnoControlContainer::removeControl( const uno::Reference< awt::XControl >& _rxControl ) throw(uno::RuntimeException) +{ + if ( _rxControl.is() ) + { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + UnoControlHolderList::ControlIdentifier id = mpControls->getControlIdentifier( _rxControl ); + if ( id != -1 ) + impl_removeControl( id, _rxControl, NULL ); + } +} + + + +// awt::XUnoControlContainer +void UnoControlContainer::setTabControllers( const uno::Sequence< uno::Reference< awt::XTabController > >& TabControllers ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + maTabControllers = TabControllers; +} + +uno::Sequence< uno::Reference< awt::XTabController > > UnoControlContainer::getTabControllers( ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return maTabControllers; +} + +void UnoControlContainer::addTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_uInt32 nCount = maTabControllers.getLength(); + maTabControllers.realloc( nCount + 1 ); + maTabControllers[ nCount ] = TabController; +} + +void UnoControlContainer::removeTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_uInt32 nCount = maTabControllers.getLength(); + const uno::Reference< awt::XTabController >* pLoop = maTabControllers.getConstArray(); + for ( sal_uInt32 n = 0; n < nCount; ++n, ++pLoop ) + { + if( pLoop->get() == TabController.get() ) + { + ::comphelper::removeElementAt( maTabControllers, n ); + break; + } + } +} + +// awt::XControl +void UnoControlContainer::createPeer( const uno::Reference< awt::XToolkit >& rxToolkit, const uno::Reference< awt::XWindowPeer >& rParent ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + if( !getPeer().is() ) + { + sal_Bool bVis = maComponentInfos.bVisible; + if( bVis ) + UnoControl::setVisible( sal_False ); + // eigenes Peer erzeugen + UnoControl::createPeer( rxToolkit, rParent ); + + // alle Peers der Childs erzeugen + if ( !mbCreatingCompatiblePeer ) + { + // Evaluate "Step" property + uno::Reference< awt::XControlModel > xModel( getModel() ); + uno::Reference< beans::XPropertySet > xPSet + ( xModel, uno::UNO_QUERY ); + uno::Reference< beans::XPropertySetInfo > + xInfo = xPSet->getPropertySetInfo(); + ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); + if ( xInfo->hasPropertyByName( aPropName ) ) + { + ::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName ); + sal_Int32 nDialogStep = 0; + aVal >>= nDialogStep; + uno::Reference< awt::XControlContainer > xContainer = + SAL_STATIC_CAST( awt::XControlContainer*, this ); + implUpdateVisibility( nDialogStep, xContainer ); + + uno::Reference< beans::XPropertyChangeListener > xListener = + SAL_STATIC_CAST( beans::XPropertyChangeListener*, + new DialogStepChangedListener( xContainer ) ); + xPSet->addPropertyChangeListener( aPropName, xListener ); + } + + uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls(); + sal_uInt32 nCtrls = aCtrls.getLength(); + for( sal_uInt32 n = 0; n < nCtrls; n++ ) + aCtrls.getArray()[n]->createPeer( rxToolkit, getPeer() ); + + uno::Reference< awt::XVclContainerPeer > xC( getPeer(), uno::UNO_QUERY ); + + xC->enableDialogControl( sal_True ); + ImplActivateTabControllers(); + } + + if( bVis && !isDesignMode() ) + UnoControl::setVisible( sal_True ); + } +} + + +// awt::XWindow +void UnoControlContainer::setVisible( sal_Bool bVisible ) throw(uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + UnoControl::setVisible( bVisible ); + if( !mxContext.is() && bVisible ) + // Es ist ein TopWindow, also automatisch anzeigen + createPeer( uno::Reference< awt::XToolkit > (), uno::Reference< awt::XWindowPeer > () ); +} + + + diff --git a/toolkit/source/controls/unocontrolcontainermodel.cxx b/toolkit/source/controls/unocontrolcontainermodel.cxx new file mode 100644 index 000000000000..6262c3f77839 --- /dev/null +++ b/toolkit/source/controls/unocontrolcontainermodel.cxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontrolcontainermodel.cxx,v $ + * $Revision: 1.6 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" + +#include <toolkit/controls/unocontrolcontainermodel.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <toolkit/helper/unopropertyarrayhelper.hxx> + +// ---------------------------------------------------- +// class UnoControlContainerModel +// ---------------------------------------------------- +UnoControlContainerModel::UnoControlContainerModel() +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_TEXT ); +} + +::rtl::OUString UnoControlContainerModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlContainerModel ); +} + +::com::sun::star::uno::Any UnoControlContainerModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + ::com::sun::star::uno::Any aDefault; + if ( nPropId == BASEPROPERTY_BORDER ) + aDefault <<= (sal_Int16) 0; + else + aDefault <<= UnoControlModel::ImplGetDefaultValue( nPropId ); + return aDefault; +} + + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > UnoControlContainerModel::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException) +{ + static ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +::cppu::IPropertyArrayHelper& UnoControlContainerModel::getInfoHelper() +{ + ::osl::Guard< ::osl::Mutex > aGuard( ((UnoControlContainerModel*)this)->GetMutex() ); + + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + ::com::sun::star::uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + + + + diff --git a/toolkit/source/controls/unocontrolmodel.cxx b/toolkit/source/controls/unocontrolmodel.cxx new file mode 100644 index 000000000000..a4febcd33b33 --- /dev/null +++ b/toolkit/source/controls/unocontrolmodel.cxx @@ -0,0 +1,1498 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontrolmodel.cxx,v $ + * $Revision: 1.62 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/awt/FontWidth.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/MouseWheelBehavior.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/io/XMarkableStream.hpp> +#include <toolkit/controls/unocontrolmodel.hxx> +#include <toolkit/helper/macros.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/extract.hxx> +#include <rtl/memory.h> +#include <rtl/uuid.h> +#include <tools/diagnose_ex.h> +#include <tools/string.hxx> +#include <tools/table.hxx> +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/urlobj.hxx> +#include <tools/debug.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/helper/emptyfontdescriptor.hxx> +#include <com/sun/star/lang/Locale.hpp> +#include <unotools/localedatawrapper.hxx> +#include <unotools/configmgr.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> +#include <vcl/svapp.hxx> +#include <uno/data.h> + +#include <memory> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::i18n; +using ::com::sun::star::awt::FontDescriptor; + +struct ImplControlProperty +{ +private: + sal_uInt16 nId; + ::com::sun::star::uno::Any aValue; + +public: + ImplControlProperty( const ImplControlProperty& rProp ) : aValue( rProp.aValue ) + { + nId = rProp.nId; + } + + ImplControlProperty( sal_uInt16 nT ) + { + nId = nT; + } + + ImplControlProperty( sal_uInt16 nT, const ::com::sun::star::uno::Any& rValue ) : aValue( rValue ) + { + nId = nT; + } + + sal_uInt16 GetId() const { return nId; } + const ::com::sun::star::uno::Any& GetValue() const { return aValue; } + void SetValue( const ::com::sun::star::uno::Any& rValue ) { aValue = rValue; } +}; + +DECLARE_TABLE( ImplPropertyTable, ImplControlProperty* ) + +#define UNOCONTROL_STREAMVERSION (short)2 + +static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, const Any& rValue ) +{ + // some props are defined with other types than the matching FontDescriptor members have + // (e.g. FontWidth, FontSlant) + // 78474 - 09/19/2000 - FS + float nExtractFloat = 0; + sal_Int16 nExtractShort = 0; + + switch ( nPropId ) + { + case BASEPROPERTY_FONTDESCRIPTORPART_NAME: rValue >>= rFD.Name; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: rValue >>= rFD.StyleName; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: rValue >>= rFD.Family; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: rValue >>= rFD.CharSet; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: rValue >>= nExtractFloat; rFD.Height = (sal_Int16)nExtractFloat; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: rValue >>= rFD.Weight; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: if ( rValue >>= nExtractShort ) + rFD.Slant = (::com::sun::star::awt::FontSlant)nExtractShort; + else + rValue >>= rFD.Slant; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: rValue >>= rFD.Underline; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: rValue >>= rFD.Strikeout; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: rValue >>= rFD.Width; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: rValue >>= rFD.Pitch; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: rValue >>= rFD.CharacterWidth; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: rValue >>= rFD.Orientation; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: rValue >>= rFD.Kerning; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: rValue >>= rFD.WordLineMode; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: rValue >>= rFD.Type; + break; + default: DBG_ERROR( "FontProperty?!" ); + } +} + +// ---------------------------------------------------- +// class UnoControlModel +// ---------------------------------------------------- +UnoControlModel::UnoControlModel() + : OPropertySetHelper( BrdcstHelper ), maDisposeListeners( *this ) +{ + // Die Properties muessen vom Model in die Tabelle gestopft werden, + // nur vorhandene Properties sind gueltige Properties, auch wenn VOID. + mpData = new ImplPropertyTable; +} + +UnoControlModel::UnoControlModel( const UnoControlModel& rModel ) + : XControlModel() + , XPropertyState() + , XPersistObject() + , XComponent() + , XServiceInfo() + , XTypeProvider() + , XUnoTunnel() + , XCloneable() + , MutexAndBroadcastHelper() + , OPropertySetHelper( BrdcstHelper ) + , OWeakAggObject() + , maDisposeListeners( *this ) +{ + mpData = new ImplPropertyTable; + + for ( sal_uInt32 n = rModel.mpData->Count(); n; ) + { + ImplControlProperty* pProp = rModel.mpData->GetObject( --n ); + ImplControlProperty* pNew = new ImplControlProperty( *pProp ); + mpData->Insert( pNew->GetId(), pNew ); + } +} + +UnoControlModel::~UnoControlModel() +{ + for ( sal_uInt32 n = mpData->Count(); n; ) + delete mpData->GetObject( --n ); + delete mpData; +} + +UnoControlModel* UnoControlModel::Clone() const +{ + DBG_ERROR( "UnoControlModel::Clone() ?!" ); + return NULL; +} + +::com::sun::star::uno::Sequence<sal_Int32> UnoControlModel::ImplGetPropertyIds() const +{ + sal_uInt32 nIDs = mpData->Count(); + ::com::sun::star::uno::Sequence<sal_Int32> aIDs( nIDs ); + sal_Int32* pIDs = aIDs.getArray(); + for ( sal_uInt32 n = 0; n < nIDs; n++ ) + pIDs[n] = mpData->GetObjectKey( n ); + return aIDs; +} + +sal_Bool UnoControlModel::ImplHasProperty( sal_uInt16 nPropId ) const +{ + if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) ) + nPropId = BASEPROPERTY_FONTDESCRIPTOR; + + return mpData->Get( nPropId ) ? sal_True : sal_False; +} + +void UnoControlModel::ImplPropertyChanged( sal_uInt16 ) +{ +} + +::com::sun::star::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + ::com::sun::star::uno::Any aDefault; + + if ( + (nPropId == BASEPROPERTY_FONTDESCRIPTOR) || + ( + (nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START) && + (nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END) + ) + ) + { + EmptyFontDescriptor aFD; + switch ( nPropId ) + { + case BASEPROPERTY_FONTDESCRIPTOR: aDefault <<= aFD; break; + case BASEPROPERTY_FONTDESCRIPTORPART_NAME: aDefault <<= aFD.Name; break; + case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: aDefault <<= aFD.StyleName; break; + case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: aDefault <<= aFD.Family; break; + case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: aDefault <<= aFD.CharSet; break; + case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: aDefault <<= (float)aFD.Height; break; + case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: aDefault <<= aFD.Weight; break; + case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: aDefault <<= (sal_Int16)aFD.Slant; break; + case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: aDefault <<= aFD.Underline; break; + case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: aDefault <<= aFD.Strikeout; break; + case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: aDefault <<= aFD.Width; break; + case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: aDefault <<= aFD.Pitch; break; + case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: aDefault <<= aFD.CharacterWidth; break; + case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: aDefault <<= aFD.Orientation; break; + case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: aDefault <<= aFD.Kerning; break; + case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: aDefault <<= aFD.WordLineMode; break; + case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: aDefault <<= aFD.Type; break; + default: DBG_ERROR( "FontProperty?!" ); + } + } + else + { + switch ( nPropId ) + { + case BASEPROPERTY_GRAPHIC: + aDefault <<= Reference< graphic::XGraphic >(); + break; + + case BASEPROPERTY_REFERENCE_DEVICE: + aDefault <<= Reference< awt::XDevice >(); + break; + + case BASEPROPERTY_VERTICALALIGN: + case BASEPROPERTY_BORDERCOLOR: + case BASEPROPERTY_SYMBOL_COLOR: + case BASEPROPERTY_TABSTOP: + case BASEPROPERTY_TEXTCOLOR: + case BASEPROPERTY_TEXTLINECOLOR: + case BASEPROPERTY_DATE: + case BASEPROPERTY_DATESHOWCENTURY: + case BASEPROPERTY_TIME: + case BASEPROPERTY_VALUE_DOUBLE: + case BASEPROPERTY_PROGRESSVALUE: + case BASEPROPERTY_SCROLLVALUE: + case BASEPROPERTY_VISIBLESIZE: + case BASEPROPERTY_BACKGROUNDCOLOR: + case BASEPROPERTY_FILLCOLOR: break; // Void + + case BASEPROPERTY_FONTRELIEF: + case BASEPROPERTY_FONTEMPHASISMARK: + case BASEPROPERTY_MAXTEXTLEN: + case BASEPROPERTY_STATE: + case BASEPROPERTY_EXTDATEFORMAT: + case BASEPROPERTY_EXTTIMEFORMAT: + case BASEPROPERTY_ECHOCHAR: aDefault <<= (sal_Int16) 0; break; + case BASEPROPERTY_BORDER: aDefault <<= (sal_Int16) 1; break; + case BASEPROPERTY_DECIMALACCURACY: aDefault <<= (sal_Int16) 2; break; + case BASEPROPERTY_LINECOUNT: aDefault <<= (sal_Int16) 5; break; + case BASEPROPERTY_ALIGN: aDefault <<= (sal_Int16) PROPERTY_ALIGN_LEFT; break; + case BASEPROPERTY_IMAGEALIGN: aDefault <<= (sal_Int16) 1 /*ImageAlign::TOP*/; break; + case BASEPROPERTY_IMAGEPOSITION: aDefault <<= (sal_Int16) 12 /*ImagePosition::Centered*/; break; + case BASEPROPERTY_PUSHBUTTONTYPE: aDefault <<= (sal_Int16) 0 /*PushButtonType::STANDARD*/; break; + case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= (sal_Int16) awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break; + + case BASEPROPERTY_DATEMAX: aDefault <<= (sal_Int32) Date( 31, 12, 2200 ).GetDate(); break; + case BASEPROPERTY_DATEMIN: aDefault <<= (sal_Int32) Date( 1, 1, 1900 ).GetDate(); break; + case BASEPROPERTY_TIMEMAX: aDefault <<= (sal_Int32) Time( 23, 59 ).GetTime(); break; + case BASEPROPERTY_TIMEMIN: aDefault <<= (sal_Int32) 0; break; + case BASEPROPERTY_VALUEMAX_DOUBLE: aDefault <<= (double) 1000000; break; + case BASEPROPERTY_VALUEMIN_DOUBLE: aDefault <<= (double) -1000000; break; + case BASEPROPERTY_VALUESTEP_DOUBLE: aDefault <<= (double ) 1; break; + case BASEPROPERTY_PROGRESSVALUE_MAX: aDefault <<= (sal_Int32) 100; break; + case BASEPROPERTY_PROGRESSVALUE_MIN: aDefault <<= (sal_Int32) 0; break; + case BASEPROPERTY_SCROLLVALUE_MAX: aDefault <<= (sal_Int32) 100; break; + case BASEPROPERTY_SCROLLVALUE_MIN: aDefault <<= (sal_Int32) 0; break; + case BASEPROPERTY_LINEINCREMENT: aDefault <<= (sal_Int32) 1; break; + case BASEPROPERTY_BLOCKINCREMENT: aDefault <<= (sal_Int32) 10; break; + case BASEPROPERTY_ORIENTATION: aDefault <<= (sal_Int32) 0; break; + case BASEPROPERTY_SPINVALUE: aDefault <<= (sal_Int32) 0; break; + case BASEPROPERTY_SPININCREMENT: aDefault <<= (sal_Int32) 1; break; + case BASEPROPERTY_SPINVALUE_MIN: aDefault <<= (sal_Int32) 0; break; + case BASEPROPERTY_SPINVALUE_MAX: aDefault <<= (sal_Int32) 100; break; + case BASEPROPERTY_REPEAT_DELAY: aDefault <<= (sal_Int32) 50; break; // 50 milliseconds + case BASEPROPERTY_DEFAULTCONTROL: aDefault <<= ((UnoControlModel*)this)->getServiceName(); break; + + case BASEPROPERTY_AUTOHSCROLL: + case BASEPROPERTY_AUTOVSCROLL: + case BASEPROPERTY_MOVEABLE: + case BASEPROPERTY_CLOSEABLE: + case BASEPROPERTY_SIZEABLE: + case BASEPROPERTY_HSCROLL: + case BASEPROPERTY_DEFAULTBUTTON: + case BASEPROPERTY_MULTILINE: + case BASEPROPERTY_MULTISELECTION: + case BASEPROPERTY_TRISTATE: + case BASEPROPERTY_DROPDOWN: + case BASEPROPERTY_SPIN: + case BASEPROPERTY_READONLY: + case BASEPROPERTY_VSCROLL: + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + case BASEPROPERTY_STRICTFORMAT: + case BASEPROPERTY_REPEAT: + case BASEPROPERTY_PAINTTRANSPARENT: + case BASEPROPERTY_DESKTOP_AS_PARENT: + case BASEPROPERTY_HARDLINEBREAKS: + case BASEPROPERTY_NOLABEL: aDefault <<= (sal_Bool) sal_False; break; + + case BASEPROPERTY_HIDEINACTIVESELECTION: + case BASEPROPERTY_ENFORCE_FORMAT: + case BASEPROPERTY_AUTOCOMPLETE: + case BASEPROPERTY_SCALEIMAGE: + case BASEPROPERTY_ENABLED: + case BASEPROPERTY_PRINTABLE: + case BASEPROPERTY_ENABLEVISIBLE: + case BASEPROPERTY_DECORATION: aDefault <<= (sal_Bool) sal_True; break; + + case BASEPROPERTY_HELPTEXT: + case BASEPROPERTY_HELPURL: + case BASEPROPERTY_IMAGEURL: + case BASEPROPERTY_DIALOGSOURCEURL: + case BASEPROPERTY_EDITMASK: + case BASEPROPERTY_LITERALMASK: + case BASEPROPERTY_LABEL: + case BASEPROPERTY_TITLE: + case BASEPROPERTY_TEXT: aDefault <<= ::rtl::OUString(); break; + + case BASEPROPERTY_WRITING_MODE: + case BASEPROPERTY_CONTEXT_WRITING_MODE: + aDefault <<= text::WritingMode2::CONTEXT; + break; + + case BASEPROPERTY_STRINGITEMLIST: + { + ::com::sun::star::uno::Sequence< ::rtl::OUString> aStringSeq; + aDefault <<= aStringSeq; + + } + break; + case BASEPROPERTY_SELECTEDITEMS: + { + ::com::sun::star::uno::Sequence<sal_Int16> aINT16Seq; + aDefault <<= aINT16Seq; + } + break; + case BASEPROPERTY_CURRENCYSYMBOL: + { + Any aDefaultCurrency = ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::DEFAULTCURRENCY); + DBG_ASSERT( TypeClass_STRING == aDefaultCurrency.getValueTypeClass(), "UnoControlModel::ImplGetDefaultValue: invalid currency config value!" ); + + ::rtl::OUString sDefaultCurrency; + aDefaultCurrency >>= sDefaultCurrency; + + // extract the bank symbol + sal_Int32 nSepPos = sDefaultCurrency.indexOf( '-' ); + ::rtl::OUString sBankSymbol; + if ( nSepPos >= 0 ) + { + sBankSymbol = sDefaultCurrency.copy( 0, nSepPos ); + sDefaultCurrency = sDefaultCurrency.copy( nSepPos + 1 ); + } + + // the remaming is the locale + Locale aLocale; + nSepPos = sDefaultCurrency.indexOf( '-' ); + if ( nSepPos >= 0 ) + { + aLocale.Language = sDefaultCurrency.copy( 0, nSepPos ); + aLocale.Country = sDefaultCurrency.copy( nSepPos + 1 ); + } + + LocaleDataWrapper aLocaleInfo( ::comphelper::getProcessServiceFactory(), aLocale ); + if ( !sBankSymbol.getLength() ) + sBankSymbol = aLocaleInfo.getCurrBankSymbol(); + + // look for the currency entry (for this language) which has the given bank symbol + Sequence< Currency2 > aAllCurrencies = aLocaleInfo.getAllCurrencies(); + const Currency2* pAllCurrencies = aAllCurrencies.getConstArray(); + const Currency2* pAllCurrenciesEnd = pAllCurrencies + aAllCurrencies.getLength(); + + ::rtl::OUString sCurrencySymbol = aLocaleInfo.getCurrSymbol(); + if ( !sBankSymbol.getLength() ) + { + DBG_ASSERT( pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: no currencies at all!" ); + if ( pAllCurrencies != pAllCurrenciesEnd ) + { + sBankSymbol = pAllCurrencies->BankSymbol; + sCurrencySymbol = pAllCurrencies->Symbol; + } + } + + if ( sBankSymbol.getLength() ) + { + bool bLegacy = false; + for ( ;pAllCurrencies != pAllCurrenciesEnd; ++pAllCurrencies ) + if ( pAllCurrencies->BankSymbol == sBankSymbol ) + { + sCurrencySymbol = pAllCurrencies->Symbol; + if ( pAllCurrencies->LegacyOnly ) + bLegacy = true; + else + break; + } + DBG_ASSERT( bLegacy || pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: did not find the given bank symbol!" ); + } + + aDefault <<= sCurrencySymbol; + } + break; + + default: DBG_ERROR( "ImplGetDefaultValue - unknown Property" ); + } + } + + return aDefault; +} + +void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId, const ::com::sun::star::uno::Any& rDefault ) +{ + ImplControlProperty* pProp = new ImplControlProperty( nPropId, rDefault ); + mpData->Insert( nPropId, pProp ); +} + +void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId ) +{ + ImplRegisterProperty( nPropId, ImplGetDefaultValue( nPropId ) ); + + if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR ) + { + // some properties are not included in the FontDescriptor, but everytime + // when we have a FontDescriptor we want to have these properties too. + // => Easier to register the here, istead everywhere where I register the FontDescriptor... + + ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR ); + ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR ); + ImplRegisterProperty( BASEPROPERTY_FONTRELIEF ); + ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK ); + } +} + +void UnoControlModel::ImplRegisterProperties( const std::list< sal_uInt16 > &rIds ) +{ + std::list< sal_uInt16 >::const_iterator iter; + for( iter = rIds.begin(); iter != rIds.end(); iter++) { + if( !ImplHasProperty( *iter ) ) + ImplRegisterProperty( *iter, ImplGetDefaultValue( *iter ) ); + } +} + +// ::com::sun::star::uno::XInterface +::com::sun::star::uno::Any UnoControlModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XControlModel*, this ), + SAL_STATIC_CAST( ::com::sun::star::io::XPersistObject*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XComponent*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XServiceInfo*, this ), + SAL_STATIC_CAST( ::com::sun::star::util::XCloneable*, this ), + SAL_STATIC_CAST( ::com::sun::star::beans::XPropertyState*, this ), + SAL_STATIC_CAST( ::com::sun::star::beans::XMultiPropertySet*, this ), + SAL_STATIC_CAST( ::com::sun::star::beans::XFastPropertySet*, this ), + SAL_STATIC_CAST( ::com::sun::star::beans::XPropertySet*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XUnoTunnel*, this ) ); + return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType )); +} + +// ::com::sun::star::lang::XUnoTunnel +IMPL_XUNOTUNNEL( UnoControlModel ) + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoControlModel ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>* ) NULL ) +IMPL_XTYPEPROVIDER_END + + +uno::Reference< util::XCloneable > UnoControlModel::createClone() throw(::com::sun::star::uno::RuntimeException) +{ + UnoControlModel* pClone = Clone(); + uno::Reference< util::XCloneable > xClone( (::cppu::OWeakObject*) pClone, uno::UNO_QUERY ); + return xClone; +} + +// ::com::sun::star::lang::XComponent +void UnoControlModel::dispose( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::lang::EventObject aEvt; + aEvt.Source = (::com::sun::star::uno::XAggregation*)(::cppu::OWeakAggObject*)this; + maDisposeListeners.disposeAndClear( aEvt ); + + // let the property set helper notify our property listeners + OPropertySetHelper::disposing(); +} + +void UnoControlModel::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + maDisposeListeners.addInterface( rxListener ); +} + +void UnoControlModel::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + maDisposeListeners.removeInterface( rxListener ); +} + + +// ::com::sun::star::beans::XPropertyState +::com::sun::star::beans::PropertyState UnoControlModel::getPropertyState( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_uInt16 nPropId = GetPropertyId( PropertyName ); + + ::com::sun::star::uno::Any aValue = getPropertyValue( PropertyName ); + ::com::sun::star::uno::Any aDefault = ImplGetDefaultValue( nPropId ); + + return CompareProperties( aValue, aDefault ) ? ::com::sun::star::beans::PropertyState_DEFAULT_VALUE : ::com::sun::star::beans::PropertyState_DIRECT_VALUE; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > UnoControlModel::getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_uInt32 nNames = PropertyNames.getLength(); + const ::rtl::OUString* pNames = PropertyNames.getConstArray(); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > aStates( nNames ); + ::com::sun::star::beans::PropertyState* pStates = aStates.getArray(); + + for ( sal_uInt32 n = 0; n < nNames; n++ ) + pStates[n] = getPropertyState( pNames[n] ); + + return aStates; +} + +void UnoControlModel::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + Any aDefaultValue; + { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) ); + } + setPropertyValue( PropertyName, aDefaultValue ); +} + +::com::sun::star::uno::Any UnoControlModel::getPropertyDefault( const ::rtl::OUString& rPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + return ImplGetDefaultValue( GetPropertyId( rPropertyName ) ); +} + + +// ::com::sun::star::io::XPersistObjec +::rtl::OUString UnoControlModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + DBG_ERROR( "ServiceName von UnoControlModel ?!" ); + return ::rtl::OUString(); +} + +void UnoControlModel::write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY ); + DBG_ASSERT( xMark.is(), "write: no ::com::sun::star::io::XMarkableStream!" ); + + OutStream->writeShort( UNOCONTROL_STREAMVERSION ); + + ImplPropertyTable aProps; + sal_uInt32 i; + for ( i = mpData->Count(); i; ) + { + ImplControlProperty* pProp = mpData->GetObject( --i ); + if ( ( ( GetPropertyAttribs( pProp->GetId() ) & ::com::sun::star::beans::PropertyAttribute::TRANSIENT ) == 0 ) + && ( getPropertyState( GetPropertyName( pProp->GetId() ) ) != ::com::sun::star::beans::PropertyState_DEFAULT_VALUE ) ) + { + aProps.Insert( pProp->GetId(), pProp ); + } + } + + sal_uInt32 nProps = aProps.Count(); + + // FontProperty wegen fehlender Unterscheidung zwischen 5.0 / 5.1 + // immer im alten Format mitspeichern. + OutStream->writeLong( (long) aProps.IsKeyValid( BASEPROPERTY_FONTDESCRIPTOR ) ? ( nProps + 3 ) : nProps ); + for ( i = 0; i < nProps; i++ ) + { + sal_Int32 nPropDataBeginMark = xMark->createMark(); + OutStream->writeLong( 0L ); // DataLen + + ImplControlProperty* pProp = aProps.GetObject( i ); + OutStream->writeShort( pProp->GetId() ); + + sal_Bool bVoid = pProp->GetValue().getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID; + + OutStream->writeBoolean( bVoid ); + + if ( !bVoid ) + { + const ::com::sun::star::uno::Any& rValue = pProp->GetValue(); + const ::com::sun::star::uno::Type& rType = rValue.getValueType(); + + if ( rType == ::getBooleanCppuType() ) + { + sal_Bool b = false; + rValue >>= b; + OutStream->writeBoolean( b ); + } + else if ( rType == ::getCppuType((const ::rtl::OUString*)0) ) + { + ::rtl::OUString aUString; + rValue >>= aUString; + OutStream->writeUTF( aUString ); + } + else if ( rType == ::getCppuType((const sal_uInt16*)0) ) + { + sal_uInt16 n = 0; + rValue >>= n; + OutStream->writeShort( n ); + } + else if ( rType == ::getCppuType((const sal_Int16*)0) ) + { + sal_Int16 n = 0; + rValue >>= n; + OutStream->writeShort( n ); + } + else if ( rType == ::getCppuType((const sal_uInt32*)0) ) + { + sal_uInt32 n = 0; + rValue >>= n; + OutStream->writeLong( n ); + } + else if ( rType == ::getCppuType((const sal_Int32*)0) ) + { + sal_Int32 n = 0; + rValue >>= n; + OutStream->writeLong( n ); + } + else if ( rType == ::getCppuType((const double*)0) ) + { + double n = 0; + rValue >>= n; + OutStream->writeDouble( n ); + } + else if ( rType == ::getCppuType((const ::com::sun::star::awt::FontDescriptor*)0) ) + { + ::com::sun::star::awt::FontDescriptor aFD; + rValue >>= aFD; + OutStream->writeUTF( aFD.Name ); + OutStream->writeShort( aFD.Height ); + OutStream->writeShort( aFD.Width ); + OutStream->writeUTF( aFD.StyleName ); + OutStream->writeShort( aFD.Family ); + OutStream->writeShort( aFD.CharSet ); + OutStream->writeShort( aFD.Pitch ); + OutStream->writeDouble( aFD.CharacterWidth ); + OutStream->writeDouble( aFD.Weight ); + OutStream->writeShort( + sal::static_int_cast< sal_Int16 >(aFD.Slant) ); + OutStream->writeShort( aFD.Underline ); + OutStream->writeShort( aFD.Strikeout ); + OutStream->writeDouble( aFD.Orientation ); + OutStream->writeBoolean( aFD.Kerning ); + OutStream->writeBoolean( aFD.WordLineMode ); + OutStream->writeShort( aFD.Type ); + } + else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence< ::rtl::OUString>*)0 ) ) + { + ::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq; + rValue >>= aSeq; + long nEntries = aSeq.getLength(); + OutStream->writeLong( nEntries ); + for ( long n = 0; n < nEntries; n++ ) + OutStream->writeUTF( aSeq.getConstArray()[n] ); + } + else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_uInt16>*)0 ) ) + { + ::com::sun::star::uno::Sequence<sal_uInt16> aSeq; + rValue >>= aSeq; + long nEntries = aSeq.getLength(); + OutStream->writeLong( nEntries ); + for ( long n = 0; n < nEntries; n++ ) + OutStream->writeShort( aSeq.getConstArray()[n] ); + } + else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_Int16>*)0 ) ) + { + ::com::sun::star::uno::Sequence<sal_Int16> aSeq; + rValue >>= aSeq; + long nEntries = aSeq.getLength(); + OutStream->writeLong( nEntries ); + for ( long n = 0; n < nEntries; n++ ) + OutStream->writeShort( aSeq.getConstArray()[n] ); + } + else if ( rType.getTypeClass() == TypeClass_ENUM ) + { + sal_Int32 nAsInt = 0; + ::cppu::enum2int( nAsInt, rValue ); + OutStream->writeLong( nAsInt ); + } +#if OSL_DEBUG_LEVEL > 0 + else + { + ::rtl::OString sMessage( "UnoControlModel::write: don't know how to handle a property of type '" ); + ::rtl::OUString sTypeName( rType.getTypeName() ); + sMessage += ::rtl::OString( sTypeName.getStr(), sTypeName.getLength(), RTL_TEXTENCODING_ASCII_US ); + sMessage += "'.\n(Currently handling property '"; + ::rtl::OUString sPropertyName( GetPropertyName( pProp->GetId() ) ); + sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), osl_getThreadTextEncoding() ); + sMessage += "'.)"; + DBG_ERROR( sMessage ); + } +#endif + } + + sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark ); + xMark->jumpToMark( nPropDataBeginMark ); + OutStream->writeLong( nPropDataLen ); + xMark->jumpToFurthest(); + xMark->deleteMark(nPropDataBeginMark); + } + + ImplControlProperty* pProp = aProps.Get( BASEPROPERTY_FONTDESCRIPTOR ); + if ( pProp ) + { + // Solange wir keinen 5.0-Export haben, muss das alte + // Format mit rausgeschrieben werden... + ::com::sun::star::awt::FontDescriptor aFD; + pProp->GetValue() >>= aFD; + + for ( sal_uInt16 n = BASEPROPERTY_FONT_TYPE; n <= BASEPROPERTY_FONT_ATTRIBS; n++ ) + { + sal_Int32 nPropDataBeginMark = xMark->createMark(); + OutStream->writeLong( 0L ); // DataLen + OutStream->writeShort( n ); // PropId + OutStream->writeBoolean( sal_False ); // Void + + if ( n == BASEPROPERTY_FONT_TYPE ) + { + OutStream->writeUTF( aFD.Name ); + OutStream->writeUTF( aFD.StyleName ); + OutStream->writeShort( aFD.Family ); + OutStream->writeShort( aFD.CharSet ); + OutStream->writeShort( aFD.Pitch ); + } + else if ( n == BASEPROPERTY_FONT_SIZE ) + { + OutStream->writeLong( aFD.Width ); + OutStream->writeLong( aFD.Height ); + OutStream->writeShort( + sal::static_int_cast< sal_Int16 >( + VCLUnoHelper::ConvertFontWidth( aFD.CharacterWidth )) ); + } + else if ( n == BASEPROPERTY_FONT_ATTRIBS ) + { + OutStream->writeShort( + sal::static_int_cast< sal_Int16 >( + VCLUnoHelper::ConvertFontWeight( aFD.Weight )) ); + OutStream->writeShort( + sal::static_int_cast< sal_Int16 >(aFD.Slant) ); + OutStream->writeShort( aFD.Underline ); + OutStream->writeShort( aFD.Strikeout ); + OutStream->writeShort( (short)(aFD.Orientation * 10) ); + OutStream->writeBoolean( aFD.Kerning ); + OutStream->writeBoolean( aFD.WordLineMode ); + } + else + { + DBG_ERROR( "Property?!" ); + } + + sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark ); + xMark->jumpToMark( nPropDataBeginMark ); + OutStream->writeLong( nPropDataLen ); + xMark->jumpToFurthest(); + xMark->deleteMark(nPropDataBeginMark); + } + } +} + +void UnoControlModel::read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( InStream, ::com::sun::star::uno::UNO_QUERY ); + DBG_ASSERT( xMark.is(), "read: no ::com::sun::star::io::XMarkableStream!" ); + + short nVersion = InStream->readShort(); + sal_uInt32 nProps = (sal_uInt32)InStream->readLong(); + ::com::sun::star::uno::Sequence< ::rtl::OUString> aProps( nProps ); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> aValues( nProps ); + sal_Bool bInvalidEntries = sal_False; + + // Dummerweise kein Mark fuer den gesamten Block, es koennen also + // nur Properties geaendert werden, es koennen aber nicht spaeter mal Daten + // fuer das Model hinter den Properties geschrieben werden. + + // Fuer den Import der alten ::com::sun::star::awt::FontDescriptor-Teile + ::com::sun::star::awt::FontDescriptor* pFD = NULL; + + sal_uInt32 i; + for ( i = 0; i < nProps; i++ ) + { + sal_Int32 nPropDataBeginMark = xMark->createMark(); + sal_Int32 nPropDataLen = InStream->readLong(); + + sal_uInt16 nPropId = (sal_uInt16)InStream->readShort(); + + ::com::sun::star::uno::Any aValue; + sal_Bool bIsVoid = InStream->readBoolean(); + if ( !bIsVoid ) + { + const ::com::sun::star::uno::Type* pType = mpData->Get( nPropId ) ? GetPropertyType( nPropId ) : NULL; + if ( pType ) + { + if ( *pType == ::getBooleanCppuType() ) + { + sal_Bool b = InStream->readBoolean(); + aValue <<= b; + } + else if ( *pType == ::getCppuType((const ::rtl::OUString*)0) ) + { + ::rtl::OUString aUTF = InStream->readUTF(); + aValue <<= aUTF; + } + else if ( *pType == ::getCppuType((const sal_uInt16*)0) ) + { + sal_uInt16 n = InStream->readShort(); + aValue <<= n; + } + else if ( *pType == ::getCppuType((const sal_Int16*)0) ) + { + sal_Int16 n = InStream->readShort(); + aValue <<= n; + } + else if ( *pType == ::getCppuType((const sal_uInt32*)0) ) + { + sal_uInt32 n = InStream->readLong(); + aValue <<= n; + } + else if ( *pType == ::getCppuType((const sal_Int32*)0) ) + { + sal_Int32 n = InStream->readLong(); + aValue <<= n; + } + else if ( *pType == ::getCppuType((const double*)0) ) + { + double n = InStream->readDouble(); + aValue <<= n; + } + else if ( *pType == ::getCppuType((const ::com::sun::star::awt::FontDescriptor*)0) ) + { + ::com::sun::star::awt::FontDescriptor aFD; + aFD.Name = InStream->readUTF(); + aFD.Height = InStream->readShort(); + aFD.Width = InStream->readShort(); + aFD.StyleName = InStream->readUTF(); + aFD.Family = InStream->readShort(); + aFD.CharSet = InStream->readShort(); + aFD.Pitch = InStream->readShort(); + aFD.CharacterWidth = (float)InStream->readDouble(); + aFD.Weight = (float)InStream->readDouble(); + aFD.Slant = (::com::sun::star::awt::FontSlant)InStream->readShort(); + aFD.Underline = InStream->readShort(); + aFD.Strikeout = InStream->readShort(); + aFD.Orientation = (float)InStream->readDouble(); + aFD.Kerning = InStream->readBoolean(); + aFD.WordLineMode = InStream->readBoolean(); + aFD.Type = InStream->readShort(); + aValue <<= aFD; + } + else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence< ::rtl::OUString>*)0 ) ) + { + long nEntries = InStream->readLong(); + ::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq( nEntries ); + for ( long n = 0; n < nEntries; n++ ) + aSeq.getArray()[n] = InStream->readUTF(); + aValue <<= aSeq; + + } + else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_uInt16>*)0 ) ) + + { + long nEntries = InStream->readLong(); + ::com::sun::star::uno::Sequence<sal_uInt16> aSeq( nEntries ); + for ( long n = 0; n < nEntries; n++ ) + aSeq.getArray()[n] = (sal_uInt16)InStream->readShort(); + aValue <<= aSeq; + } + else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_Int16>*)0 ) ) + { + long nEntries = InStream->readLong(); + ::com::sun::star::uno::Sequence<sal_Int16> aSeq( nEntries ); + for ( long n = 0; n < nEntries; n++ ) + aSeq.getArray()[n] = (sal_Int16)InStream->readShort(); + aValue <<= aSeq; + } + else if ( pType->getTypeClass() == TypeClass_ENUM ) + { + sal_Int32 nAsInt = InStream->readLong(); + aValue = ::cppu::int2enum( nAsInt, *pType ); + } + else + { + ::rtl::OString sMessage( "UnoControlModel::read: don't know how to handle a property of type '" ); + ::rtl::OUString sTypeName( pType->getTypeName() ); + sMessage += ::rtl::OString( sTypeName.getStr(), sTypeName.getLength(), RTL_TEXTENCODING_ASCII_US ); + sMessage += "'.\n(Currently handling property '"; + ::rtl::OUString sPropertyName( GetPropertyName( nPropId ) ); + sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), osl_getThreadTextEncoding() ); + sMessage += "'.)"; + DBG_ERROR( sMessage ); + } + } + else + { + // Altes Geraffel aus 5.0 + if ( nPropId == BASEPROPERTY_FONT_TYPE ) + { + // Sonst ist es nur die redundante Info fuer alte Versionen + // Daten werden durch MarkableStream geskippt. + if ( nVersion < 2 ) + { + if ( !pFD ) + { + pFD = new ::com::sun::star::awt::FontDescriptor; + ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR ); + if ( pProp ) // wegen den Defaults... + pProp->GetValue() >>= *pFD; + } + pFD->Name = InStream->readUTF(); + pFD->StyleName = InStream->readUTF(); + pFD->Family = InStream->readShort(); + pFD->CharSet = InStream->readShort(); + pFD->Pitch = InStream->readShort(); + } + } + else if ( nPropId == BASEPROPERTY_FONT_SIZE ) + { + if ( nVersion < 2 ) + { + if ( !pFD ) + { + pFD = new ::com::sun::star::awt::FontDescriptor; + ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR ); + if ( pProp ) // wegen den Defaults... + pProp->GetValue() >>= *pFD; + } + pFD->Width = (sal_Int16)InStream->readLong(); + pFD->Height = (sal_Int16)InStream->readLong(); + InStream->readShort(); // ::com::sun::star::awt::FontWidth ignorieren - wurde mal falsch geschrieben und wird nicht gebraucht. + pFD->CharacterWidth = ::com::sun::star::awt::FontWidth::DONTKNOW; + } + } + else if ( nPropId == BASEPROPERTY_FONT_ATTRIBS ) + { + if ( nVersion < 2 ) + { + if ( !pFD ) + { + pFD = new ::com::sun::star::awt::FontDescriptor; + ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR ); + if ( pProp ) // wegen den Defaults... + pProp->GetValue() >>= *pFD; + } + pFD->Weight = VCLUnoHelper::ConvertFontWeight( (FontWeight) InStream->readShort() ); + pFD->Slant = (::com::sun::star::awt::FontSlant)InStream->readShort(); + pFD->Underline = InStream->readShort(); + pFD->Strikeout = InStream->readShort(); + pFD->Orientation = ( (float)(double)InStream->readShort() ) / 10; + pFD->Kerning = InStream->readBoolean(); + pFD->WordLineMode = InStream->readBoolean(); + } + } + else + { + DBG_ERROR( "read: unknown Property!" ); + } + } + } + else // bVoid + { + if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR ) + { + EmptyFontDescriptor aFD; + aValue <<= aFD; + } + } + + if ( mpData->Get( nPropId ) ) + { + aProps.getArray()[i] = GetPropertyName( nPropId ); + aValues.getArray()[i] = aValue; + } + else + { + bInvalidEntries = sal_True; + } + + // Falls bereits mehr drinsteht als diese Version kennt: + xMark->jumpToMark( nPropDataBeginMark ); + InStream->skipBytes( nPropDataLen ); + xMark->deleteMark(nPropDataBeginMark); + } + if ( bInvalidEntries ) + { + for ( i = 0; i < (sal_uInt32)aProps.getLength(); i++ ) + { + if ( !aProps.getConstArray()[i].getLength() ) + { + ::comphelper::removeElementAt( aProps, i ); + ::comphelper::removeElementAt( aValues, i ); + i--; + } + } + } + + try + { + setPropertyValues( aProps, aValues ); + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if ( pFD ) + { + ::com::sun::star::uno::Any aValue; + aValue <<= *pFD; + setPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ), aValue ); + delete pFD; + } +} + + +// ::com::sun::star::lang::XServiceInfo +::rtl::OUString UnoControlModel::getImplementationName( ) throw(::com::sun::star::uno::RuntimeException) +{ + DBG_ERROR( "This method should be overloaded!" ); + return ::rtl::OUString(); + +} + +sal_Bool UnoControlModel::supportsService( const ::rtl::OUString& rServiceName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); + const ::rtl::OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == rServiceName ) + return sal_True; + return sal_False; +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > UnoControlModel::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlModel" ) ); + return Sequence< ::rtl::OUString >( &sName, 1 ); +} + +// ::cppu::OPropertySetHelper +::cppu::IPropertyArrayHelper& UnoControlModel::getInfoHelper() +{ + DBG_ERROR( "UnoControlModel::getInfoHelper() not possible!" ); + return *(::cppu::IPropertyArrayHelper*) NULL; +} + +// ------------------------------------------------------------------ +template <class TYPE> +sal_Bool convertType(Any& _rConvertedValue, const Any& _rNewValueTest, const TYPE* /* _pTypeDisambiguation */) +{ + TYPE tValue; + if (_rNewValueTest >>= tValue) + { + _rConvertedValue <<= tValue; + return sal_True; + } +} + +// .................................................................. +sal_Bool UnoControlModel::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue ) throw (IllegalArgumentException) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + sal_Bool bVoid = rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID; + if ( bVoid ) + { + rConvertedValue.clear(); + } + else + { + const ::com::sun::star::uno::Type* pDestType = GetPropertyType( (sal_uInt16)nPropId ); + if ( pDestType->getTypeClass() == TypeClass_ANY ) + { + rConvertedValue = rValue; + } + else + { + if ( pDestType->equals( rValue.getValueType() ) ) + { + rConvertedValue = rValue; + } + else + { + BOOL bConverted = FALSE; + // 13.03.2001 - 84923 - frank.schoenheit@germany.sun.com + + switch (pDestType->getTypeClass()) + { + case TypeClass_DOUBLE: + { + // try as double + double nAsDouble = 0; + bConverted = ( rValue >>= nAsDouble ); + if ( bConverted ) + rConvertedValue <<= nAsDouble; + else + { // try as integer - 96136 - 2002-10-08 - fs@openoffice.org + sal_Int32 nAsInteger = 0; + bConverted = ( rValue >>= nAsInteger ); + if ( bConverted ) + rConvertedValue <<= (double)nAsInteger; + } + } + break; + case TypeClass_SHORT: + { + sal_Int16 n; + bConverted = ( rValue >>= n ); + if ( bConverted ) + rConvertedValue <<= n; + } + break; + case TypeClass_UNSIGNED_SHORT: + { + sal_uInt16 n; + bConverted = ( rValue >>= n ); + if ( bConverted ) + rConvertedValue <<= n; + } + break; + case TypeClass_LONG: + { + sal_Int32 n; + bConverted = ( rValue >>= n ); + if ( bConverted ) + rConvertedValue <<= n; + } + break; + case TypeClass_UNSIGNED_LONG: + { + sal_uInt32 n; + bConverted = ( rValue >>= n ); + if ( bConverted ) + rConvertedValue <<= n; + } + break; + case TypeClass_INTERFACE: + { + if ( rValue.getValueType().getTypeClass() == TypeClass_INTERFACE ) + { + Reference< XInterface > xPure( rValue, UNO_QUERY ); + if ( xPure.is() ) + rConvertedValue = xPure->queryInterface( *pDestType ); + else + rConvertedValue.setValue( NULL, *pDestType ); + bConverted = sal_True; + } + } + break; + case TypeClass_ENUM: + { + sal_Int32 nValue = 0; + bConverted = ( rValue >>= nValue ); + if ( bConverted ) + rConvertedValue = ::cppu::int2enum( nValue, *pDestType ); + } + break; + default: ; // avoid compiler warning + } + + if (!bConverted) + { + ::rtl::OUStringBuffer aErrorMessage; + aErrorMessage.appendAscii( "Unable to convert the given value for the property " ); + aErrorMessage.append ( GetPropertyName( (sal_uInt16)nPropId ) ); + aErrorMessage.appendAscii( ".\n" ); + aErrorMessage.appendAscii( "Expected type: " ); + aErrorMessage.append ( pDestType->getTypeName() ); + aErrorMessage.appendAscii( "\n" ); + aErrorMessage.appendAscii( "Found type: " ); + aErrorMessage.append ( rValue.getValueType().getTypeName() ); + throw ::com::sun::star::lang::IllegalArgumentException( + aErrorMessage.makeStringAndClear(), + static_cast< ::com::sun::star::beans::XPropertySet* >(this), + 1); + } + } + } + } + + // the current value + getFastPropertyValue( rOldValue, nPropId ); + return !CompareProperties( rConvertedValue, rOldValue ); +} + +void UnoControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception) +{ + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + + // Fehlt: Die gefakten Einzelproperties des FontDescriptors... + + ImplControlProperty* pProp = mpData->Get( nPropId ); + if ( pProp ) + { + DBG_ASSERT( ( rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID ) || ( GetPropertyAttribs( (sal_uInt16)nPropId ) & ::com::sun::star::beans::PropertyAttribute::MAYBEVOID ), "Property darf nicht VOID sein!" ); + ImplPropertyChanged( (sal_uInt16)nPropId ); + pProp->SetValue( rValue ); + } + else + { + // exception... + DBG_ERROR( "SetPropertyValues: Invalid Property!" ); + } +} + +void UnoControlModel::getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nPropId ) const +{ + ::osl::Guard< ::osl::Mutex > aGuard( ((UnoControlModel*)this)->GetMutex() ); + + ImplControlProperty* pProp = mpData->Get( nPropId ); + + if ( pProp ) + rValue = pProp->GetValue(); + else if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) ) + { + pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR ); + ::com::sun::star::awt::FontDescriptor aFD; + pProp->GetValue() >>= aFD; + switch ( nPropId ) + { + case BASEPROPERTY_FONTDESCRIPTORPART_NAME: rValue <<= aFD.Name; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: rValue <<= aFD.StyleName; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: rValue <<= aFD.Family; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: rValue <<= aFD.CharSet; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: rValue <<= (float)aFD.Height; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: rValue <<= aFD.Weight; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: rValue <<= (sal_Int16)aFD.Slant; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: rValue <<= aFD.Underline; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: rValue <<= aFD.Strikeout; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: rValue <<= aFD.Width; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: rValue <<= aFD.Pitch; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: rValue <<= aFD.CharacterWidth; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: rValue <<= aFD.Orientation; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: rValue <<= aFD.Kerning; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: rValue <<= aFD.WordLineMode; + break; + case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: rValue <<= aFD.Type; + break; + default: DBG_ERROR( "FontProperty?!" ); + } + } + else + { + DBG_ERROR( "getFastPropertyValue - invalid Property!" ); + } +} + +// ::com::sun::star::beans::XPropertySet +void UnoControlModel::setPropertyValue( const ::rtl::OUString& rPropertyName, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nPropId = 0; + { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + nPropId = (sal_Int32) GetPropertyId( rPropertyName ); + DBG_ASSERT( nPropId, "Invalid ID in UnoControlModel::setPropertyValue" ); + } + if( nPropId ) + setFastPropertyValue( nPropId, rValue ); + else + throw ::com::sun::star::beans::UnknownPropertyException(); +} + +// ::com::sun::star::beans::XFastPropertySet +void UnoControlModel::setFastPropertyValue( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) ) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + + Any aOldSingleValue; + getFastPropertyValue( aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START ); + + ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR ); + FontDescriptor aOldFontDescriptor; + pProp->GetValue() >>= aOldFontDescriptor; + + FontDescriptor aNewFontDescriptor( aOldFontDescriptor ); + lcl_ImplMergeFontProperty( aNewFontDescriptor, (sal_uInt16)nPropId, rValue ); + + Any aNewValue; + aNewValue <<= aNewFontDescriptor; + sal_Int32 nDescriptorId( BASEPROPERTY_FONTDESCRIPTOR ); + nDescriptorId = BASEPROPERTY_FONTDESCRIPTOR; + + // also, we need fire a propertyChange event for the single property, since with + // the above line, only an event for the FontDescriptor property will be fired + Any aNewSingleValue; + getFastPropertyValue( aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START ); + + aGuard.clear(); + setFastPropertyValues( 1, &nDescriptorId, &aNewValue, 1 ); + fire( &nPropId, &aNewSingleValue, &aOldSingleValue, 1, sal_False ); + } + else + setFastPropertyValues( 1, &nPropId, &rValue, 1 ); +} + +// ::com::sun::star::beans::XMultiPropertySet +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > UnoControlModel::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException) +{ + DBG_ERROR( "UnoControlModel::getPropertySetInfo() not possible!" ); + return ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >(); +} + +void UnoControlModel::setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values ) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + + sal_Int32 nProps = rPropertyNames.getLength(); + +// sal_Int32* pHandles = new sal_Int32[nProps]; + // don't do this - it leaks in case of an exception + Sequence< sal_Int32 > aHandles( nProps ); + sal_Int32* pHandles = aHandles.getArray(); + + // may need to change the order in the sequence, for this we need a non-const value sequence + // 15.05.2002 - 99314 - fs@openoffice.org + uno::Sequence< uno::Any > aValues( Values ); + uno::Any* pValues = aValues.getArray(); + + sal_Int32 nValidHandles = getInfoHelper().fillHandles( pHandles, rPropertyNames ); + + if ( nValidHandles ) + { + // if somebody sets properties which are single aspects of a font descriptor, + // remove them, and build a font descriptor instead + ::std::auto_ptr< awt::FontDescriptor > pFD; + for ( sal_uInt16 n = 0; n < nProps; ++n ) + { + if ( ( pHandles[n] >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( pHandles[n] <= BASEPROPERTY_FONTDESCRIPTORPART_END ) ) + { + if ( !pFD.get() ) + { + ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR ); + pFD.reset( new awt::FontDescriptor ); + pProp->GetValue() >>= *pFD; + } + lcl_ImplMergeFontProperty( *pFD, (sal_uInt16)pHandles[n], pValues[n] ); + pHandles[n] = -1; + nValidHandles--; + } + } + + if ( nValidHandles ) + { + ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles ); + aGuard.clear(); + // clear our guard before calling into setFastPropertyValues - this method + // will implicitly call property listeners, and this should not happen with + // our mutex locked + // #i23451# - 2004-03-18 - fs@openoffice.org + setFastPropertyValues( nProps, pHandles, pValues, nValidHandles ); + } + else + aGuard.clear(); + // same as a few lines above + + // FD-Propertie nicht in das Array mergen, weil sortiert... + if ( pFD.get() ) + { + ::com::sun::star::uno::Any aValue; + aValue <<= *pFD; + sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR; + setFastPropertyValues( 1, &nHandle, &aValue, 1 ); + } + } +} + + + +void UnoControlModel::ImplNormalizePropertySequence( const sal_Int32, sal_Int32*, + uno::Any*, sal_Int32* ) const SAL_THROW(()) +{ + // nothing to do here +} + +void UnoControlModel::ImplEnsureHandleOrder( const sal_Int32 _nCount, sal_Int32* _pHandles, + uno::Any* _pValues, sal_Int32 _nFirstHandle, sal_Int32 _nSecondHandle ) const +{ + for ( sal_Int32 i=0; i < _nCount; ++_pHandles, ++_pValues, ++i ) + { + if ( _nSecondHandle == *_pHandles ) + { + sal_Int32* pLaterHandles = _pHandles + 1; + uno::Any* pLaterValues = _pValues + 1; + for ( sal_Int32 j = i + 1; j < _nCount; ++j, ++pLaterHandles, ++pLaterValues ) + { + if ( _nFirstHandle == *pLaterHandles ) + { + // indeed it is -> exchange the both places in the sequences + sal_Int32 nHandle( *_pHandles ); + *_pHandles = *pLaterHandles; + *pLaterHandles = nHandle; + + uno::Any aValue( *_pValues ); + *_pValues = *pLaterValues; + *pLaterValues = aValue; + + break; + // this will leave the inner loop, and continue with the outer loop. + // Note that this means we will encounter the _nSecondHandle handle, again, once we reached + // (in the outer loop) the place where we just put it. + } + } + } + } +} diff --git a/toolkit/source/controls/unocontrols.cxx b/toolkit/source/controls/unocontrols.cxx new file mode 100644 index 000000000000..3abacef7b67f --- /dev/null +++ b/toolkit/source/controls/unocontrols.cxx @@ -0,0 +1,3789 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unocontrols.cxx,v $ + * $Revision: 1.87 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_toolkit.hxx" +#include <com/sun/star/awt/XTextArea.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/VisualEffect.hpp> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/graphic/GraphicObject.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> + + +#include <toolkit/controls/formattedcontrol.hxx> +#include <toolkit/controls/roadmapcontrol.hxx> +#include <toolkit/controls/unocontrols.hxx> +#include <toolkit/controls/geometrycontrolmodel.hxx> +#include <toolkit/controls/stdtabcontroller.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/unopropertyarrayhelper.hxx> +#include <toolkit/helper/unomemorystream.hxx> +#include <toolkit/helper/servicenames.hxx> +#include <toolkit/helper/macros.hxx> +#include <toolkit/helper/imagealign.hxx> + +// for introspection +#include <toolkit/awt/vclxwindows.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/componentcontext.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/extract.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/edit.hxx> +#ifndef _SV_BUTTON_HXX +#include <vcl/button.hxx> +#endif +#include <vcl/group.hxx> +#include <vcl/fixed.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/combobox.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <tools/date.hxx> +#include <tools/time.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::toolkit; + + +// ---------------------------------------------------- +// helper +// ---------------------------------------------------- + +static void lcl_knitImageComponents( const uno::Reference< awt::XControlModel >& _rxModel, + const uno::Reference< awt::XWindowPeer >& _rxPeer, + bool _bAdd ) +{ + uno::Reference< awt::XImageProducer > xProducer( _rxModel, uno::UNO_QUERY ); + if ( xProducer.is() ) + { + uno::Reference< awt::XImageConsumer > xConsumer( _rxPeer, uno::UNO_QUERY ); + if ( xConsumer.is() ) + { + if ( _bAdd ) + { + xProducer->addConsumer( xConsumer ); + xProducer->startProduction(); + } + else + xProducer->removeConsumer( xConsumer ); + } + } +} + +// ---------------------------------------------------- +// class UnoControlEditModel +// ---------------------------------------------------- +UnoControlEditModel::UnoControlEditModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXEdit ); +} + +::rtl::OUString UnoControlEditModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlEditModel ); +} + +uno::Any UnoControlEditModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + uno::Any aReturn; + + switch ( nPropId ) + { + case BASEPROPERTY_LINE_END_FORMAT: + aReturn <<= (sal_Int16)awt::LineEndFormat::LINE_FEED; // LF + break; + case BASEPROPERTY_DEFAULTCONTROL: + aReturn <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlEdit ); + break; + default: + aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); + break; + } + return aReturn; +} + +::cppu::IPropertyArrayHelper& UnoControlEditModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlEditModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + +// ---------------------------------------------------- +// class UnoEditControl +// ---------------------------------------------------- +UnoEditControl::UnoEditControl() + :maTextListeners( *this ) + ,mnMaxTextLen( 0 ) + ,mbSetTextInPeer( sal_False ) + ,mbSetMaxTextLenInPeer( sal_False ) + ,mbHasTextProperty( sal_False ) +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; + mnMaxTextLen = 0; + mbSetMaxTextLenInPeer = FALSE; +} + +uno::Any SAL_CALL UnoEditControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aReturn = UnoControlBase::queryAggregation( rType ); + if ( !aReturn.hasValue() ) + aReturn = UnoEditControl_Base::queryInterface( rType ); + return aReturn; +} + +uno::Any SAL_CALL UnoEditControl::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException) +{ + return UnoControlBase::queryInterface( rType ); +} + +void SAL_CALL UnoEditControl::acquire( ) throw () +{ + UnoControlBase::acquire(); +} + +void SAL_CALL UnoEditControl::release( ) throw () +{ + UnoControlBase::release(); +} + +IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoEditControl, UnoControlBase, UnoEditControl_Base ) + +::rtl::OUString UnoEditControl::GetComponentServiceName() +{ + // by default, we want a simple edit field + ::rtl::OUString sName( ::rtl::OUString::createFromAscii( "Edit" ) ); + + // but maybe we are to display multi-line text? + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_MULTILINE ) ); + sal_Bool b = sal_Bool(); + if ( ( aVal >>= b ) && b ) + sName= ::rtl::OUString::createFromAscii( "MultiLineEdit" ); + + return sName; +} + +sal_Bool SAL_CALL UnoEditControl::setModel(const uno::Reference< awt::XControlModel >& _rModel) throw ( uno::RuntimeException ) +{ + sal_Bool bReturn = UnoControlBase::setModel( _rModel ); + mbHasTextProperty = ImplHasProperty( BASEPROPERTY_TEXT ); + return bReturn; +} + +void UnoEditControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const uno::Any& rVal ) +{ + sal_Bool bDone = sal_False; + if ( GetPropertyId( rPropName ) == BASEPROPERTY_TEXT ) + { + // #96986# use setText(), or text listener will not be called. + uno::Reference < awt::XTextComponent > xTextComponent( getPeer(), uno::UNO_QUERY ); + if ( xTextComponent.is() ) + { + ::rtl::OUString sText; + rVal >>= sText; + ImplCheckLocalize( sText ); + xTextComponent->setText( sText ); + bDone = sal_True; + } + } + + if ( !bDone ) + UnoControlBase::ImplSetPeerProperty( rPropName, rVal ); +} + +void UnoEditControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt( *this ); + maTextListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); +} + +void UnoEditControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference< awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + { + xText->addTextListener( this ); + + if ( mbSetMaxTextLenInPeer ) + xText->setMaxTextLen( mnMaxTextLen ); + if ( mbSetTextInPeer ) + xText->setText( maText ); + } +} + +void UnoEditControl::textChanged(const awt::TextEvent& e) throw(uno::RuntimeException) +{ + uno::Reference< awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + + if ( mbHasTextProperty ) + { + uno::Any aAny; + aAny <<= xText->getText(); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), aAny, sal_False ); + } + else + { + maText = xText->getText(); + } + + if ( maTextListeners.getLength() ) + maTextListeners.textChanged( e ); +} + +void UnoEditControl::addTextListener(const uno::Reference< awt::XTextListener > & l) throw(uno::RuntimeException) +{ + maTextListeners.addInterface( l ); +} + +void UnoEditControl::removeTextListener(const uno::Reference< awt::XTextListener > & l) throw(uno::RuntimeException) +{ + maTextListeners.removeInterface( l ); +} + +void UnoEditControl::setText( const ::rtl::OUString& aText ) throw(uno::RuntimeException) +{ + if ( mbHasTextProperty ) + { + uno::Any aAny; + aAny <<= aText; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), aAny, sal_True ); + } + else + { + maText = aText; + mbSetTextInPeer = sal_True; + uno::Reference < awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + xText->setText( maText ); + } + + // Setting the property to the VCLXWindow doesn't call textChanged + if ( maTextListeners.getLength() ) + { + awt::TextEvent aEvent; + aEvent.Source = *this; + maTextListeners.textChanged( aEvent ); + } +} + +namespace +{ + static void lcl_normalize( awt::Selection& _rSel ) + { + if ( _rSel.Min > _rSel.Max ) + ::std::swap( _rSel.Min, _rSel.Max ); + } + +/* + static bool lcl_intersect( const awt::Selection& _rLHS, const awt::Selection& _rRHS ) + { + OSL_PRECOND( _rLHS.Min <= _rLHS.Max, "lcl_intersect: LHS to be normalized!" ); + OSL_PRECOND( _rRHS.Min <= _rRHS.Max, "lcl_intersect: RHS to be normalized!" ); + return !( ( _rLHS.Max < _rRHS.Min ) || ( _rLHS.Min > _rRHS.Max ) ); + } +*/ +} + +void UnoEditControl::insertText( const awt::Selection& rSel, const ::rtl::OUString& rNewText ) throw(uno::RuntimeException) +{ + // normalize the selection - OUString::replaceAt has a strange behaviour if the min is greater than the max + awt::Selection aSelection( rSel ); + lcl_normalize( aSelection ); + + // preserve the selection resp. cursor position + awt::Selection aNewSelection( getSelection() ); +#ifdef ALSO_PRESERVE_COMPLETE_SELECTION + // (not sure - looks uglier ...) + sal_Int32 nDeletedCharacters = ( aSelection.Max - aSelection.Min ) - rNewText.getLength(); + if ( aNewSelection.Min > aSelection.Min ) + aNewSelection.Min -= nDeletedCharacters; + if ( aNewSelection.Max > aSelection.Max ) + aNewSelection.Max -= nDeletedCharacters; +#else + aNewSelection.Max = ::std::min( aNewSelection.Min, aNewSelection.Max ) + rNewText.getLength(); + aNewSelection.Min = aNewSelection.Max; +#endif + + ::rtl::OUString aOldText = getText(); + ::rtl::OUString aNewText = aOldText.replaceAt( aSelection.Min, aSelection.Max - aSelection.Min, rNewText ); + setText( aNewText ); + + setSelection( aNewSelection ); +} + +::rtl::OUString UnoEditControl::getText() throw(uno::RuntimeException) +{ + ::rtl::OUString aText = maText; + + if ( mbHasTextProperty ) + aText = ImplGetPropertyValue_UString( BASEPROPERTY_TEXT ); + else + { + uno::Reference< awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + aText = xText->getText(); + } + + return aText; +} + +::rtl::OUString UnoEditControl::getSelectedText( void ) throw(uno::RuntimeException) +{ + ::rtl::OUString sSelected; + uno::Reference< awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + sSelected = xText->getSelectedText(); + + return sSelected; +} + +void UnoEditControl::setSelection( const awt::Selection& aSelection ) throw(uno::RuntimeException) +{ + uno::Reference< awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + xText->setSelection( aSelection ); +} + +awt::Selection UnoEditControl::getSelection( void ) throw(uno::RuntimeException) +{ + awt::Selection aSel; + uno::Reference< awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + aSel = xText->getSelection(); + return aSel; +} + +sal_Bool UnoEditControl::isEditable( void ) throw(uno::RuntimeException) +{ + return !ImplGetPropertyValue_BOOL( BASEPROPERTY_READONLY ); +} + +void UnoEditControl::setEditable( sal_Bool bEditable ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Bool)!bEditable; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_READONLY ), aAny, sal_True ); +} + +sal_Int16 UnoEditControl::getMaxTextLen() throw(uno::RuntimeException) +{ + sal_Int16 nMaxLen = mnMaxTextLen; + + if ( ImplHasProperty( BASEPROPERTY_MAXTEXTLEN ) ) + nMaxLen = ImplGetPropertyValue_INT16( BASEPROPERTY_MAXTEXTLEN ); + + return nMaxLen; +} + +void UnoEditControl::setMaxTextLen( sal_Int16 nLen ) throw(uno::RuntimeException) +{ + if ( ImplHasProperty( BASEPROPERTY_MAXTEXTLEN) ) + { + uno::Any aAny; + aAny <<= (sal_Int16)nLen; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_MAXTEXTLEN ), aAny, sal_True ); + } + else + { + mnMaxTextLen = nLen; + mbSetMaxTextLenInPeer = sal_True; + uno::Reference < awt::XTextComponent > xText( getPeer(), uno::UNO_QUERY ); + if ( xText.is() ) + xText->setMaxTextLen( mnMaxTextLen ); + } +} + +awt::Size UnoEditControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoEditControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoEditControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +awt::Size UnoEditControl::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize( nCols, nLines ); +} + +void UnoEditControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(uno::RuntimeException) +{ + Impl_getColumnsAndLines( nCols, nLines ); +} + + +// ---------------------------------------------------- +// class UnoControlFileControlModel +// ---------------------------------------------------- +UnoControlFileControlModel::UnoControlFileControlModel() +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_READONLY ); + ImplRegisterProperty( BASEPROPERTY_TABSTOP ); + ImplRegisterProperty( BASEPROPERTY_TEXT ); + ImplRegisterProperty( BASEPROPERTY_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION ); +} + +::rtl::OUString UnoControlFileControlModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFileControlModel ); +} + +uno::Any UnoControlFileControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlFileControl ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlFileControlModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlFileControlModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +// ---------------------------------------------------- +// class UnoFileControl +// ---------------------------------------------------- +UnoFileControl::UnoFileControl() +{ +} + +::rtl::OUString UnoFileControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "filecontrol" ); +} + +// ---------------------------------------------------- +// class ImageProducerControlModel +// ---------------------------------------------------- +uno::Any SAL_CALL ImageProducerControlModel::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException) +{ + return UnoControlModel::queryInterface( rType ); +} + +uno::Any SAL_CALL ImageProducerControlModel::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, SAL_STATIC_CAST( awt::XImageProducer*, this ) ); + return (aRet.hasValue() ? aRet : UnoControlModel::queryAggregation( rType )); +} + +void SAL_CALL ImageProducerControlModel::acquire() throw() +{ + UnoControlModel::acquire(); +} + +void SAL_CALL ImageProducerControlModel::release() throw() +{ + UnoControlModel::release(); +} + +uno::Any ImageProducerControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_GRAPHIC ) + return uno::makeAny( uno::Reference< graphic::XGraphic >() ); + + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + uno::Reference< graphic::XGraphic > ImageProducerControlModel::getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL ) + { + uno::Reference< graphic::XGraphic > xGraphic; + + if( ( _rURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 ) ) + { + // graphic manager uniqueid + rtl::OUString sID = _rURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 ); + // get the DefaultContext + ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); + mxGrfObj = graphic::GraphicObject::createWithId( aContext.getUNOContext(), sID ); + } + else // linked + mxGrfObj = NULL; // release the GraphicObject + + if ( !_rURL.getLength() ) + return xGraphic; + + try + { + ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); + uno::Reference< graphic::XGraphicProvider > xProvider; + if ( aContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) ) + { + uno::Sequence< beans::PropertyValue > aMediaProperties(1); + aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aMediaProperties[0].Value <<= _rURL; + xGraphic = xProvider->queryGraphic( aMediaProperties ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return xGraphic; + } + +void SAL_CALL ImageProducerControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception) +{ + UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + + // - ImageAlign and ImagePosition need to correspond to each other + // - Graphic and ImageURL need to correspond to each other + try + { + switch ( nHandle ) + { + case BASEPROPERTY_IMAGEURL: + if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_GRAPHIC ) ) + { + mbAdjustingGraphic = true; + ::rtl::OUString sImageURL; + OSL_VERIFY( rValue >>= sImageURL ); + setPropertyValue( GetPropertyName( BASEPROPERTY_GRAPHIC ), uno::makeAny( getGraphicFromURL_nothrow( sImageURL ) ) ); + mbAdjustingGraphic = false; + } + break; + + case BASEPROPERTY_GRAPHIC: + if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_IMAGEURL ) ) + { + mbAdjustingGraphic = true; + setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEURL ), uno::makeAny( ::rtl::OUString() ) ); + mbAdjustingGraphic = false; + } + break; + + case BASEPROPERTY_IMAGEALIGN: + if ( !mbAdjustingImagePosition && ImplHasProperty( BASEPROPERTY_IMAGEPOSITION ) ) + { + mbAdjustingImagePosition = true; + sal_Int16 nUNOValue = 0; + OSL_VERIFY( rValue >>= nUNOValue ); + setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEPOSITION ), uno::makeAny( getExtendedImagePosition( nUNOValue ) ) ); + mbAdjustingImagePosition = false; + } + break; + case BASEPROPERTY_IMAGEPOSITION: + if ( !mbAdjustingImagePosition && ImplHasProperty( BASEPROPERTY_IMAGEALIGN ) ) + { + mbAdjustingImagePosition = true; + sal_Int16 nUNOValue = 0; + OSL_VERIFY( rValue >>= nUNOValue ); + setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEALIGN ), uno::makeAny( getCompatibleImageAlign( translateImagePosition( nUNOValue ) ) ) ); + mbAdjustingImagePosition = false; + } + break; + } + } + catch( const ::com::sun::star::uno::Exception& ) + { + OSL_ENSURE( sal_False, "ImageProducerControlModel::setFastPropertyValue_NoBroadcast: caught an exception while aligning the ImagePosition/ImageAlign properties!" ); + mbAdjustingImagePosition = sal_False; + } +} + +void ImageProducerControlModel::addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException) +{ + maListeners.push_back( xConsumer ); +} + +void ImageProducerControlModel::removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException) +{ + maListeners.remove( xConsumer ); +} + +void ImageProducerControlModel::startProduction( ) throw (::com::sun::star::uno::RuntimeException) +{ + uno::Sequence<uno::Any> aArgs(1); + aArgs.getArray()[0] = getPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEURL ) ); + uno::Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + uno::Reference< awt::XImageProducer > xImageProducer( xMSF->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "com.sun.star.awt.ImageProducer" ), aArgs ), uno::UNO_QUERY ); + if ( xImageProducer.is() ) + { + std::list< uno::Reference< awt::XImageConsumer > >::iterator aIter( maListeners.begin() ); + while ( aIter != maListeners.end() ) + { + xImageProducer->addConsumer( *aIter ); + aIter++; + } + xImageProducer->startProduction(); + } +} + +// ---------------------------------------------------- +// class ImageConsumerControl +// ---------------------------------------------------- + +sal_Bool SAL_CALL ImageConsumerControl::setModel(const uno::Reference< awt::XControlModel >& _rModel) throw ( uno::RuntimeException ) +{ + // remove the peer as image consumer from the model + lcl_knitImageComponents( getModel(), getPeer(), false ); + + sal_Bool bReturn = UnoControlBase::setModel( _rModel ); + + // add the peer as image consumer to the model + lcl_knitImageComponents( getModel(), getPeer(), true ); + + return bReturn; +} + +void SAL_CALL ImageConsumerControl::createPeer( const uno::Reference< awt::XToolkit >& rxToolkit, const uno::Reference< awt::XWindowPeer >& rParentPeer ) throw(uno::RuntimeException) +{ + // remove the peer as image consumer from the model + lcl_knitImageComponents( getModel(), getPeer(), false ); + + UnoControlBase::createPeer( rxToolkit, rParentPeer ); + + // add the peer as image consumer to the model + lcl_knitImageComponents( getModel(), getPeer(), true ); +} + +void SAL_CALL ImageConsumerControl::dispose( ) throw(::com::sun::star::uno::RuntimeException) +{ + // remove the peer as image consumer from the model + lcl_knitImageComponents( getModel(), getPeer(), false ); + + UnoControlBase::dispose(); +} + +void ImageConsumerControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const uno::Any& rVal ) +{ + sal_uInt16 nType = GetPropertyId( rPropName ); + if ( nType == BASEPROPERTY_IMAGEURL ) + { + uno::Reference < awt::XImageProducer > xImgProd( getModel(), uno::UNO_QUERY ); + uno::Reference < awt::XImageConsumer > xImgCons( getPeer(), uno::UNO_QUERY ); + + if ( xImgProd.is() && xImgCons.is() ) + xImgProd->startProduction(); + } + else + UnoControlBase::ImplSetPeerProperty( rPropName, rVal ); +} + +// ---------------------------------------------------- +// class UnoControlButtonModel +// ---------------------------------------------------- +UnoControlButtonModel::UnoControlButtonModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXButton ); + + osl_incrementInterlockedCount( &m_refCount ); + { + setFastPropertyValue_NoBroadcast( BASEPROPERTY_IMAGEPOSITION, ImplGetDefaultValue( BASEPROPERTY_IMAGEPOSITION ) ); + // this ensures that our ImagePosition is consistent with our ImageAlign property (since both + // defaults are not per se consistent), since both are coupled in setFastPropertyValue_NoBroadcast + } + osl_decrementInterlockedCount( &m_refCount ); +} + +::rtl::OUString UnoControlButtonModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlButtonModel ); +} + +uno::Any UnoControlButtonModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoControlButton ) ); + case BASEPROPERTY_TOGGLE: + return uno::makeAny( (sal_Bool)sal_False ); + case BASEPROPERTY_ALIGN: + return uno::makeAny( (sal_Int16)PROPERTY_ALIGN_CENTER ); + case BASEPROPERTY_FOCUSONCLICK: + return uno::makeAny( (sal_Bool)sal_True ); + } + + return ImageProducerControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlButtonModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlButtonModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +// ---------------------------------------------------- +// class UnoButtonControl +// ---------------------------------------------------- +UnoButtonControl::UnoButtonControl() + : maActionListeners( *this ) + , maItemListeners( *this ) +{ + maComponentInfos.nWidth = 50; + maComponentInfos.nHeight = 14; +} + +::rtl::OUString UnoButtonControl::GetComponentServiceName() +{ + ::rtl::OUString aName( ::rtl::OUString::createFromAscii( "pushbutton" ) ); + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_PUSHBUTTONTYPE ) ); + sal_Int16 n = sal_Int16(); + if ( ( aVal >>= n ) && n ) + { + // Use PushButtonType later when available... + switch ( n ) + { + case 1 /*PushButtonType::OK*/: aName= ::rtl::OUString::createFromAscii( "okbutton" ); + break; + case 2 /*PushButtonType::CANCEL*/: aName= ::rtl::OUString::createFromAscii( "cancelbutton" ); + break; + case 3 /*PushButtonType::HELP*/: aName= ::rtl::OUString::createFromAscii( "helpbutton" ); + break; + default: + { + DBG_ERROR( "Unknown Button Type!" ); + } + } + } + return aName; +} + +void UnoButtonControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maActionListeners.disposeAndClear( aEvt ); + maItemListeners.disposeAndClear( aEvt ); + ImageConsumerControl::dispose(); +} + +void UnoButtonControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + ImageConsumerControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->setActionCommand( maActionCommand ); + if ( maActionListeners.getLength() ) + xButton->addActionListener( &maActionListeners ); + + uno::Reference< XToggleButton > xPushButton( getPeer(), uno::UNO_QUERY ); + if ( xPushButton.is() ) + xPushButton->addItemListener( this ); +} + +void UnoButtonControl::addActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + maActionListeners.addInterface( l ); + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->addActionListener( &maActionListeners ); + } +} + +void UnoButtonControl::removeActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->removeActionListener( &maActionListeners ); + } + maActionListeners.removeInterface( l ); +} + +void UnoButtonControl::addItemListener(const uno::Reference< awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.addInterface( l ); +} + +void UnoButtonControl::removeItemListener(const uno::Reference< awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.removeInterface( l ); +} + +void SAL_CALL UnoButtonControl::disposing( const lang::EventObject& Source ) throw (uno::RuntimeException) +{ + ImageConsumerControl::disposing( Source ); +} + +void SAL_CALL UnoButtonControl::itemStateChanged( const awt::ItemEvent& rEvent ) throw (uno::RuntimeException) +{ + // forward to model + uno::Any aAny; + aAny <<= (sal_Int16)rEvent.Selected; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ), aAny, sal_False ); + + // multiplex + ItemEvent aEvent( rEvent ); + aEvent.Source = *this; + maItemListeners.itemStateChanged( aEvent ); +} + +void UnoButtonControl::setLabel( const ::rtl::OUString& rLabel ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= rLabel; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LABEL ), aAny, sal_True ); +} + +void UnoButtonControl::setActionCommand( const ::rtl::OUString& rCommand ) throw(uno::RuntimeException) +{ + maActionCommand = rCommand; + if ( getPeer().is() ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->setActionCommand( rCommand ); + } +} + +awt::Size UnoButtonControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoButtonControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoButtonControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +// ---------------------------------------------------- +// class UnoControlImageControlModel +// ---------------------------------------------------- +UnoControlImageControlModel::UnoControlImageControlModel() + :mbAdjustingImageScaleMode( false ) +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXImageControl ); +} + +::rtl::OUString UnoControlImageControlModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlImageControlModel ); +} + +uno::Any UnoControlImageControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoControlImageControl ) ); + + if ( nPropId == BASEPROPERTY_IMAGE_SCALE_MODE ) + return makeAny( awt::ImageScaleMode::Anisotropic ); + + return ImageProducerControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlImageControlModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlImageControlModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +void SAL_CALL UnoControlImageControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::uno::Exception) +{ + ImageProducerControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + + // ScaleImage is an older (and less powerful) version of ScaleMode, but keep both in sync as far as possible + try + { + switch ( _nHandle ) + { + case BASEPROPERTY_IMAGE_SCALE_MODE: + if ( !mbAdjustingImageScaleMode && ImplHasProperty( BASEPROPERTY_SCALEIMAGE ) ) + { + mbAdjustingImageScaleMode = true; + sal_Int16 nScaleMode( awt::ImageScaleMode::Anisotropic ); + OSL_VERIFY( _rValue >>= nScaleMode ); + setPropertyValue( GetPropertyName( BASEPROPERTY_SCALEIMAGE ), uno::makeAny( sal_Bool( nScaleMode != awt::ImageScaleMode::None ) ) ); + mbAdjustingImageScaleMode = false; + } + break; + case BASEPROPERTY_SCALEIMAGE: + if ( !mbAdjustingImageScaleMode && ImplHasProperty( BASEPROPERTY_IMAGE_SCALE_MODE ) ) + { + mbAdjustingImageScaleMode = true; + sal_Bool bScale = sal_True; + OSL_VERIFY( _rValue >>= bScale ); + setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGE_SCALE_MODE ), uno::makeAny( bScale ? awt::ImageScaleMode::Anisotropic : awt::ImageScaleMode::None ) ); + mbAdjustingImageScaleMode = false; + } + break; + } + } + catch( const Exception& ) + { + mbAdjustingImageScaleMode = false; + throw; + } +} + +// ---------------------------------------------------- +// class UnoImageControlControl +// ---------------------------------------------------- +UnoImageControlControl::UnoImageControlControl() + : maActionListeners( *this ) +{ + // Woher die Defaults nehmen? + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 100; +} + +::rtl::OUString UnoImageControlControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "fixedimage" ); +} + +void UnoImageControlControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maActionListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); +} + +sal_Bool UnoImageControlControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} + +awt::Size UnoImageControlControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoImageControlControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoImageControlControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +// ---------------------------------------------------- +// class UnoControlRadioButtonModel +// ---------------------------------------------------- +UnoControlRadioButtonModel::UnoControlRadioButtonModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXRadioButton ); +} + +::rtl::OUString UnoControlRadioButtonModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlRadioButtonModel ); +} + +uno::Any UnoControlRadioButtonModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoControlRadioButton ) ); + + case BASEPROPERTY_VISUALEFFECT: + return uno::makeAny( (sal_Int16)awt::VisualEffect::LOOK3D ); + } + + return ImageProducerControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlRadioButtonModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlRadioButtonModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + + +// ---------------------------------------------------- +// class UnoRadioButtonControl +// ---------------------------------------------------- +UnoRadioButtonControl::UnoRadioButtonControl() + : maItemListeners( *this ), maActionListeners( *this ) +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; +} + +::rtl::OUString UnoRadioButtonControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "radiobutton" ); +} + +void UnoRadioButtonControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maItemListeners.disposeAndClear( aEvt ); + ImageConsumerControl::dispose(); +} + + +sal_Bool UnoRadioButtonControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} + +void UnoRadioButtonControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + ImageConsumerControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XRadioButton > xRadioButton( getPeer(), uno::UNO_QUERY ); + xRadioButton->addItemListener( this ); + + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->setActionCommand( maActionCommand ); + if ( maActionListeners.getLength() ) + xButton->addActionListener( &maActionListeners ); + + // as default, set the "AutoToggle" to true + // (it is set to false in VCLXToolkit::ImplCreateWindow because of #87254#, but we want to + // have it enabled by default because of 85071) + uno::Reference< awt::XVclWindowPeer > xVclWindowPeer( getPeer(), uno::UNO_QUERY ); + if ( xVclWindowPeer.is() ) + xVclWindowPeer->setProperty( GetPropertyName( BASEPROPERTY_AUTOTOGGLE ), ::cppu::bool2any( sal_True ) ); +} + +void UnoRadioButtonControl::addItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.addInterface( l ); +} + +void UnoRadioButtonControl::removeItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.removeInterface( l ); +} + +void UnoRadioButtonControl::addActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + maActionListeners.addInterface( l ); + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->addActionListener( &maActionListeners ); + } +} + +void UnoRadioButtonControl::removeActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->removeActionListener( &maActionListeners ); + } + maActionListeners.removeInterface( l ); +} + +void UnoRadioButtonControl::setLabel( const ::rtl::OUString& rLabel ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= rLabel; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LABEL ), aAny, sal_True ); +} + +void UnoRadioButtonControl::setActionCommand( const ::rtl::OUString& rCommand ) throw(uno::RuntimeException) +{ + maActionCommand = rCommand; + if ( getPeer().is() ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->setActionCommand( rCommand ); + } +} + +void UnoRadioButtonControl::setState( sal_Bool bOn ) throw(uno::RuntimeException) +{ + sal_Int16 nState = bOn ? 1 : 0; + uno::Any aAny; + aAny <<= nState; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ), aAny, sal_True ); +} + +sal_Bool UnoRadioButtonControl::getState() throw(uno::RuntimeException) +{ + sal_Int16 nState = 0; + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ) ); + aVal >>= nState; + return nState ? sal_True : sal_False; +} + +void UnoRadioButtonControl::itemStateChanged( const awt::ItemEvent& rEvent ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Int16)rEvent.Selected; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ), aAny, sal_False ); + + // compatibility: + // in OOo 1.0.x, when the user clicked a radio button in a group of buttons, this resulted + // in _one_ itemStateChanged call for exactly the radio button which's state changed from + // "0" to "1". + // Nowadays, since the listener handling changed a lot towards 1.1 (the VCLXWindow reacts on more + // basic events from the VCL-windows, not anymore on the Link-based events like in 1.0.x), this + // isn't the case anymore: For instance, this method here gets called for the radio button + // which is being implicitily _de_selected, too. This is pretty bad for compatibility. + // Thus, we suppress all events with a new state other than "1". This is unlogical, and weird, when looking + // from a pure API perspective, but it's _compatible_ with older product versions, and this is + // all which matters here. + // #i14703# - 2003-05-23 - fs@openoffice.org + if ( 1 == rEvent.Selected ) + { + if ( maItemListeners.getLength() ) + maItemListeners.itemStateChanged( rEvent ); + } + // note that speaking stricly, this is wrong: When in 1.0.x, the user would have de-selected + // a radio button _without_ selecing another one, this would have caused a notification. + // With the change done here, this today won't cause a notification anymore. + // + // Fortunately, it's not possible for the user to de-select a radio button without selecting another on, + // at least not via the regular UI. It _would_ be possible via the Accessibility API, which + // counts as "user input", too. But in 1.0.x, there was no Accessibility API, so there is nothing + // to be inconsistent with. +} + +awt::Size UnoRadioButtonControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoRadioButtonControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoRadioButtonControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +// ---------------------------------------------------- +// class UnoControlCheckBoxModel +// ---------------------------------------------------- +UnoControlCheckBoxModel::UnoControlCheckBoxModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXCheckBox ); +} + +::rtl::OUString UnoControlCheckBoxModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlCheckBoxModel ); +} + +uno::Any UnoControlCheckBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + switch ( nPropId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_UnoControlCheckBox ) ); + + case BASEPROPERTY_VISUALEFFECT: + return uno::makeAny( (sal_Int16)awt::VisualEffect::LOOK3D ); + } + + return ImageProducerControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlCheckBoxModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlCheckBoxModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + + +// ---------------------------------------------------- +// class UnoCheckBoxControl +// ---------------------------------------------------- +UnoCheckBoxControl::UnoCheckBoxControl() + : maItemListeners( *this ), maActionListeners( *this ) +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; +} + +::rtl::OUString UnoCheckBoxControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "checkbox" ); +} + +void UnoCheckBoxControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maItemListeners.disposeAndClear( aEvt ); + ImageConsumerControl::dispose(); +} + +sal_Bool UnoCheckBoxControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} + +void UnoCheckBoxControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + ImageConsumerControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XCheckBox > xCheckBox( getPeer(), uno::UNO_QUERY ); + xCheckBox->addItemListener( this ); + + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->setActionCommand( maActionCommand ); + if ( maActionListeners.getLength() ) + xButton->addActionListener( &maActionListeners ); +} + +void UnoCheckBoxControl::addItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.addInterface( l ); +} + +void UnoCheckBoxControl::removeItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.removeInterface( l ); +} + +void UnoCheckBoxControl::addActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + maActionListeners.addInterface( l ); + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->addActionListener( &maActionListeners ); + } +} + +void UnoCheckBoxControl::removeActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->removeActionListener( &maActionListeners ); + } + maActionListeners.removeInterface( l ); +} + +void UnoCheckBoxControl::setActionCommand( const ::rtl::OUString& rCommand ) throw(uno::RuntimeException) +{ + maActionCommand = rCommand; + if ( getPeer().is() ) + { + uno::Reference < awt::XButton > xButton( getPeer(), uno::UNO_QUERY ); + xButton->setActionCommand( rCommand ); + } +} + + +void UnoCheckBoxControl::setLabel( const ::rtl::OUString& rLabel ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= rLabel; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LABEL ), aAny, sal_True ); +} + +void UnoCheckBoxControl::setState( short n ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Int16)n; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ), aAny, sal_True ); +} + +short UnoCheckBoxControl::getState() throw(uno::RuntimeException) +{ + short nState = 0; + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ) ); + aVal >>= nState; + return nState; +} + +void UnoCheckBoxControl::enableTriState( sal_Bool b ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= b; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TRISTATE ), aAny, sal_True ); +} + +void UnoCheckBoxControl::itemStateChanged( const awt::ItemEvent& rEvent ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Int16)rEvent.Selected; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STATE ), aAny, sal_False ); + + if ( maItemListeners.getLength() ) + maItemListeners.itemStateChanged( rEvent ); +} + +awt::Size UnoCheckBoxControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoCheckBoxControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoCheckBoxControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +// ---------------------------------------------------- +// class UnoControlFixedHyperlinkModel +// ---------------------------------------------------- +UnoControlFixedHyperlinkModel::UnoControlFixedHyperlinkModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXFixedHyperlink ); +} + +::rtl::OUString UnoControlFixedHyperlinkModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFixedHyperlinkModel ); +} + +uno::Any UnoControlFixedHyperlinkModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlFixedHyperlink ); + return aAny; + } + else if ( nPropId == BASEPROPERTY_BORDER ) + { + uno::Any aAny; + aAny <<= (sal_Int16)0; + return aAny; + } + else if ( nPropId == BASEPROPERTY_URL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString(); + return aAny; + } + + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlFixedHyperlinkModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlFixedHyperlinkModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +// ---------------------------------------------------- +// class UnoFixedHyperlinkControl +// ---------------------------------------------------- +UnoFixedHyperlinkControl::UnoFixedHyperlinkControl() + : maActionListeners( *this ) +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; +} + +::rtl::OUString UnoFixedHyperlinkControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "fixedhyperlink" ); +} + +// uno::XInterface +uno::Any UnoFixedHyperlinkControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XFixedHyperlink*, this ), + SAL_STATIC_CAST( awt::XLayoutConstrains*, this ) ); + return (aRet.hasValue() ? aRet : UnoControlBase::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoFixedHyperlinkControl ) + getCppuType( ( uno::Reference< awt::XFixedHyperlink>* ) NULL ), + getCppuType( ( uno::Reference< awt::XLayoutConstrains>* ) NULL ), + UnoControlBase::getTypes() +IMPL_XTYPEPROVIDER_END + +sal_Bool UnoFixedHyperlinkControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} + +void UnoFixedHyperlinkControl::setText( const ::rtl::OUString& Text ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Text; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LABEL ), aAny, sal_True ); +} + +::rtl::OUString UnoFixedHyperlinkControl::getText() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_UString( BASEPROPERTY_LABEL ); +} + +void UnoFixedHyperlinkControl::setURL( const ::rtl::OUString& URL ) throw(::com::sun::star::uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= URL; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_URL ), aAny, sal_True ); +} + +::rtl::OUString UnoFixedHyperlinkControl::getURL( ) throw(::com::sun::star::uno::RuntimeException) +{ + return ImplGetPropertyValue_UString( BASEPROPERTY_URL ); +} + +void UnoFixedHyperlinkControl::setAlignment( short nAlign ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Int16)nAlign; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_ALIGN ), aAny, sal_True ); +} + +short UnoFixedHyperlinkControl::getAlignment() throw(uno::RuntimeException) +{ + short nAlign = 0; + if ( mxModel.is() ) + { + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_ALIGN ) ); + aVal >>= nAlign; + } + return nAlign; +} + +awt::Size UnoFixedHyperlinkControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoFixedHyperlinkControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoFixedHyperlinkControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +void UnoFixedHyperlinkControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maActionListeners.disposeAndClear( aEvt ); + UnoControlBase::dispose(); +} + +void UnoFixedHyperlinkControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoControlBase::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XFixedHyperlink > xFixedHyperlink( getPeer(), uno::UNO_QUERY ); + if ( maActionListeners.getLength() ) + xFixedHyperlink->addActionListener( &maActionListeners ); +} + +void UnoFixedHyperlinkControl::addActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + maActionListeners.addInterface( l ); + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XFixedHyperlink > xFixedHyperlink( getPeer(), uno::UNO_QUERY ); + xFixedHyperlink->addActionListener( &maActionListeners ); + } +} + +void UnoFixedHyperlinkControl::removeActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XFixedHyperlink > xFixedHyperlink( getPeer(), uno::UNO_QUERY ); + xFixedHyperlink->removeActionListener( &maActionListeners ); + } + maActionListeners.removeInterface( l ); +} + +// ---------------------------------------------------- +// class UnoControlFixedTextModel +// ---------------------------------------------------- +UnoControlFixedTextModel::UnoControlFixedTextModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXFixedText ); +} + +::rtl::OUString UnoControlFixedTextModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFixedTextModel ); +} + +uno::Any UnoControlFixedTextModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlFixedText ); + return aAny; + } + else if ( nPropId == BASEPROPERTY_BORDER ) + { + uno::Any aAny; + aAny <<= (sal_Int16)0; + return aAny; + } + + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlFixedTextModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlFixedTextModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + +// ---------------------------------------------------- +// class UnoFixedTextControl +// ---------------------------------------------------- +UnoFixedTextControl::UnoFixedTextControl() +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; +} + +::rtl::OUString UnoFixedTextControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "fixedtext" ); +} + +// uno::XInterface +uno::Any UnoFixedTextControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XFixedText*, this ), + SAL_STATIC_CAST( awt::XLayoutConstrains*, this ) ); + return (aRet.hasValue() ? aRet : UnoControlBase::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoFixedTextControl ) + getCppuType( ( uno::Reference< awt::XFixedText>* ) NULL ), + getCppuType( ( uno::Reference< awt::XLayoutConstrains>* ) NULL ), + UnoControlBase::getTypes() +IMPL_XTYPEPROVIDER_END + +sal_Bool UnoFixedTextControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} + +void UnoFixedTextControl::setText( const ::rtl::OUString& Text ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Text; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LABEL ), aAny, sal_True ); +} + +::rtl::OUString UnoFixedTextControl::getText() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_UString( BASEPROPERTY_LABEL ); +} + +void UnoFixedTextControl::setAlignment( short nAlign ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Int16)nAlign; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_ALIGN ), aAny, sal_True ); +} + +short UnoFixedTextControl::getAlignment() throw(uno::RuntimeException) +{ + short nAlign = 0; + if ( mxModel.is() ) + { + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_ALIGN ) ); + aVal >>= nAlign; + } + return nAlign; +} + +awt::Size UnoFixedTextControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoFixedTextControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoFixedTextControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +// ---------------------------------------------------- +// class UnoControlGroupBoxModel +// ---------------------------------------------------- +UnoControlGroupBoxModel::UnoControlGroupBoxModel() +{ + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_LABEL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE ); +} + +::rtl::OUString UnoControlGroupBoxModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlGroupBoxModel ); +} + +uno::Any UnoControlGroupBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlGroupBox ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlGroupBoxModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlGroupBoxModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +// ---------------------------------------------------- +// class UnoGroupBoxControl +// ---------------------------------------------------- +UnoGroupBoxControl::UnoGroupBoxControl() +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 100; +} + +::rtl::OUString UnoGroupBoxControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "groupbox" ); +} + +sal_Bool UnoGroupBoxControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} + +// ---------------------------------------------------- +// class UnoControlListBoxModel +// ---------------------------------------------------- +UnoControlListBoxModel::UnoControlListBoxModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXListBox ); +} + +::rtl::OUString UnoControlListBoxModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlListBoxModel ); +} + +uno::Any UnoControlListBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlListBox ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlListBoxModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlListBoxModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +void UnoControlListBoxModel::ImplPropertyChanged( sal_uInt16 nPropId ) +{ + if ( nPropId == BASEPROPERTY_STRINGITEMLIST ) + { + uno::Sequence<sal_Int16> aSeq; + uno::Any aAny; + aAny <<= aSeq; + setPropertyValue( GetPropertyName( BASEPROPERTY_SELECTEDITEMS ), aAny ); + } + + UnoControlModel::ImplPropertyChanged( nPropId ); +} + +void UnoControlListBoxModel::ImplNormalizePropertySequence( const sal_Int32 _nCount, sal_Int32* _pHandles, + uno::Any* _pValues, sal_Int32* _pValidHandles ) const SAL_THROW(()) +{ + // dependencies we know: + // BASEPROPERTY_STRINGITEMLIST->BASEPROPERTY_SELECTEDITEMS + ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_STRINGITEMLIST, BASEPROPERTY_SELECTEDITEMS ); + + UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles ); +} + +// ---------------------------------------------------- +// class UnoListBoxControl +// ---------------------------------------------------- +UnoListBoxControl::UnoListBoxControl() + : maActionListeners( *this ), + maItemListeners( *this ) +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; +} + +::rtl::OUString UnoListBoxControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "listbox" ); +} + +// uno::XInterface +uno::Any UnoListBoxControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XListBox*, this ), + SAL_STATIC_CAST( awt::XItemListener*, this ), + SAL_STATIC_CAST( lang::XEventListener*, SAL_STATIC_CAST( awt::XItemListener*, this ) ), + SAL_STATIC_CAST( awt::XLayoutConstrains*, this ), + SAL_STATIC_CAST( awt::XTextLayoutConstrains*, this ) ); + return (aRet.hasValue() ? aRet : UnoControlBase::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoListBoxControl ) + getCppuType( ( uno::Reference< awt::XListBox>* ) NULL ), + getCppuType( ( uno::Reference< awt::XItemListener>* ) NULL ), + getCppuType( ( uno::Reference< awt::XLayoutConstrains>* ) NULL ), + getCppuType( ( uno::Reference< awt::XTextLayoutConstrains>* ) NULL ), + UnoControlBase::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoListBoxControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maActionListeners.disposeAndClear( aEvt ); + maItemListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); +} + +void UnoListBoxControl::ImplUpdateSelectedItemsProperty() +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + DBG_ASSERT( xListBox.is(), "XListBox?" ); + + uno::Sequence<sal_Int16> aSeq = xListBox->getSelectedItemsPos(); + uno::Any aAny; + aAny <<= aSeq; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_SELECTEDITEMS ), aAny, sal_False ); + } +} + +void UnoListBoxControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const uno::Any& rVal ) +{ + UnoControl::ImplSetPeerProperty( rPropName, rVal ); + + // Wenn die SelectedItems vor der StringItemList gesetzt werden, + // hat das keine Auswirkung... + if ( rPropName == GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ) + { + ::rtl::OUString aSelPropName = GetPropertyName( BASEPROPERTY_SELECTEDITEMS ); + uno::Any aVal = ImplGetPropertyValue( aSelPropName ); + if ( !( aVal.getValueType().getTypeClass() == uno::TypeClass_VOID ) ) + { + uno::Reference< awt::XVclWindowPeer > xW( getPeer(), uno::UNO_QUERY ); + if (xW.is()) + // same comment as in UnoControl::ImplSetPeerProperty - see there + xW->setProperty( aSelPropName, aVal ); + } + } +} + +void UnoListBoxControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->addItemListener( this ); + + if ( maActionListeners.getLength() ) + xListBox->addActionListener( &maActionListeners ); +} + +void UnoListBoxControl::addActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + maActionListeners.addInterface( l ); + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->addActionListener( &maActionListeners ); + } +} + +void UnoListBoxControl::removeActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->removeActionListener( &maActionListeners ); + } + maActionListeners.removeInterface( l ); +} + +void UnoListBoxControl::addItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.addInterface( l ); +} + +void UnoListBoxControl::removeItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.removeInterface( l ); +} + +void UnoListBoxControl::addItem( const ::rtl::OUString& aItem, sal_Int16 nPos ) throw(uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString> aSeq( 1 ); + aSeq.getArray()[0] = aItem; + addItems( aSeq, nPos ); +} + +void UnoListBoxControl::addItems( const uno::Sequence< ::rtl::OUString>& aItems, sal_Int16 nPos ) throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + sal_uInt16 nNewItems = (sal_uInt16)aItems.getLength(); + sal_uInt16 nOldLen = (sal_uInt16)aSeq.getLength(); + sal_uInt16 nNewLen = nOldLen + nNewItems; + + uno::Sequence< ::rtl::OUString> aNewSeq( nNewLen ); + ::rtl::OUString* pNewData = aNewSeq.getArray(); + ::rtl::OUString* pOldData = aSeq.getArray(); + + if ( ( nPos < 0 ) || ( nPos > nOldLen ) ) + nPos = (sal_uInt16) nOldLen; + + sal_uInt16 n; + // Items vor der Einfuege-Position + for ( n = 0; n < nPos; n++ ) + pNewData[n] = pOldData[n]; + + // Neue Items + for ( n = 0; n < nNewItems; n++ ) + pNewData[nPos+n] = aItems.getConstArray()[n]; + + // Rest der alten Items + for ( n = nPos; n < nOldLen; n++ ) + pNewData[nNewItems+n] = pOldData[n]; + + uno::Any aAny; + aAny <<= aNewSeq; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ), aAny, sal_True ); +} + +void UnoListBoxControl::removeItems( sal_Int16 nPos, sal_Int16 nCount ) throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + sal_uInt16 nOldLen = (sal_uInt16)aSeq.getLength(); + if ( nOldLen && ( nPos < nOldLen ) ) + { + if ( nCount > ( nOldLen-nPos ) ) + nCount = nOldLen-nPos; + + sal_uInt16 nNewLen = nOldLen - nCount; + + uno::Sequence< ::rtl::OUString> aNewSeq( nNewLen ); + ::rtl::OUString* pNewData = aNewSeq.getArray(); + ::rtl::OUString* pOldData = aSeq.getArray(); + + sal_uInt16 n; + // Items vor der Entfern-Position + for ( n = 0; n < nPos; n++ ) + pNewData[n] = pOldData[n]; + + // Rest der Items + for ( n = nPos; n < (nOldLen-nCount); n++ ) + pNewData[n] = pOldData[n+nCount]; + + uno::Any aAny; + aAny <<= aNewSeq; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ), aAny, sal_True ); + } +} + +sal_Int16 UnoListBoxControl::getItemCount() throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + return (sal_Int16)aSeq.getLength(); +} + +::rtl::OUString UnoListBoxControl::getItem( sal_Int16 nPos ) throw(uno::RuntimeException) +{ + ::rtl::OUString aItem; + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + if ( nPos < aSeq.getLength() ) + aItem = aSeq.getConstArray()[nPos]; + return aItem; +} + +uno::Sequence< ::rtl::OUString> UnoListBoxControl::getItems() throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + return aSeq; +} + +sal_Int16 UnoListBoxControl::getSelectedItemPos() throw(uno::RuntimeException) +{ + sal_Int16 n = -1; + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + n = xListBox->getSelectedItemPos(); + } + return n; +} + +uno::Sequence<sal_Int16> UnoListBoxControl::getSelectedItemsPos() throw(uno::RuntimeException) +{ + uno::Sequence<sal_Int16> aSeq; + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + aSeq = xListBox->getSelectedItemsPos(); + } + return aSeq; +} + +::rtl::OUString UnoListBoxControl::getSelectedItem() throw(uno::RuntimeException) +{ + ::rtl::OUString aItem; + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + aItem = xListBox->getSelectedItem(); + } + return aItem; +} + +uno::Sequence< ::rtl::OUString> UnoListBoxControl::getSelectedItems() throw(uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString> aSeq; + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + aSeq = xListBox->getSelectedItems(); + } + return aSeq; +} + +void UnoListBoxControl::selectItemPos( sal_Int16 nPos, sal_Bool bSelect ) throw(uno::RuntimeException) +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->selectItemPos( nPos, bSelect ); + } + ImplUpdateSelectedItemsProperty(); +} + +void UnoListBoxControl::selectItemsPos( const uno::Sequence<sal_Int16>& aPositions, sal_Bool bSelect ) throw(uno::RuntimeException) +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->selectItemsPos( aPositions, bSelect ); + } + ImplUpdateSelectedItemsProperty(); +} + +void UnoListBoxControl::selectItem( const ::rtl::OUString& aItem, sal_Bool bSelect ) throw(uno::RuntimeException) +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->selectItem( aItem, bSelect ); + } + ImplUpdateSelectedItemsProperty(); +} + +void UnoListBoxControl::makeVisible( sal_Int16 nEntry ) throw(uno::RuntimeException) +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XListBox > xListBox( getPeer(), uno::UNO_QUERY ); + xListBox->makeVisible( nEntry ); + } +} + +void UnoListBoxControl::setDropDownLineCount( sal_Int16 nLines ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= (sal_Int16)nLines; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LINECOUNT ), aAny, sal_True ); +} + +sal_Int16 UnoListBoxControl::getDropDownLineCount() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT16( BASEPROPERTY_LINECOUNT ); +} + +sal_Bool UnoListBoxControl::isMutipleMode() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_BOOL( BASEPROPERTY_MULTISELECTION ); +} + +void UnoListBoxControl::setMultipleMode( sal_Bool bMulti ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= bMulti; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_MULTISELECTION ), aAny, sal_True ); +} + +void UnoListBoxControl::itemStateChanged( const awt::ItemEvent& rEvent ) throw(uno::RuntimeException) +{ + ImplUpdateSelectedItemsProperty(); + if ( maItemListeners.getLength() ) + { + try + { + maItemListeners.itemStateChanged( rEvent ); + } + catch( const Exception& e ) + { +#if OSL_DEBUG_LEVEL == 0 + (void) e; // suppress warning +#else + ::rtl::OString sMessage( "UnoListBoxControl::itemStateChanged: caught an exception:\n" ); + sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US ); + OSL_ENSURE( sal_False, sMessage.getStr() ); +#endif + } + } +} + +awt::Size UnoListBoxControl::getMinimumSize( ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize(); +} + +awt::Size UnoListBoxControl::getPreferredSize( ) throw(uno::RuntimeException) +{ + return Impl_getPreferredSize(); +} + +awt::Size UnoListBoxControl::calcAdjustedSize( const awt::Size& rNewSize ) throw(uno::RuntimeException) +{ + return Impl_calcAdjustedSize( rNewSize ); +} + +awt::Size UnoListBoxControl::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(uno::RuntimeException) +{ + return Impl_getMinimumSize( nCols, nLines ); +} + +void UnoListBoxControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(uno::RuntimeException) +{ + Impl_getColumnsAndLines( nCols, nLines ); +} + +// ---------------------------------------------------- +// class UnoControlComboBoxModel +// ---------------------------------------------------- +UnoControlComboBoxModel::UnoControlComboBoxModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXComboBox ); +} + +::rtl::OUString UnoControlComboBoxModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlComboBoxModel ); +} + +uno::Any UnoControlComboBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlComboBox ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + + +::cppu::IPropertyArrayHelper& UnoControlComboBoxModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlComboBoxModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + + +// ---------------------------------------------------- +// class UnoComboBoxControl +// ---------------------------------------------------- +UnoComboBoxControl::UnoComboBoxControl() + : maActionListeners( *this ), + maItemListeners( *this ) +{ + maComponentInfos.nWidth = 100; + maComponentInfos.nHeight = 12; +} + +::rtl::OUString UnoComboBoxControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "combobox" ); +} + +// uno::XInterface +uno::Any UnoComboBoxControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XComboBox*, this ) ); + return (aRet.hasValue() ? aRet : UnoEditControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoComboBoxControl ) + getCppuType( ( uno::Reference< awt::XComboBox>* ) NULL ), + UnoEditControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoComboBoxControl::dispose() throw(uno::RuntimeException) +{ + lang::EventObject aEvt; + aEvt.Source = (::cppu::OWeakObject*)this; + maActionListeners.disposeAndClear( aEvt ); + maItemListeners.disposeAndClear( aEvt ); + UnoControl::dispose(); +} + +void UnoComboBoxControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoEditControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XComboBox > xComboBox( getPeer(), uno::UNO_QUERY ); + if ( maActionListeners.getLength() ) + xComboBox->addActionListener( &maActionListeners ); + if ( maItemListeners.getLength() ) + xComboBox->addItemListener( &maItemListeners ); +} + +void UnoComboBoxControl::addActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + maActionListeners.addInterface( l ); + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XComboBox > xComboBox( getPeer(), uno::UNO_QUERY ); + xComboBox->addActionListener( &maActionListeners ); + } +} + +void UnoComboBoxControl::removeActionListener(const uno::Reference< awt::XActionListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maActionListeners.getLength() == 1 ) + { + uno::Reference < awt::XComboBox > xComboBox( getPeer(), uno::UNO_QUERY ); + xComboBox->removeActionListener( &maActionListeners ); + } + maActionListeners.removeInterface( l ); +} + +void UnoComboBoxControl::addItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + maItemListeners.addInterface( l ); + if( getPeer().is() && maItemListeners.getLength() == 1 ) + { + uno::Reference < awt::XComboBox > xComboBox( getPeer(), uno::UNO_QUERY ); + xComboBox->addItemListener( &maItemListeners ); + } +} + +void UnoComboBoxControl::removeItemListener(const uno::Reference < awt::XItemListener > & l) throw(uno::RuntimeException) +{ + if( getPeer().is() && maItemListeners.getLength() == 1 ) + { + uno::Reference < awt::XComboBox > xComboBox( getPeer(), uno::UNO_QUERY ); // MT: Mal alles so umstellen, schoener als Ref anlegen und query rufen + xComboBox->removeItemListener( &maItemListeners ); + } + maItemListeners.removeInterface( l ); +} + +void UnoComboBoxControl::addItem( const ::rtl::OUString& aItem, sal_Int16 nPos ) throw(uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString> aSeq( 1 ); + aSeq.getArray()[0] = aItem; + addItems( aSeq, nPos ); +} + +void UnoComboBoxControl::addItems( const uno::Sequence< ::rtl::OUString>& aItems, sal_Int16 nPos ) throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + sal_uInt16 nNewItems = (sal_uInt16)aItems.getLength(); + sal_uInt16 nOldLen = (sal_uInt16)aSeq.getLength(); + sal_uInt16 nNewLen = nOldLen + nNewItems; + + uno::Sequence< ::rtl::OUString> aNewSeq( nNewLen ); + ::rtl::OUString* pNewData = aNewSeq.getArray(); + const ::rtl::OUString* pOldData = aSeq.getConstArray(); + + if ( ( nPos < 0 ) || ( nPos > nOldLen ) ) + nPos = (sal_uInt16) nOldLen; + + sal_uInt16 n; + // Items vor der Einfuege-Position + for ( n = 0; n < nPos; n++ ) + pNewData[n] = pOldData[n]; + + // Neue Items + for ( n = 0; n < nNewItems; n++ ) + pNewData[nPos+n] = aItems.getConstArray()[n]; + + // Rest der alten Items + for ( n = nPos; n < nOldLen; n++ ) + pNewData[nNewItems+n] = pOldData[n]; + + uno::Any aAny; + aAny <<= aNewSeq; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ), aAny, sal_True ); +} + +void UnoComboBoxControl::removeItems( sal_Int16 nPos, sal_Int16 nCount ) throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + sal_uInt16 nOldLen = (sal_uInt16)aSeq.getLength(); + if ( nOldLen && ( nPos < nOldLen ) ) + { + if ( nCount > ( nOldLen-nPos ) ) + nCount = nOldLen-nPos; + + sal_uInt16 nNewLen = nOldLen - nCount; + + uno::Sequence< ::rtl::OUString> aNewSeq( nNewLen ); + ::rtl::OUString* pNewData = aNewSeq.getArray(); + ::rtl::OUString* pOldData = aSeq.getArray(); + + sal_uInt16 n; + // Items vor der Entfern-Position + for ( n = 0; n < nPos; n++ ) + pNewData[n] = pOldData[n]; + + // Rest der Items + for ( n = nPos; n < (nOldLen-nCount); n++ ) + pNewData[n] = pOldData[n+nCount]; + + uno::Any aAny; + aAny <<= aNewSeq; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ), aAny, sal_True ); + } +} + +sal_Int16 UnoComboBoxControl::getItemCount() throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + return (sal_Int16)aSeq.getLength(); +} + +::rtl::OUString UnoComboBoxControl::getItem( sal_Int16 nPos ) throw(uno::RuntimeException) +{ + ::rtl::OUString aItem; + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + if ( nPos < aSeq.getLength() ) + aItem = aSeq.getConstArray()[nPos]; + return aItem; +} + +uno::Sequence< ::rtl::OUString> UnoComboBoxControl::getItems() throw(uno::RuntimeException) +{ + uno::Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) ); + uno::Sequence< ::rtl::OUString> aSeq; + aVal >>= aSeq; + return aSeq; +} + +void UnoComboBoxControl::setDropDownLineCount( sal_Int16 nLines ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= nLines; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LINECOUNT ), aAny, sal_True ); +} + +sal_Int16 UnoComboBoxControl::getDropDownLineCount() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT16( BASEPROPERTY_LINECOUNT ); +} + + +// ---------------------------------------------------- +// UnoSpinFieldControl +// ---------------------------------------------------- +UnoSpinFieldControl::UnoSpinFieldControl() : maSpinListeners( *this ) +{ + mbRepeat = sal_False; +} + +// uno::XInterface +uno::Any UnoSpinFieldControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XSpinField*, this ) ); + return (aRet.hasValue() ? aRet : UnoEditControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoSpinFieldControl ) + getCppuType( ( uno::Reference< awt::XSpinField>* ) NULL ), + UnoEditControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoSpinFieldControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoEditControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + xField->enableRepeat( mbRepeat ); + if ( maSpinListeners.getLength() ) + xField->addSpinListener( &maSpinListeners ); +} + + // ::com::sun::star::awt::XSpinField +void UnoSpinFieldControl::addSpinListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSpinListener >& l ) throw(::com::sun::star::uno::RuntimeException) +{ + maSpinListeners.addInterface( l ); + if( getPeer().is() && maSpinListeners.getLength() == 1 ) + { + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + xField->addSpinListener( &maSpinListeners ); + } +} + +void UnoSpinFieldControl::removeSpinListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSpinListener >& l ) throw(::com::sun::star::uno::RuntimeException) +{ + if( getPeer().is() && maSpinListeners.getLength() == 1 ) + { + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + xField->removeSpinListener( &maSpinListeners ); + } + maSpinListeners.removeInterface( l ); +} + +void UnoSpinFieldControl::up() throw(::com::sun::star::uno::RuntimeException) +{ + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + if ( xField.is() ) + xField->up(); +} + +void UnoSpinFieldControl::down() throw(::com::sun::star::uno::RuntimeException) +{ + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + if ( xField.is() ) + xField->down(); +} + +void UnoSpinFieldControl::first() throw(::com::sun::star::uno::RuntimeException) +{ + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + if ( xField.is() ) + xField->first(); +} + +void UnoSpinFieldControl::last() throw(::com::sun::star::uno::RuntimeException) +{ + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + if ( xField.is() ) + xField->last(); +} + +void UnoSpinFieldControl::enableRepeat( sal_Bool bRepeat ) throw(::com::sun::star::uno::RuntimeException) +{ + mbRepeat = bRepeat; + + uno::Reference < awt::XSpinField > xField( getPeer(), uno::UNO_QUERY ); + if ( xField.is() ) + xField->enableRepeat( bRepeat ); +} + +// ---------------------------------------------------- +// class UnoControlDateFieldModel +// ---------------------------------------------------- +UnoControlDateFieldModel::UnoControlDateFieldModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXDateField ); +} + +::rtl::OUString UnoControlDateFieldModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlDateFieldModel ); +} + +uno::Any UnoControlDateFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDateField ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + + +::cppu::IPropertyArrayHelper& UnoControlDateFieldModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlDateFieldModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + + +// ---------------------------------------------------- +// class UnoDateFieldControl +// ---------------------------------------------------- +UnoDateFieldControl::UnoDateFieldControl() +{ + mnFirst = Date( 1, 1, 1900 ).GetDate(); + mnLast = Date( 31, 12, 2200 ).GetDate(); + mbLongFormat = 2; +} + +::rtl::OUString UnoDateFieldControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "datefield" ); +} + +// uno::XInterface +uno::Any UnoDateFieldControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XDateField*, this ) ); + return (aRet.hasValue() ? aRet : UnoSpinFieldControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoDateFieldControl ) + getCppuType( ( uno::Reference< awt::XDateField>* ) NULL ), + UnoSpinFieldControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoDateFieldControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoSpinFieldControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + xField->setLast( mnLast ); + if ( mbLongFormat != 2 ) // not set + xField->setLongFormat( mbLongFormat ); +} + + +void UnoDateFieldControl::textChanged( const awt::TextEvent& e ) throw(uno::RuntimeException) +{ + uno::Reference< awt::XVclWindowPeer > xPeer( getPeer(), uno::UNO_QUERY ); + + // also change the text property (#i25106#) + if ( xPeer.is() ) + { + ::rtl::OUString sTextPropertyName = GetPropertyName( BASEPROPERTY_TEXT ); + ImplSetPropertyValue( sTextPropertyName, xPeer->getProperty( sTextPropertyName ), sal_False ); + } + + // re-calc the Date property + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + uno::Any aValue; + if ( xField->isEmpty() ) + { + // the field says it's empty + sal_Bool bEnforceFormat = sal_True; + if ( xPeer.is() ) + xPeer->getProperty( GetPropertyName( BASEPROPERTY_ENFORCE_FORMAT ) ) >>= bEnforceFormat; + if ( !bEnforceFormat ) + { + // and it also says that it is currently accepting invalid inputs, without + // forcing it to a valid date + uno::Reference< awt::XTextComponent > xText( xPeer, uno::UNO_QUERY ); + if ( xText.is() && xText->getText().getLength() ) + // and in real, the text of the peer is *not* empty + // -> simulate an invalid date, which is different from "no date" + aValue <<= util::Date( 0, 0, 0 ); + } + } + else + aValue <<= xField->getDate(); + + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_DATE ), aValue, sal_False ); + + // multiplex the event + if ( GetTextListeners().getLength() ) + GetTextListeners().textChanged( e ); +} + +void UnoDateFieldControl::setDate( sal_Int32 Date ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Date; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_DATE ), aAny, sal_True ); +} + +sal_Int32 UnoDateFieldControl::getDate() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_DATE ); +} + +void UnoDateFieldControl::setMin( sal_Int32 Date ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Date; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_DATEMIN ), aAny, sal_True ); +} + +sal_Int32 UnoDateFieldControl::getMin() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_DATEMIN ); +} + +void UnoDateFieldControl::setMax( sal_Int32 Date ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Date; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_DATEMAX ), aAny, sal_True ); +} + +sal_Int32 UnoDateFieldControl::getMax() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_DATEMAX ); +} + +void UnoDateFieldControl::setFirst( sal_Int32 Date ) throw(uno::RuntimeException) +{ + mnFirst = Date; + if ( getPeer().is() ) + { + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( Date ); + } +} + +sal_Int32 UnoDateFieldControl::getFirst() throw(uno::RuntimeException) +{ + return mnFirst; +} + +void UnoDateFieldControl::setLast( sal_Int32 Date ) throw(uno::RuntimeException) +{ + mnLast = Date; + if ( getPeer().is() ) + { + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + xField->setLast( Date ); + } +} + +sal_Int32 UnoDateFieldControl::getLast() throw(uno::RuntimeException) +{ + return mnLast; +} + +void UnoDateFieldControl::setLongFormat( sal_Bool bLong ) throw(uno::RuntimeException) +{ + mbLongFormat = bLong; + if ( getPeer().is() ) + { + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + xField->setLongFormat( bLong ); + } +} + +sal_Bool UnoDateFieldControl::isLongFormat() throw(uno::RuntimeException) +{ + return ( mbLongFormat != 2 ) ? mbLongFormat : sal_False; +} + +void UnoDateFieldControl::setEmpty() throw(uno::RuntimeException) +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + xField->setEmpty(); + } +} + +sal_Bool UnoDateFieldControl::isEmpty() throw(uno::RuntimeException) +{ + sal_Bool bEmpty = sal_False; + if ( getPeer().is() ) + { + uno::Reference < awt::XDateField > xField( getPeer(), uno::UNO_QUERY ); + bEmpty = xField->isEmpty(); + } + return bEmpty; +} + +void UnoDateFieldControl::setStrictFormat( sal_Bool bStrict ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= bStrict; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRICTFORMAT ), aAny, sal_True ); +} + +sal_Bool UnoDateFieldControl::isStrictFormat() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_BOOL( BASEPROPERTY_STRICTFORMAT ); +} + +// ---------------------------------------------------- +// class UnoControlTimeFieldModel +// ---------------------------------------------------- +UnoControlTimeFieldModel::UnoControlTimeFieldModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXTimeField ); +} + +::rtl::OUString UnoControlTimeFieldModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlTimeFieldModel ); +} + +uno::Any UnoControlTimeFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlTimeField ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + + +::cppu::IPropertyArrayHelper& UnoControlTimeFieldModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlTimeFieldModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + + +// ---------------------------------------------------- +// class UnoTimeFieldControl +// ---------------------------------------------------- +UnoTimeFieldControl::UnoTimeFieldControl() +{ + mnFirst = Time( 0, 0 ).GetTime(); + mnLast = Time( 23, 59, 59, 99 ).GetTime(); +} + +::rtl::OUString UnoTimeFieldControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "timefield" ); +} + +// uno::XInterface +uno::Any UnoTimeFieldControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XTimeField*, this ) ); + return (aRet.hasValue() ? aRet : UnoSpinFieldControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoTimeFieldControl ) + getCppuType( ( uno::Reference< awt::XTimeField>* ) NULL ), + UnoSpinFieldControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoTimeFieldControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoSpinFieldControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XTimeField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + xField->setLast( mnLast ); +} + +void UnoTimeFieldControl::textChanged( const awt::TextEvent& e ) throw(uno::RuntimeException) +{ + // also change the text property (#i25106#) + uno::Reference< awt::XVclWindowPeer > xPeer( getPeer(), uno::UNO_QUERY ); + ::rtl::OUString sTextPropertyName = GetPropertyName( BASEPROPERTY_TEXT ); + ImplSetPropertyValue( sTextPropertyName, xPeer->getProperty( sTextPropertyName ), sal_False ); + + // re-calc the Time property + uno::Reference < awt::XTimeField > xField( getPeer(), uno::UNO_QUERY ); + uno::Any aValue; + if ( !xField->isEmpty() ) + aValue <<= xField->getTime(); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TIME ), aValue, sal_False ); + + // multiplex the event + if ( GetTextListeners().getLength() ) + GetTextListeners().textChanged( e ); +} + +void UnoTimeFieldControl::setTime( sal_Int32 Time ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Time; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TIME ), aAny, sal_True ); +} + +sal_Int32 UnoTimeFieldControl::getTime() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_TIME ); +} + +void UnoTimeFieldControl::setMin( sal_Int32 Time ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Time; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TIMEMIN ), aAny, sal_True ); +} + +sal_Int32 UnoTimeFieldControl::getMin() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_TIMEMIN ); +} + +void UnoTimeFieldControl::setMax( sal_Int32 Time ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Time; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TIMEMAX ), aAny, sal_True ); +} + +sal_Int32 UnoTimeFieldControl::getMax() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_TIMEMAX ); +} + +void UnoTimeFieldControl::setFirst( sal_Int32 Time ) throw(uno::RuntimeException) +{ + mnFirst = Time; + if ( getPeer().is() ) + { + uno::Reference < awt::XTimeField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + } +} + +sal_Int32 UnoTimeFieldControl::getFirst() throw(uno::RuntimeException) +{ + return mnFirst; +} + +void UnoTimeFieldControl::setLast( sal_Int32 Time ) throw(uno::RuntimeException) +{ + mnLast = Time; + if ( getPeer().is() ) + { + uno::Reference < awt::XTimeField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnLast ); + } +} + +sal_Int32 UnoTimeFieldControl::getLast() throw(uno::RuntimeException) +{ + return mnLast; +} + +void UnoTimeFieldControl::setEmpty() throw(uno::RuntimeException) +{ + if ( getPeer().is() ) + { + uno::Reference < awt::XTimeField > xField( getPeer(), uno::UNO_QUERY ); + xField->setEmpty(); + } +} + +sal_Bool UnoTimeFieldControl::isEmpty() throw(uno::RuntimeException) +{ + sal_Bool bEmpty = sal_False; + if ( getPeer().is() ) + { + uno::Reference < awt::XTimeField > xField( getPeer(), uno::UNO_QUERY ); + bEmpty = xField->isEmpty(); + } + return bEmpty; +} + +void UnoTimeFieldControl::setStrictFormat( sal_Bool bStrict ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= bStrict; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRICTFORMAT ), aAny, sal_True ); +} + +sal_Bool UnoTimeFieldControl::isStrictFormat() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_BOOL( BASEPROPERTY_STRICTFORMAT ); +} + +// ---------------------------------------------------- +// class UnoControlNumericFieldModel +// ---------------------------------------------------- +UnoControlNumericFieldModel::UnoControlNumericFieldModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXNumericField ); +} + +::rtl::OUString UnoControlNumericFieldModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlNumericFieldModel ); +} + +uno::Any UnoControlNumericFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlNumericField ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + + +::cppu::IPropertyArrayHelper& UnoControlNumericFieldModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlNumericFieldModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + + +// ---------------------------------------------------- +// class UnoNumericFieldControl +// ---------------------------------------------------- +UnoNumericFieldControl::UnoNumericFieldControl() +{ + mnFirst = 0; + mnLast = 0x7FFFFFFF; +} + +::rtl::OUString UnoNumericFieldControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "numericfield" ); +} + +// uno::XInterface +uno::Any UnoNumericFieldControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XNumericField*, this ) ); + return (aRet.hasValue() ? aRet : UnoSpinFieldControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoNumericFieldControl ) + getCppuType( ( uno::Reference< awt::XNumericField>* ) NULL ), + UnoSpinFieldControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoNumericFieldControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoSpinFieldControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XNumericField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + xField->setLast( mnLast ); +} + + +void UnoNumericFieldControl::textChanged( const awt::TextEvent& e ) throw(uno::RuntimeException) +{ + uno::Reference < awt::XNumericField > xField( getPeer(), uno::UNO_QUERY ); + uno::Any aAny; + aAny <<= xField->getValue(); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUE_DOUBLE ), aAny, sal_False ); + + if ( GetTextListeners().getLength() ) + GetTextListeners().textChanged( e ); +} + +void UnoNumericFieldControl::setValue( double Value ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Value; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUE_DOUBLE ), aAny, sal_True ); +} + +double UnoNumericFieldControl::getValue() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUE_DOUBLE ); +} + +void UnoNumericFieldControl::setMin( double Value ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Value; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUEMIN_DOUBLE ), aAny, sal_True ); +} + +double UnoNumericFieldControl::getMin() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUEMIN_DOUBLE ); +} + +void UnoNumericFieldControl::setMax( double Value ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Value; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUEMAX_DOUBLE ), aAny, sal_True ); +} + +double UnoNumericFieldControl::getMax() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUEMAX_DOUBLE ); +} + +void UnoNumericFieldControl::setFirst( double Value ) throw(uno::RuntimeException) +{ + mnFirst = Value; + if ( getPeer().is() ) + { + uno::Reference < awt::XNumericField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + } +} + +double UnoNumericFieldControl::getFirst() throw(uno::RuntimeException) +{ + return mnFirst; +} + +void UnoNumericFieldControl::setLast( double Value ) throw(uno::RuntimeException) +{ + mnLast = Value; + if ( getPeer().is() ) + { + uno::Reference < awt::XNumericField > xField( getPeer(), uno::UNO_QUERY ); + xField->setLast( mnLast ); + } +} + +double UnoNumericFieldControl::getLast() throw(uno::RuntimeException) +{ + return mnLast; +} + +void UnoNumericFieldControl::setStrictFormat( sal_Bool bStrict ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= bStrict; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRICTFORMAT ), aAny, sal_True ); +} + +sal_Bool UnoNumericFieldControl::isStrictFormat() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_BOOL( BASEPROPERTY_STRICTFORMAT ); +} + +void UnoNumericFieldControl::setSpinSize( double Digits ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Digits; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUESTEP_DOUBLE ), aAny, sal_True ); +} + +double UnoNumericFieldControl::getSpinSize() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUESTEP_DOUBLE ); +} + +void UnoNumericFieldControl::setDecimalDigits( sal_Int16 Digits ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Digits; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_DECIMALACCURACY ), aAny, sal_True ); +} + +sal_Int16 UnoNumericFieldControl::getDecimalDigits() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT16( BASEPROPERTY_DECIMALACCURACY ); +} + +// ---------------------------------------------------- +// class UnoControlCurrencyFieldModel +// ---------------------------------------------------- +UnoControlCurrencyFieldModel::UnoControlCurrencyFieldModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXCurrencyField ); +} + +::rtl::OUString UnoControlCurrencyFieldModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlCurrencyFieldModel ); +} + +uno::Any UnoControlCurrencyFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlCurrencyField ); + return aAny; + } + if ( nPropId == BASEPROPERTY_CURSYM_POSITION ) + { + uno::Any aAny; + aAny <<= (sal_Bool)sal_False; + return aAny; + } + + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlCurrencyFieldModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlCurrencyFieldModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +// ---------------------------------------------------- +// class UnoCurrencyFieldControl +// ---------------------------------------------------- +UnoCurrencyFieldControl::UnoCurrencyFieldControl() +{ + mnFirst = 0; + mnLast = 0x7FFFFFFF; +} + +::rtl::OUString UnoCurrencyFieldControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "longcurrencyfield" ); +} + +// uno::XInterface +uno::Any UnoCurrencyFieldControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XCurrencyField*, this ) ); + return (aRet.hasValue() ? aRet : UnoSpinFieldControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoCurrencyFieldControl ) + getCppuType( ( uno::Reference< awt::XCurrencyField>* ) NULL ), + UnoSpinFieldControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoCurrencyFieldControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) +{ + UnoSpinFieldControl::createPeer( rxToolkit, rParentPeer ); + + uno::Reference < awt::XCurrencyField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + xField->setLast( mnLast ); +} + +void UnoCurrencyFieldControl::textChanged( const awt::TextEvent& e ) throw(uno::RuntimeException) +{ + uno::Reference < awt::XCurrencyField > xField( getPeer(), uno::UNO_QUERY ); + uno::Any aAny; + aAny <<= xField->getValue(); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUE_DOUBLE ), aAny, sal_False ); + + if ( GetTextListeners().getLength() ) + GetTextListeners().textChanged( e ); +} + +void UnoCurrencyFieldControl::setValue( double Value ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Value; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUE_DOUBLE ), aAny, sal_True ); +} + +double UnoCurrencyFieldControl::getValue() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUE_DOUBLE ); +} + +void UnoCurrencyFieldControl::setMin( double Value ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Value; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUEMIN_DOUBLE ), aAny, sal_True ); +} + +double UnoCurrencyFieldControl::getMin() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUEMIN_DOUBLE ); +} + +void UnoCurrencyFieldControl::setMax( double Value ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Value; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUEMAX_DOUBLE ), aAny, sal_True ); +} + +double UnoCurrencyFieldControl::getMax() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUEMAX_DOUBLE ); +} + +void UnoCurrencyFieldControl::setFirst( double Value ) throw(uno::RuntimeException) +{ + mnFirst = Value; + if ( getPeer().is() ) + { + uno::Reference < awt::XCurrencyField > xField( getPeer(), uno::UNO_QUERY ); + xField->setFirst( mnFirst ); + } +} + +double UnoCurrencyFieldControl::getFirst() throw(uno::RuntimeException) +{ + return mnFirst; +} + +void UnoCurrencyFieldControl::setLast( double Value ) throw(uno::RuntimeException) +{ + mnLast = Value; + if ( getPeer().is() ) + { + uno::Reference < awt::XCurrencyField > xField( getPeer(), uno::UNO_QUERY ); + xField->setLast( mnLast ); + } +} + +double UnoCurrencyFieldControl::getLast() throw(uno::RuntimeException) +{ + return mnLast; +} + +void UnoCurrencyFieldControl::setStrictFormat( sal_Bool bStrict ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= bStrict; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRICTFORMAT ), aAny, sal_True ); +} + +sal_Bool UnoCurrencyFieldControl::isStrictFormat() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_BOOL( BASEPROPERTY_STRICTFORMAT ); +} + +void UnoCurrencyFieldControl::setSpinSize( double Digits ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Digits; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_VALUESTEP_DOUBLE ), aAny, sal_True ); +} + +double UnoCurrencyFieldControl::getSpinSize() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_DOUBLE( BASEPROPERTY_VALUESTEP_DOUBLE ); +} + +void UnoCurrencyFieldControl::setDecimalDigits( sal_Int16 Digits ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= Digits; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_DECIMALACCURACY ), aAny, sal_True ); +} + +sal_Int16 UnoCurrencyFieldControl::getDecimalDigits() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_INT16( BASEPROPERTY_DECIMALACCURACY ); +} + +// ---------------------------------------------------- +// class UnoControlPatternFieldModel +// ---------------------------------------------------- +UnoControlPatternFieldModel::UnoControlPatternFieldModel() +{ + UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXPatternField ); +} + +::rtl::OUString UnoControlPatternFieldModel::getServiceName() throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlPatternFieldModel ); +} + +uno::Any UnoControlPatternFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlPatternField ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlPatternFieldModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlPatternFieldModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + +// ---------------------------------------------------- +// class UnoPatternFieldControl +// ---------------------------------------------------- +UnoPatternFieldControl::UnoPatternFieldControl() +{ +} + +::rtl::OUString UnoPatternFieldControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "patternfield" ); +} + +void UnoPatternFieldControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const uno::Any& rVal ) +{ + sal_uInt16 nType = GetPropertyId( rPropName ); + if ( ( nType == BASEPROPERTY_TEXT ) || ( nType == BASEPROPERTY_EDITMASK ) || ( nType == BASEPROPERTY_LITERALMASK ) ) + { + // Die Masken koennen nicht nacheinander gesetzt werden. + ::rtl::OUString Text = ImplGetPropertyValue_UString( BASEPROPERTY_TEXT ); + ::rtl::OUString EditMask = ImplGetPropertyValue_UString( BASEPROPERTY_EDITMASK ); + ::rtl::OUString LiteralMask = ImplGetPropertyValue_UString( BASEPROPERTY_LITERALMASK ); + + uno::Reference < awt::XPatternField > xPF( getPeer(), uno::UNO_QUERY ); + if (xPF.is()) + { + // same comment as in UnoControl::ImplSetPeerProperty - see there + ::rtl::OUString sText( Text ); + ImplCheckLocalize( sText ); + xPF->setString( sText ); + xPF->setMasks( EditMask, LiteralMask ); + } + } + else + UnoSpinFieldControl::ImplSetPeerProperty( rPropName, rVal ); +} + + +// uno::XInterface +uno::Any UnoPatternFieldControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XPatternField*, this ) ); + return (aRet.hasValue() ? aRet : UnoSpinFieldControl::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoPatternFieldControl ) + getCppuType( ( uno::Reference< awt::XPatternField>* ) NULL ), + UnoSpinFieldControl::getTypes() +IMPL_XTYPEPROVIDER_END + +void UnoPatternFieldControl::setString( const ::rtl::OUString& rString ) throw(uno::RuntimeException) +{ + setText( rString ); +} + +::rtl::OUString UnoPatternFieldControl::getString() throw(uno::RuntimeException) +{ + return getText(); +} + +void UnoPatternFieldControl::setMasks( const ::rtl::OUString& EditMask, const ::rtl::OUString& LiteralMask ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= EditMask; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_EDITMASK ), aAny, sal_True ); + aAny <<= LiteralMask; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_LITERALMASK ), aAny, sal_True ); +} + +void UnoPatternFieldControl::getMasks( ::rtl::OUString& EditMask, ::rtl::OUString& LiteralMask ) throw(uno::RuntimeException) +{ + EditMask = ImplGetPropertyValue_UString( BASEPROPERTY_EDITMASK ); + LiteralMask = ImplGetPropertyValue_UString( BASEPROPERTY_LITERALMASK ); +} + +void UnoPatternFieldControl::setStrictFormat( sal_Bool bStrict ) throw(uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= bStrict; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_STRICTFORMAT ), aAny, sal_True ); +} + +sal_Bool UnoPatternFieldControl::isStrictFormat() throw(uno::RuntimeException) +{ + return ImplGetPropertyValue_BOOL( BASEPROPERTY_STRICTFORMAT ); +} + + +// ---------------------------------------------------- +// class UnoControlProgressBarModel +// ---------------------------------------------------- +UnoControlProgressBarModel::UnoControlProgressBarModel() +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); + ImplRegisterProperty( BASEPROPERTY_PROGRESSVALUE ); + ImplRegisterProperty( BASEPROPERTY_PROGRESSVALUE_MAX ); + ImplRegisterProperty( BASEPROPERTY_PROGRESSVALUE_MIN ); +} + +::rtl::OUString UnoControlProgressBarModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlProgressBarModel ); +} + +uno::Any UnoControlProgressBarModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlProgressBar ); + return aAny; + } + + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlProgressBarModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlProgressBarModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + + +// ---------------------------------------------------- +// class UnoProgressBarControl +// ---------------------------------------------------- +UnoProgressBarControl::UnoProgressBarControl() +{ +} + +::rtl::OUString UnoProgressBarControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "ProgressBar" ); +} + +// uno::XInterface +uno::Any UnoProgressBarControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( awt::XProgressBar*, this ) ); + return (aRet.hasValue() ? aRet : UnoControlBase::queryAggregation( rType )); +} + +// lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( UnoProgressBarControl ) + getCppuType( ( uno::Reference< awt::XProgressBar>* ) NULL ), + UnoControlBase::getTypes() +IMPL_XTYPEPROVIDER_END + +// ::com::sun::star::awt::XProgressBar +void UnoProgressBarControl::setForegroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= nColor; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_FILLCOLOR ), aAny, sal_True ); +} + +void UnoProgressBarControl::setBackgroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= nColor; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_BACKGROUNDCOLOR ), aAny, sal_True ); +} + +void UnoProgressBarControl::setValue( sal_Int32 nValue ) throw(::com::sun::star::uno::RuntimeException) +{ + uno::Any aAny; + aAny <<= nValue; + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_PROGRESSVALUE ), aAny, sal_True ); +} + +void UnoProgressBarControl::setRange( sal_Int32 nMin, sal_Int32 nMax ) throw(::com::sun::star::uno::RuntimeException ) +{ + uno::Any aMin; + uno::Any aMax; + + if ( nMin < nMax ) + { + // take correct min and max + aMin <<= nMin; + aMax <<= nMax; + } + else + { + // change min and max + aMin <<= nMax; + aMax <<= nMin; + } + + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_PROGRESSVALUE_MIN ), aMin, sal_True ); + ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_PROGRESSVALUE_MAX ), aMax, sal_True ); +} + +sal_Int32 UnoProgressBarControl::getValue() throw(::com::sun::star::uno::RuntimeException) +{ + return ImplGetPropertyValue_INT32( BASEPROPERTY_PROGRESSVALUE ); +} + + +// ---------------------------------------------------- +// class UnoControlFixedLineModel +// ---------------------------------------------------- +UnoControlFixedLineModel::UnoControlFixedLineModel() +{ + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_LABEL ); + ImplRegisterProperty( BASEPROPERTY_ORIENTATION ); + ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); +} + +::rtl::OUString UnoControlFixedLineModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFixedLineModel ); +} + +uno::Any UnoControlFixedLineModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const +{ + if ( nPropId == BASEPROPERTY_DEFAULTCONTROL ) + { + uno::Any aAny; + aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlFixedLine ); + return aAny; + } + return UnoControlModel::ImplGetDefaultValue( nPropId ); +} + +::cppu::IPropertyArrayHelper& UnoControlFixedLineModel::getInfoHelper() +{ + static UnoPropertyArrayHelper* pHelper = NULL; + if ( !pHelper ) + { + uno::Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); + pHelper = new UnoPropertyArrayHelper( aIDs ); + } + return *pHelper; +} + +// beans::XMultiPropertySet +uno::Reference< beans::XPropertySetInfo > UnoControlFixedLineModel::getPropertySetInfo( ) throw(uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +// ---------------------------------------------------- +// class UnoFixedLineControl +// ---------------------------------------------------- +UnoFixedLineControl::UnoFixedLineControl() +{ + maComponentInfos.nWidth = 100; // ?? + maComponentInfos.nHeight = 100; // ?? +} + +::rtl::OUString UnoFixedLineControl::GetComponentServiceName() +{ + return ::rtl::OUString::createFromAscii( "FixedLine" ); +} + +sal_Bool UnoFixedLineControl::isTransparent() throw(uno::RuntimeException) +{ + return sal_True; +} |