| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_toolkit.hxx" |
| |
| #include <toolkit/controls/controlmodelcontainerbase.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/window.hxx> |
| #include <vcl/wall.hxx> |
| #include <vos/mutex.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" |
| #include "toolkit/controls/tkscrollbar.hxx" |
| #include "toolkit/controls/tabpagemodel.hxx" |
| #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 <com/sun/star/lang/XInitialization.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 <toolkit/helper/tkresmgr.hxx> |
| #include <unotools/ucbstreamhelper.hxx> |
| #include <vcl/graph.hxx> |
| #include <vcl/image.hxx> |
| |
| #include "tree/treecontrol.hxx" |
| #include "grid/gridcontrol.hxx" |
| #include <toolkit/controls/tabpagecontainer.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" )) |
| |
| //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; |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| // 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< ControlModelContainerBase::UnoControlModelHolder, bool > |
| { |
| private: |
| const ::rtl::OUString& m_rName; |
| |
| public: |
| FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { } |
| |
| bool operator()( const ControlModelContainerBase::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< ControlModelContainerBase::UnoControlModelHolder, void > |
| { |
| private: |
| ControlModelContainerBase::UnoControlModelHolderList& m_rTargetList; |
| |
| public: |
| CloneControlModel( ControlModelContainerBase::UnoControlModelHolderList& _rTargetList ) |
| :m_rTargetList( _rTargetList ) |
| { |
| } |
| |
| void operator()( const ControlModelContainerBase::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( ControlModelContainerBase::UnoControlModelHolder( xClone, _rSource.second ) ); |
| } |
| }; |
| |
| // ---------------------------------------------------------------------------- |
| // functor for comparing a XControlModel with a given reference |
| struct CompareControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool > |
| { |
| private: |
| Reference< XControlModel > m_xReference; |
| public: |
| CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { } |
| |
| bool operator()( const ControlModelContainerBase::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 ControlModelContainerBase |
| // ---------------------------------------------------- |
| ControlModelContainerBase::ControlModelContainerBase( const Reference< XMultiServiceFactory >& i_factory ) |
| :ControlModelContainer_IBase( i_factory ) |
| ,maContainerListeners( *this ) |
| ,maChangeListeners ( GetMutex() ) |
| ,mbGroupsUpToDate( sal_False ) |
| ,m_bEnabled( sal_True ) |
| { |
| } |
| |
| ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel ) |
| : ControlModelContainer_IBase( rModel ) |
| , maContainerListeners( *this ) |
| , maChangeListeners ( GetMutex() ) |
| , mbGroupsUpToDate( sal_False ) |
| { |
| } |
| |
| ControlModelContainerBase::~ControlModelContainerBase() |
| { |
| maModels.clear(); |
| mbGroupsUpToDate = sal_False; |
| } |
| |
| Any ControlModelContainerBase::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& ControlModelContainerBase::getInfoHelper() |
| { |
| static UnoPropertyArrayHelper* pHelper = NULL; |
| if ( !pHelper ) |
| { |
| Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); |
| pHelper = new UnoPropertyArrayHelper( aIDs ); |
| } |
| return *pHelper; |
| } |
| |
| void SAL_CALL ControlModelContainerBase::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 > ControlModelContainerBase::getPropertySetInfo( ) throw(RuntimeException) |
| { |
| static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); |
| return xInfo; |
| } |
| void ControlModelContainerBase::Clone_Impl(ControlModelContainerBase& _rClone) const |
| { |
| // clone all children |
| ::std::for_each( |
| maModels.begin(), maModels.end(), |
| CloneControlModel( _rClone.maModels ) |
| ); |
| } |
| UnoControlModel* ControlModelContainerBase::Clone() const |
| { |
| // clone the container itself |
| ControlModelContainerBase* pClone = new ControlModelContainerBase( *this ); |
| Clone_Impl(*pClone); |
| |
| return pClone; |
| } |
| |
| ControlModelContainerBase::UnoControlModelHolderList::iterator ControlModelContainerBase::ImplFindElement( const ::rtl::OUString& rName ) |
| { |
| return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) ); |
| } |
| |
| // ::XMultiServiceFactory |
| Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| OGeometryControlModel_Base* pNewModel = NULL; |
| |
| const Reference< XMultiServiceFactory > xFactory( maContext.getLegacyServiceFactory() ); |
| if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlEditModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlFileControlModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlButtonModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlImageControlModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlListBoxModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoTreeModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory ); |
| else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 ) |
| pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory ); |
| |
| if ( !pNewModel ) |
| { |
| if ( xFactory.is() ) |
| { |
| Reference< XInterface > xObject = xFactory->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 > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments ) throw(Exception, RuntimeException) |
| { |
| const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) ); |
| const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY ); |
| ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance ); |
| xInstanceInit->initialize( i_arguments ); |
| return xInstance; |
| } |
| |
| Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames() throw(RuntimeException) |
| { |
| static Sequence< ::rtl::OUString >* pNamesSeq = NULL; |
| if ( !pNamesSeq ) |
| { |
| pNamesSeq = new Sequence< ::rtl::OUString >( 24 ); |
| ::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[21] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel ); |
| pNames[22] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageContainerModel ); |
| pNames[23] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageModel ); |
| } |
| return *pNamesSeq; |
| } |
| |
| // XContainer |
| void ControlModelContainerBase::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) |
| { |
| maContainerListeners.addInterface( l ); |
| } |
| |
| void ControlModelContainerBase::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) |
| { |
| maContainerListeners.removeInterface( l ); |
| } |
| |
| // XElementAcces |
| Type ControlModelContainerBase::getElementType() throw(RuntimeException) |
| { |
| Type aType = getCppuType( ( Reference< XControlModel>* ) NULL ); |
| return aType; |
| } |
| |
| sal_Bool ControlModelContainerBase::hasElements() throw(RuntimeException) |
| { |
| return !maModels.empty(); |
| } |
| |
| // XNameContainer, XNameReplace, XNameAccess |
| void ControlModelContainerBase::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 ControlModelContainerBase::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 > ControlModelContainerBase::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 ControlModelContainerBase::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) |
| { |
| return maModels.end() != ImplFindElement( aName ); |
| } |
| |
| void ControlModelContainerBase::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 ) && ImplHasProperty(BASEPROPERTY_DIALOGSOURCEURL) ) |
| { |
| 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 ControlModelContainerBase::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 ControlModelContainerBase::getGroupControl( ) throw (RuntimeException) |
| { |
| return sal_True; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| void SAL_CALL ControlModelContainerBase::setGroupControl( sal_Bool ) throw (RuntimeException) |
| { |
| DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| void SAL_CALL ControlModelContainerBase::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 ControlModelContainerBase::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 ControlModelContainerBase::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" ); |
| } |
| |
| ////----- XInitialization ------------------------------------------------------------------- |
| void SAL_CALL ControlModelContainerBase::initialize (const Sequence<Any>& rArguments) throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException) |
| { |
| sal_Int16 nPageId = -1; |
| if ( rArguments.getLength() == 1 ) |
| { |
| if ( !( rArguments[ 0 ] >>= nPageId )) |
| throw lang::IllegalArgumentException(); |
| m_nTabPageId = nPageId; |
| } |
| else |
| m_nTabPageId = -1; |
| } |
| ::sal_Int16 SAL_CALL ControlModelContainerBase::getTabPageID() throw (::com::sun::star::uno::RuntimeException) |
| { |
| return m_nTabPageId; |
| } |
| ::sal_Bool SAL_CALL ControlModelContainerBase::getEnabled() throw (::com::sun::star::uno::RuntimeException) |
| { |
| return m_bEnabled; |
| } |
| void SAL_CALL ControlModelContainerBase::setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| m_bEnabled = _enabled; |
| } |
| ::rtl::OUString SAL_CALL ControlModelContainerBase::getTitle() throw (::com::sun::star::uno::RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| Reference<XPropertySet> xThis(*this,UNO_QUERY); |
| ::rtl::OUString sTitle; |
| xThis->getPropertyValue(GetPropertyName(BASEPROPERTY_TITLE)) >>= sTitle; |
| return sTitle; |
| } |
| void SAL_CALL ControlModelContainerBase::setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| Reference<XPropertySet> xThis(*this,UNO_QUERY); |
| xThis->setPropertyValue(GetPropertyName(BASEPROPERTY_TITLE),makeAny(_title)); |
| } |
| ::rtl::OUString SAL_CALL ControlModelContainerBase::getImageURL() throw (::com::sun::star::uno::RuntimeException) |
| { |
| return m_sImageURL; |
| } |
| void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| m_sImageURL = _imageurl; |
| } |
| ::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip() throw (::com::sun::star::uno::RuntimeException) |
| { |
| return m_sTooltip; |
| } |
| void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| m_sTooltip = _tooltip; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| 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 ControlModelContainerBase::getGroupCount( ) throw (RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| implUpdateGroupStructure(); |
| |
| return maGroups.size(); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| void SAL_CALL ControlModelContainerBase::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 ControlModelContainerBase::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 ControlModelContainerBase::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) |
| { |
| maChangeListeners.addInterface( _rxListener ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) |
| { |
| maChangeListeners.removeInterface( _rxListener ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| void ControlModelContainerBase::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 ControlModelContainerBase::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 ControlModelContainerBase::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 ControlModelContainerBase::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException) |
| { |
| } |
| |
| // ---------------------------------------------------------------------------- |
| void ControlModelContainerBase::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 ControlModelContainerBase::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 DialogContainerControl |
| // ---------------------------------------------------- |
| ControlContainerBase::ControlContainerBase( const Reference< XMultiServiceFactory >& i_factory ) |
| :ContainerControl_IBase( i_factory ) |
| ,mbSizeModified(false) |
| ,mbPosModified(false) |
| { |
| maComponentInfos.nWidth = 280; |
| maComponentInfos.nHeight = 400; |
| mxListener = new ResourceListener( Reference< util::XModifyListener >( |
| static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| |
| ControlContainerBase::~ControlContainerBase() |
| { |
| } |
| |
| void ControlContainerBase::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| UnoControlContainer::createPeer( rxToolkit, rParentPeer ); |
| } |
| |
| void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName ) |
| { |
| Reference< XPropertySet > xP( rxModel, UNO_QUERY ); |
| |
| ::rtl::OUString aDefCtrl; |
| xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl; |
| Reference < XControl > xCtrl; |
| maContext.createComponent( aDefCtrl, xCtrl ); |
| |
| DBG_ASSERT( xCtrl.is(), "ControlContainerBase::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 ControlContainerBase::ImplRemoveControl( Reference< XControlModel >& rxModel ) |
| { |
| Sequence< Reference< XControl > > aControls = getControls(); |
| Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel ); |
| if ( xCtrl.is() ) |
| { |
| removeControl( xCtrl ); |
| try |
| { |
| Reference< XComponent > const xControlComp( xCtrl, UNO_QUERY_THROW ); |
| xControlComp->dispose(); |
| } |
| catch( Exception const & ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| |
| void ControlContainerBase::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; |
| MapMode aMode( MAP_APPFONT ); |
| OutputDevice*pOutDev = Application::GetDefaultDevice(); |
| if ( pOutDev ) |
| { |
| ::Size aTmp( nX, nY ); |
| aTmp = pOutDev->LogicToPixel( aTmp, aMode ); |
| nX = aTmp.Width(); |
| nY = aTmp.Height(); |
| aTmp = ::Size( nWidth, nHeight ); |
| aTmp = pOutDev->LogicToPixel( aTmp, aMode ); |
| 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 ControlContainerBase::dispose() throw(RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| EventObject aEvt; |
| aEvt.Source = static_cast< ::cppu::OWeakObject* >( this ); |
| // 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 ControlContainerBase::disposing( |
| const EventObject& Source ) |
| throw(RuntimeException) |
| { |
| UnoControlContainer::disposing( Source ); |
| } |
| |
| sal_Bool ControlContainerBase::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 ControlContainerBase::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 ControlContainerBase::elementInserted( const ContainerEvent& Event ) throw(RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| Reference< XControlModel > xModel; |
| ::rtl::OUString aName; |
| |
| Event.Accessor >>= aName; |
| Event.Element >>= xModel; |
| ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" ); |
| try |
| { |
| ImplInsertControl( xModel, aName ); |
| } |
| catch ( const RuntimeException& e ) { throw; } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| void ControlContainerBase::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| Reference< XControlModel > xModel; |
| Event.Element >>= xModel; |
| ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" ); |
| try |
| { |
| ImplRemoveControl( xModel ); |
| } |
| catch ( const RuntimeException& e ) { throw; } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| Reference< XControlModel > xModel; |
| Event.ReplacedElement >>= xModel; |
| try |
| { |
| OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" ); |
| if ( xModel.is() ) |
| ImplRemoveControl( xModel ); |
| } |
| catch ( const RuntimeException& e ) { throw; } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| ::rtl::OUString aName; |
| Event.Accessor >>= aName; |
| Event.Element >>= xModel; |
| ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" ); |
| try |
| { |
| ImplInsertControl( xModel, aName ); |
| } |
| catch ( const RuntimeException& e ) { throw; } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // XPropertiesChangeListener |
| void ControlContainerBase::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; |
| } |
| } |
| } |
| |
| UnoControlContainer::ImplModelPropertiesChanged( rEvents ); |
| } |
| |
| void ControlContainerBase::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 ControlContainerBase::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 ControlContainerBase::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(); |
| } |
| void lcl_ApplyResolverToNestedContainees( const Reference< resource::XStringResourceResolver >& xStringResourceResolver, const Reference< XControlContainer >& xContainer ) |
| { |
| rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); |
| |
| Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver; |
| |
| Sequence< rtl::OUString > aPropNames(1); |
| aPropNames[0] = aPropName; |
| |
| const Sequence< Reference< awt::XControl > > aSeq = xContainer->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& ) |
| { |
| } |
| |
| uno::Reference< XControlContainer > xNestedContainer( xControl, uno::UNO_QUERY ); |
| if ( xNestedContainer.is() ) |
| lcl_ApplyResolverToNestedContainees( xStringResourceResolver, xNestedContainer ); |
| |
| } |
| |
| } |
| void ControlContainerBase::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 ControlContainerBase::ImplUpdateResourceResolver() |
| { |
| rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); |
| Reference< resource::XStringResourceResolver > xStringResourceResolver; |
| |
| ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver; |
| if ( !xStringResourceResolver.is() ) |
| return; |
| |
| lcl_ApplyResolverToNestedContainees( xStringResourceResolver, this ); |
| |
| // 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 ); |
| } |
| } |
| |
| |
| uno::Reference< graphic::XGraphic > ControlContainerBase::Impl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL ) |
| { |
| uno::Reference< graphic::XGraphic > xGraphic; |
| if ( !_rURL.getLength() ) |
| return xGraphic; |
| |
| try |
| { |
| uno::Reference< graphic::XGraphicProvider > xProvider; |
| if ( maContext.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; |
| } |
| //// ---------------------------------------------------- |
| //// 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 baseLocation; |
| ::rtl::OUString url; |
| |
| rbase >>= baseLocation; |
| rUrl >>= url; |
| |
| ::rtl::OUString absoluteURL( url ); |
| if ( url.getLength() > 0 ) |
| { |
| INetURLObject urlObj(baseLocation); |
| urlObj.removeSegment(); |
| baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE ); |
| |
| const INetURLObject protocolCheck( url ); |
| const INetProtocol protocol = protocolCheck.GetProtocol(); |
| if ( protocol == INET_PROT_NOT_VALID ) |
| { |
| ::rtl::OUString testAbsoluteURL; |
| if ( ::osl::FileBase::E_None == ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, testAbsoluteURL ) ) |
| absoluteURL = testAbsoluteURL; |
| } |
| } |
| |
| return absoluteURL; |
| } |
| |