1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_toolkit.hxx" 30 31 #include <toolkit/controls/controlmodelcontainerbase.hxx> 32 #include <vcl/svapp.hxx> 33 #include <vcl/window.hxx> 34 #include <vcl/wall.hxx> 35 #include <vos/mutex.hxx> 36 #include <toolkit/helper/property.hxx> 37 #include <toolkit/helper/unopropertyarrayhelper.hxx> 38 #include <toolkit/controls/geometrycontrolmodel.hxx> 39 #include <toolkit/controls/unocontrols.hxx> 40 #include "toolkit/controls/formattedcontrol.hxx" 41 #include "toolkit/controls/roadmapcontrol.hxx" 42 #include "toolkit/controls/tkscrollbar.hxx" 43 #include "toolkit/controls/tabpagemodel.hxx" 44 #include <toolkit/controls/stdtabcontroller.hxx> 45 #include <com/sun/star/awt/PosSize.hpp> 46 #include <com/sun/star/awt/WindowAttribute.hpp> 47 #include <com/sun/star/resource/XStringResourceResolver.hpp> 48 #include <com/sun/star/graphic/XGraphicProvider.hpp> 49 #include <com/sun/star/lang/XInitialization.hpp> 50 #include <tools/list.hxx> 51 #include <cppuhelper/typeprovider.hxx> 52 #include <tools/debug.hxx> 53 #include <tools/diagnose_ex.h> 54 #include <comphelper/processfactory.hxx> 55 #include <vcl/svapp.hxx> 56 #include <vcl/outdev.hxx> 57 #include <comphelper/types.hxx> 58 59 #include <comphelper/componentcontext.hxx> 60 #include <toolkit/helper/vclunohelper.hxx> 61 #include <toolkit/helper/tkresmgr.hxx> 62 #include <unotools/ucbstreamhelper.hxx> 63 #include <vcl/graph.hxx> 64 #include <vcl/image.hxx> 65 66 #include "tree/treecontrol.hxx" 67 #include "grid/gridcontrol.hxx" 68 #include <toolkit/controls/tabpagecontainer.hxx> 69 70 #include <map> 71 #include <algorithm> 72 #include <functional> 73 #include "tools/urlobj.hxx" 74 #include "osl/file.hxx" 75 76 using namespace ::com::sun::star; 77 using namespace ::com::sun::star::uno; 78 using namespace ::com::sun::star::awt; 79 using namespace ::com::sun::star::lang; 80 using namespace ::com::sun::star::container; 81 using namespace ::com::sun::star::beans; 82 using namespace ::com::sun::star::util; 83 using namespace toolkit; 84 85 #define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" )) 86 87 //HELPER 88 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl ); 89 90 struct LanguageDependentProp 91 { 92 const char* pPropName; 93 sal_Int32 nPropNameLength; 94 }; 95 96 // ---------------------------------------------------------------------------- 97 namespace 98 { 99 static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties() 100 { 101 static Sequence< ::rtl::OUString > s_aLanguageDependentProperties; 102 if ( s_aLanguageDependentProperties.getLength() == 0 ) 103 { 104 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 105 if ( s_aLanguageDependentProperties.getLength() == 0 ) 106 { 107 s_aLanguageDependentProperties.realloc( 2 ); 108 s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) ); 109 s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 110 // note: properties must be sorted 111 } 112 } 113 return s_aLanguageDependentProperties; 114 } 115 } 116 117 // ---------------------------------------------------------------------------- 118 // functor for disposing a control model 119 struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void > 120 { 121 void operator()( Reference< XControlModel >& _rxModel ) 122 { 123 try 124 { 125 ::comphelper::disposeComponent( _rxModel ); 126 } 127 catch( const Exception& ) 128 { 129 DBG_ERROR( "DisposeControlModel::(): caught an exception while disposing a component!" ); 130 } 131 } 132 }; 133 134 // ---------------------------------------------------------------------------- 135 // functor for searching control model by name 136 struct FindControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool > 137 { 138 private: 139 const ::rtl::OUString& m_rName; 140 141 public: 142 FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { } 143 144 bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare ) 145 { 146 return ( _rCompare.second == m_rName ) ? true : false; 147 } 148 }; 149 150 // ---------------------------------------------------------------------------- 151 // functor for cloning a control model, and insertion into a target list 152 struct CloneControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, void > 153 { 154 private: 155 ControlModelContainerBase::UnoControlModelHolderList& m_rTargetList; 156 157 public: 158 CloneControlModel( ControlModelContainerBase::UnoControlModelHolderList& _rTargetList ) 159 :m_rTargetList( _rTargetList ) 160 { 161 } 162 163 void operator()( const ControlModelContainerBase::UnoControlModelHolder& _rSource ) 164 { 165 // clone the source object 166 Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY ); 167 Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY ); 168 // add to target list 169 m_rTargetList.push_back( ControlModelContainerBase::UnoControlModelHolder( xClone, _rSource.second ) ); 170 } 171 }; 172 173 // ---------------------------------------------------------------------------- 174 // functor for comparing a XControlModel with a given reference 175 struct CompareControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool > 176 { 177 private: 178 Reference< XControlModel > m_xReference; 179 public: 180 CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { } 181 182 bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare ) 183 { 184 return ( _rCompare.first.get() == m_xReference.get() ) ? true : false; 185 } 186 }; 187 188 // ---------------------------------------------------------------------------- 189 static void lcl_throwIllegalArgumentException( ) 190 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... 191 throw IllegalArgumentException(); 192 } 193 194 // ---------------------------------------------------------------------------- 195 static void lcl_throwNoSuchElementException( ) 196 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... 197 throw NoSuchElementException(); 198 } 199 200 // ---------------------------------------------------------------------------- 201 static void lcl_throwElementExistException( ) 202 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this .... 203 throw ElementExistException(); 204 } 205 206 // ---------------------------------------------------------------------------- 207 static const ::rtl::OUString& getTabIndexPropertyName( ) 208 { 209 static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) ); 210 return s_sTabIndexProperty; 211 } 212 213 // ---------------------------------------------------------------------------- 214 static const ::rtl::OUString& getStepPropertyName( ) 215 { 216 static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); 217 return s_sStepProperty; 218 } 219 220 // ---------------------------------------------------- 221 // class ControlModelContainerBase 222 // ---------------------------------------------------- 223 ControlModelContainerBase::ControlModelContainerBase( const Reference< XMultiServiceFactory >& i_factory ) 224 :ControlModelContainer_IBase( i_factory ) 225 ,maContainerListeners( *this ) 226 ,maChangeListeners ( GetMutex() ) 227 ,mbGroupsUpToDate( sal_False ) 228 { 229 } 230 231 ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel ) 232 : ControlModelContainer_IBase( rModel ) 233 , maContainerListeners( *this ) 234 , maChangeListeners ( GetMutex() ) 235 , mbGroupsUpToDate( sal_False ) 236 { 237 } 238 239 ControlModelContainerBase::~ControlModelContainerBase() 240 { 241 maModels.clear(); 242 mbGroupsUpToDate = sal_False; 243 } 244 245 Any ControlModelContainerBase::ImplGetDefaultValue( sal_uInt16 nPropId ) const 246 { 247 Any aAny; 248 249 switch ( nPropId ) 250 { 251 case BASEPROPERTY_DEFAULTCONTROL: 252 aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog ); 253 break; 254 default: 255 aAny = UnoControlModel::ImplGetDefaultValue( nPropId ); 256 } 257 258 return aAny; 259 } 260 261 ::cppu::IPropertyArrayHelper& ControlModelContainerBase::getInfoHelper() 262 { 263 static UnoPropertyArrayHelper* pHelper = NULL; 264 if ( !pHelper ) 265 { 266 Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); 267 pHelper = new UnoPropertyArrayHelper( aIDs ); 268 } 269 return *pHelper; 270 } 271 272 void SAL_CALL ControlModelContainerBase::dispose( ) throw(RuntimeException) 273 { 274 // ==================================================================== 275 // tell our listeners 276 { 277 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 278 279 EventObject aDisposeEvent; 280 aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) ); 281 282 maContainerListeners.disposeAndClear( aDisposeEvent ); 283 maChangeListeners.disposeAndClear( aDisposeEvent ); 284 } 285 286 // ==================================================================== 287 // call the base class 288 UnoControlModel::dispose(); 289 290 // ==================================================================== 291 // dispose our child models 292 // for this, collect the models (we collect them from maModels, and this is modified when disposing children) 293 ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() ); 294 295 ::std::transform( 296 maModels.begin(), maModels.end(), // source range 297 aChildModels.begin(), // target location 298 ::std::select1st< UnoControlModelHolder >( ) // operation to apply -> select the XControlModel part 299 ); 300 301 // now dispose 302 ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() ); 303 aChildModels.clear(); 304 305 mbGroupsUpToDate = sal_False; 306 } 307 308 // XMultiPropertySet 309 Reference< XPropertySetInfo > ControlModelContainerBase::getPropertySetInfo( ) throw(RuntimeException) 310 { 311 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 312 return xInfo; 313 } 314 void ControlModelContainerBase::Clone_Impl(ControlModelContainerBase& _rClone) const 315 { 316 // clone all children 317 ::std::for_each( 318 maModels.begin(), maModels.end(), 319 CloneControlModel( _rClone.maModels ) 320 ); 321 } 322 UnoControlModel* ControlModelContainerBase::Clone() const 323 { 324 // clone the container itself 325 ControlModelContainerBase* pClone = new ControlModelContainerBase( *this ); 326 Clone_Impl(*pClone); 327 328 return pClone; 329 } 330 331 ControlModelContainerBase::UnoControlModelHolderList::iterator ControlModelContainerBase::ImplFindElement( const ::rtl::OUString& rName ) 332 { 333 return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) ); 334 } 335 336 // ::XMultiServiceFactory 337 Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException) 338 { 339 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 340 341 OGeometryControlModel_Base* pNewModel = NULL; 342 343 const Reference< XMultiServiceFactory > xFactory( maContext.getLegacyServiceFactory() ); 344 if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 ) 345 pNewModel = new OGeometryControlModel< UnoControlEditModel >( xFactory ); 346 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 ) 347 pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >( xFactory ); 348 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 ) 349 pNewModel = new OGeometryControlModel< UnoControlFileControlModel >( xFactory ); 350 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 ) 351 pNewModel = new OGeometryControlModel< UnoControlButtonModel >( xFactory ); 352 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 ) 353 pNewModel = new OGeometryControlModel< UnoControlImageControlModel >( xFactory ); 354 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 ) 355 pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >( xFactory ); 356 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 ) 357 pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >( xFactory ); 358 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 ) 359 pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >( xFactory ); 360 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 ) 361 pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >( xFactory ); 362 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 ) 363 pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >( xFactory ); 364 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 ) 365 pNewModel = new OGeometryControlModel< UnoControlListBoxModel >( xFactory ); 366 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 ) 367 pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >( xFactory ); 368 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 ) 369 pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >( xFactory ); 370 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 ) 371 pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >( xFactory ); 372 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 ) 373 pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >( xFactory ); 374 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 ) 375 pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >( xFactory ); 376 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 ) 377 pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >( xFactory ); 378 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 ) 379 pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >( xFactory ); 380 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 ) 381 pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >( xFactory ); 382 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 ) 383 pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >( xFactory ); 384 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 ) 385 pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >( xFactory ); 386 else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 ) 387 pNewModel = new OGeometryControlModel< UnoTreeModel >( xFactory ); 388 else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 ) 389 pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory ); 390 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 ) 391 pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory ); 392 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 ) 393 pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory ); 394 395 if ( !pNewModel ) 396 { 397 if ( xFactory.is() ) 398 { 399 Reference< XInterface > xObject = xFactory->createInstance( aServiceSpecifier ); 400 Reference< XServiceInfo > xSI( xObject, UNO_QUERY ); 401 Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY ); 402 Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY ); 403 if ( xAgg.is() ) 404 { 405 if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) ) 406 { 407 // release 3 of the 4 references we have to the object 408 xAgg.clear(); 409 xSI.clear(); 410 xObject.clear(); 411 412 pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier ); 413 } 414 } 415 } 416 } 417 418 Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel; 419 return xNewModel; 420 } 421 422 Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments ) throw(Exception, RuntimeException) 423 { 424 const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) ); 425 const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY ); 426 ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance ); 427 xInstanceInit->initialize( i_arguments ); 428 return xInstance; 429 } 430 431 Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames() throw(RuntimeException) 432 { 433 static Sequence< ::rtl::OUString >* pNamesSeq = NULL; 434 if ( !pNamesSeq ) 435 { 436 pNamesSeq = new Sequence< ::rtl::OUString >( 24 ); 437 ::rtl::OUString* pNames = pNamesSeq->getArray(); 438 pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel ); 439 pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel ); 440 pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel ); 441 pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel ); 442 pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel ); 443 pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ); 444 pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel ); 445 pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel ); 446 pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel ); 447 pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel ); 448 pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel ); 449 pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel ); 450 pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel ); 451 pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel ); 452 pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel ); 453 pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel ); 454 pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel ); 455 pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel ); 456 pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel ); 457 pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel ); 458 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel ); 459 pNames[21] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel ); 460 pNames[22] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageContainerModel ); 461 pNames[23] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageModel ); 462 } 463 return *pNamesSeq; 464 } 465 466 // XContainer 467 void ControlModelContainerBase::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) 468 { 469 maContainerListeners.addInterface( l ); 470 } 471 472 void ControlModelContainerBase::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) 473 { 474 maContainerListeners.removeInterface( l ); 475 } 476 477 // XElementAcces 478 Type ControlModelContainerBase::getElementType() throw(RuntimeException) 479 { 480 Type aType = getCppuType( ( Reference< XControlModel>* ) NULL ); 481 return aType; 482 } 483 484 sal_Bool ControlModelContainerBase::hasElements() throw(RuntimeException) 485 { 486 return !maModels.empty(); 487 } 488 489 // XNameContainer, XNameReplace, XNameAccess 490 void ControlModelContainerBase::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) 491 { 492 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 493 494 Reference< XControlModel > xNewModel; 495 aElement >>= xNewModel; 496 if ( !xNewModel.is() ) 497 lcl_throwIllegalArgumentException(); 498 499 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 500 if ( maModels.end() == aElementPos ) 501 lcl_throwNoSuchElementException(); 502 503 // stop listening at the old model 504 stopControlListening( aElementPos->first ); 505 Reference< XControlModel > xReplaced( aElementPos->first ); 506 // remember the new model, and start listening 507 aElementPos->first = xNewModel; 508 startControlListening( xNewModel ); 509 510 ContainerEvent aEvent; 511 aEvent.Source = *this; 512 aEvent.Element = aElement; 513 aEvent.ReplacedElement <<= xReplaced; 514 aEvent.Accessor <<= aName; 515 516 // notify the container listener 517 maContainerListeners.elementReplaced( aEvent ); 518 519 // our "tab controller model" has potentially changed -> notify this 520 implNotifyTabModelChange( aName ); 521 } 522 523 Any ControlModelContainerBase::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) 524 { 525 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 526 if ( maModels.end() == aElementPos ) 527 lcl_throwNoSuchElementException(); 528 529 return makeAny( aElementPos->first ); 530 } 531 532 Sequence< ::rtl::OUString > ControlModelContainerBase::getElementNames() throw(RuntimeException) 533 { 534 Sequence< ::rtl::OUString > aNames( maModels.size() ); 535 536 ::std::transform( 537 maModels.begin(), maModels.end(), // source range 538 aNames.getArray(), // target range 539 ::std::select2nd< UnoControlModelHolder >() // operator to apply: select the second element (the name) 540 ); 541 542 return aNames; 543 } 544 545 sal_Bool ControlModelContainerBase::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) 546 { 547 return maModels.end() != ImplFindElement( aName ); 548 } 549 550 void ControlModelContainerBase::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) 551 { 552 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 553 554 Reference< XControlModel > xM; 555 aElement >>= xM; 556 557 if ( xM.is() ) 558 { 559 Reference< beans::XPropertySet > xProps( xM, UNO_QUERY ); 560 if ( xProps.is() ) 561 { 562 563 Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo(); 564 565 ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL ); 566 if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty ) && ImplHasProperty(BASEPROPERTY_DIALOGSOURCEURL) ) 567 { 568 Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty ); 569 570 ::rtl::OUString absoluteUrl = 571 getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl ); 572 573 aUrl <<= absoluteUrl; 574 575 xProps.get()->setPropertyValue( sImageSourceProperty , aUrl ); 576 } 577 } 578 } 579 580 581 582 if ( !aName.getLength() || !xM.is() ) 583 lcl_throwIllegalArgumentException(); 584 585 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 586 if ( maModels.end() != aElementPos ) 587 lcl_throwElementExistException(); 588 589 maModels.push_back( UnoControlModelHolder( xM, aName ) ); 590 mbGroupsUpToDate = sal_False; 591 startControlListening( xM ); 592 593 ContainerEvent aEvent; 594 aEvent.Source = *this; 595 aEvent.Element <<= aElement; 596 aEvent.Accessor <<= aName; 597 maContainerListeners.elementInserted( aEvent ); 598 599 // our "tab controller model" has potentially changed -> notify this 600 implNotifyTabModelChange( aName ); 601 } 602 603 void ControlModelContainerBase::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) 604 { 605 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 606 607 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 608 if ( maModels.end() == aElementPos ) 609 lcl_throwNoSuchElementException(); 610 611 ContainerEvent aEvent; 612 aEvent.Source = *this; 613 aEvent.Element <<= aElementPos->first; 614 aEvent.Accessor <<= aName; 615 maContainerListeners.elementRemoved( aEvent ); 616 617 stopControlListening( aElementPos->first ); 618 Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY ); 619 maModels.erase( aElementPos ); 620 mbGroupsUpToDate = sal_False; 621 622 if ( xPS.is() ) 623 try 624 { 625 xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) ); 626 } 627 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } 628 629 // our "tab controller model" has potentially changed -> notify this 630 implNotifyTabModelChange( aName ); 631 } 632 633 // ---------------------------------------------------------------------------- 634 sal_Bool SAL_CALL ControlModelContainerBase::getGroupControl( ) throw (RuntimeException) 635 { 636 return sal_True; 637 } 638 639 // ---------------------------------------------------------------------------- 640 void SAL_CALL ControlModelContainerBase::setGroupControl( sal_Bool ) throw (RuntimeException) 641 { 642 DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" ); 643 } 644 645 // ---------------------------------------------------------------------------- 646 void SAL_CALL ControlModelContainerBase::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException) 647 { 648 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 649 650 // set the tab indexes according to the order of models in the sequence 651 const Reference< XControlModel >* pControls = _rControls.getConstArray( ); 652 const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength(); 653 654 sal_Int16 nTabIndex = 1; 655 656 for ( ; pControls != pControlsEnd; ++pControls ) 657 { 658 // look up the control in our own structure. This is to prevent invalid arguments 659 UnoControlModelHolderList::const_iterator aPos = 660 ::std::find_if( 661 maModels.begin(), maModels.end(), 662 CompareControlModel( *pControls ) 663 ); 664 if ( maModels.end() != aPos ) 665 { 666 // okay, this is an existent model 667 // now set the TabIndex property (if applicable) 668 Reference< XPropertySet > xProps( aPos->first, UNO_QUERY ); 669 Reference< XPropertySetInfo > xPSI; 670 if ( xProps.is() ) 671 xPSI = xProps->getPropertySetInfo(); 672 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) 673 xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) ); 674 } 675 mbGroupsUpToDate = sal_False; 676 } 677 } 678 679 680 typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel; 681 682 // ---------------------------------------------------------------------------- 683 Sequence< Reference< XControlModel > > SAL_CALL ControlModelContainerBase::getControlModels( ) throw (RuntimeException) 684 { 685 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 686 687 MapIndexToModel aSortedModels; 688 // will be the sorted container of all models which have a tab index property 689 ::std::vector< Reference< XControlModel > > aUnindexedModels; 690 // will be the container of all models which do not have a tab index property 691 692 UnoControlModelHolderList::const_iterator aLoop = maModels.begin(); 693 for ( ; aLoop != maModels.end(); ++aLoop ) 694 { 695 Reference< XControlModel > xModel( aLoop->first ); 696 697 // see if the model has a TabIndex property 698 Reference< XPropertySet > xControlProps( xModel, UNO_QUERY ); 699 Reference< XPropertySetInfo > xPSI; 700 if ( xControlProps.is() ) 701 xPSI = xControlProps->getPropertySetInfo( ); 702 DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" ); 703 704 // has it? 705 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) 706 { // yes 707 sal_Int32 nTabIndex = -1; 708 xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex; 709 710 aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) ); 711 } 712 else if ( xModel.is() ) 713 // no, it hasn't, but we have to include it, anyway 714 aUnindexedModels.push_back( xModel ); 715 } 716 717 // okay, here we have a container of all our models, sorted by tab index, 718 // plus a container of "unindexed" models 719 // -> merge them 720 Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() ); 721 ::std::transform( 722 aSortedModels.begin(), aSortedModels.end(), 723 ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ), 724 ::std::select2nd< MapIndexToModel::value_type >( ) 725 ); 726 727 return aReturn; 728 } 729 730 // ---------------------------------------------------------------------------- 731 void SAL_CALL ControlModelContainerBase::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException) 732 { 733 // not supported. We have only implicit grouping: 734 // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on 735 // implementation details) that VCL does grouping according to the order of controls automatically 736 // At least VCL does this for all we're interested in: Radio buttons. 737 DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" ); 738 } 739 740 ////----- XInitialization ------------------------------------------------------------------- 741 void SAL_CALL ControlModelContainerBase::initialize (const Sequence<Any>& rArguments) throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException) 742 { 743 sal_Int16 nPageId = -1; 744 if ( rArguments.getLength() == 1 ) 745 { 746 if ( !( rArguments[ 0 ] >>= nPageId )) 747 throw lang::IllegalArgumentException(); 748 m_nTabPageId = nPageId; 749 } 750 else 751 m_nTabPageId = -1; 752 } 753 ::sal_Int16 SAL_CALL ControlModelContainerBase::getTabPageID() throw (::com::sun::star::uno::RuntimeException) 754 { 755 return m_nTabPageId; 756 } 757 ::sal_Bool SAL_CALL ControlModelContainerBase::getEnabled() throw (::com::sun::star::uno::RuntimeException) 758 { 759 return m_bEnabled; 760 } 761 void SAL_CALL ControlModelContainerBase::setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException) 762 { 763 m_bEnabled = _enabled; 764 } 765 ::rtl::OUString SAL_CALL ControlModelContainerBase::getTitle() throw (::com::sun::star::uno::RuntimeException) 766 { 767 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 768 Reference<XPropertySet> xThis(*this,UNO_QUERY); 769 ::rtl::OUString sTitle; 770 xThis->getPropertyValue(GetPropertyName(BASEPROPERTY_TITLE)) >>= sTitle; 771 return sTitle; 772 //return m_sTitle; 773 } 774 void SAL_CALL ControlModelContainerBase::setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException) 775 { 776 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 777 Reference<XPropertySet> xThis(*this,UNO_QUERY); 778 xThis->setPropertyValue(GetPropertyName(BASEPROPERTY_TITLE),makeAny(_title)); 779 } 780 ::rtl::OUString SAL_CALL ControlModelContainerBase::getImageURL() throw (::com::sun::star::uno::RuntimeException) 781 { 782 return m_sImageURL; 783 } 784 void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException) 785 { 786 m_sImageURL = _imageurl; 787 } 788 ::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip() throw (::com::sun::star::uno::RuntimeException) 789 { 790 return m_sTooltip; 791 } 792 void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException) 793 { 794 m_sTooltip = _tooltip; 795 } 796 797 // ---------------------------------------------------------------------------- 798 namespace 799 { 800 enum GroupingMachineState 801 { 802 eLookingForGroup, 803 eExpandingGroup 804 }; 805 806 // ........................................................................ 807 static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel ) 808 { 809 sal_Int32 nStep = 0; 810 try 811 { 812 Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY ); 813 xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep; 814 } 815 catch( const Exception& ) 816 { 817 DBG_ERROR( "lcl_getDialogStep: caught an exception while determining the dialog page!" ); 818 } 819 return nStep; 820 } 821 } 822 823 // ---------------------------------------------------------------------------- 824 sal_Int32 SAL_CALL ControlModelContainerBase::getGroupCount( ) throw (RuntimeException) 825 { 826 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 827 828 implUpdateGroupStructure(); 829 830 return maGroups.size(); 831 } 832 833 // ---------------------------------------------------------------------------- 834 void SAL_CALL ControlModelContainerBase::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName ) throw (RuntimeException) 835 { 836 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 837 838 implUpdateGroupStructure(); 839 840 if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) ) 841 { 842 DBG_ERROR( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" ); 843 _rGroup.realloc( 0 ); 844 _rName = ::rtl::OUString(); 845 } 846 else 847 { 848 AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup; 849 _rGroup.realloc( aGroupPos->size() ); 850 // copy the models 851 ::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() ); 852 // give the group a name 853 _rName = ::rtl::OUString::valueOf( _nGroup ); 854 } 855 } 856 857 // ---------------------------------------------------------------------------- 858 void SAL_CALL ControlModelContainerBase::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup ) throw (RuntimeException) 859 { 860 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 861 862 ::rtl::OUString sDummyName; 863 getGroup( _rName.toInt32( ), _rGroup, sDummyName ); 864 } 865 866 // ---------------------------------------------------------------------------- 867 void SAL_CALL ControlModelContainerBase::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) 868 { 869 maChangeListeners.addInterface( _rxListener ); 870 } 871 872 // ---------------------------------------------------------------------------- 873 void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) 874 { 875 maChangeListeners.removeInterface( _rxListener ); 876 } 877 878 // ---------------------------------------------------------------------------- 879 void ControlModelContainerBase::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor ) 880 { 881 // multiplex to our change listeners: 882 // the changes event 883 ChangesEvent aEvent; 884 aEvent.Source = *this; 885 aEvent.Base <<= aEvent.Source; // the "base of the changes root" is also ourself 886 aEvent.Changes.realloc( 1 ); // exactly one change 887 aEvent.Changes[ 0 ].Accessor <<= _rAccessor; 888 889 890 Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() ); 891 const Reference< XInterface >* pListener = aChangeListeners.getConstArray(); 892 const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength(); 893 for ( ; pListener != pListenerEnd; ++pListener ) 894 { 895 if ( pListener->is() ) 896 static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent ); 897 } 898 } 899 900 901 // ---------------------------------------------------------------------------- 902 void ControlModelContainerBase::implUpdateGroupStructure() 903 { 904 if ( mbGroupsUpToDate ) 905 // nothing to do 906 return; 907 908 // conditions for a group: 909 // * all elements of the group are radio buttons 910 // * all elements of the group are on the same dialog page 911 // * in the overall control order (determined by the tab index), all elements are subsequent 912 913 maGroups.clear(); 914 915 Sequence< Reference< XControlModel > > aControlModels = getControlModels(); 916 const Reference< XControlModel >* pControlModels = aControlModels.getConstArray(); 917 const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength(); 918 919 // in extreme we have as much groups as controls 920 maGroups.reserve( aControlModels.getLength() ); 921 922 GroupingMachineState eState = eLookingForGroup; // the current state of our machine 923 Reference< XServiceInfo > xModelSI; // for checking for a radion button 924 AllGroups::iterator aCurrentGroup = maGroups.end(); // the group which we're currently building 925 sal_Int32 nCurrentGroupStep = -1; // the step which all controls of the current group belong to 926 sal_Bool bIsRadioButton; // is it a radio button? 927 928 #if OSL_DEBUG_LEVEL > 1 929 ::std::vector< ::rtl::OUString > aCurrentGroupLabels; 930 #endif 931 932 for ( ; pControlModels != pControlModelsEnd; ++pControlModels ) 933 { 934 // we'll need this in every state 935 xModelSI = xModelSI.query( *pControlModels ); 936 bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) ); 937 938 switch ( eState ) 939 { 940 case eLookingForGroup: 941 { 942 if ( !bIsRadioButton ) 943 // this is no radio button -> still looking for the beginning of a group 944 continue; 945 // the current model is a radio button 946 // -> we found the beginning of a new group 947 // create the place for this group 948 size_t nGroups = maGroups.size(); 949 maGroups.resize( nGroups + 1 ); 950 aCurrentGroup = maGroups.begin() + nGroups; 951 // and add the (only, til now) member 952 aCurrentGroup->push_back( *pControlModels ); 953 954 // get the step which all controls of this group now have to belong to 955 nCurrentGroupStep = lcl_getDialogStep( *pControlModels ); 956 // new state: looking for further members 957 eState = eExpandingGroup; 958 959 #if OSL_DEBUG_LEVEL > 1 960 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY ); 961 ::rtl::OUString sLabel; 962 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) ) 963 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel; 964 aCurrentGroupLabels.push_back( sLabel ); 965 #endif 966 } 967 break; 968 969 case eExpandingGroup: 970 { 971 if ( !bIsRadioButton ) 972 { // no radio button -> the group is done 973 aCurrentGroup = maGroups.end(); 974 eState = eLookingForGroup; 975 #if OSL_DEBUG_LEVEL > 1 976 aCurrentGroupLabels.clear(); 977 #endif 978 continue; 979 } 980 981 // it is a radio button - is it on the proper page? 982 const sal_Int32 nThisModelStep = lcl_getDialogStep( *pControlModels ); 983 if ( ( nThisModelStep == nCurrentGroupStep ) // the current button is on the same dialog page 984 || ( 0 == nThisModelStep ) // the current button appears on all pages 985 ) 986 { 987 // -> it belongs to the same group 988 aCurrentGroup->push_back( *pControlModels ); 989 // state still is eExpandingGroup - we're looking for further elements 990 eState = eExpandingGroup; 991 992 #if OSL_DEBUG_LEVEL > 1 993 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY ); 994 ::rtl::OUString sLabel; 995 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) ) 996 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel; 997 aCurrentGroupLabels.push_back( sLabel ); 998 #endif 999 continue; 1000 } 1001 1002 // it's a radio button, but on a different page 1003 // -> we open a new group for it 1004 1005 // close the old group 1006 aCurrentGroup = maGroups.end(); 1007 #if OSL_DEBUG_LEVEL > 1 1008 aCurrentGroupLabels.clear(); 1009 #endif 1010 1011 // open a new group 1012 size_t nGroups = maGroups.size(); 1013 maGroups.resize( nGroups + 1 ); 1014 aCurrentGroup = maGroups.begin() + nGroups; 1015 // and add the (only, til now) member 1016 aCurrentGroup->push_back( *pControlModels ); 1017 1018 nCurrentGroupStep = nThisModelStep; 1019 1020 // state is the same: we still are looking for further elements of the current group 1021 eState = eExpandingGroup; 1022 #if OSL_DEBUG_LEVEL > 1 1023 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY ); 1024 ::rtl::OUString sLabel; 1025 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) ) 1026 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel; 1027 aCurrentGroupLabels.push_back( sLabel ); 1028 #endif 1029 } 1030 break; 1031 } 1032 } 1033 1034 mbGroupsUpToDate = sal_True; 1035 } 1036 1037 // ---------------------------------------------------------------------------- 1038 void SAL_CALL ControlModelContainerBase::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException) 1039 { 1040 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1041 1042 DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ), 1043 "UnoControlDialogModel::propertyChange: not listening for this property!" ); 1044 1045 // the accessor for the changed element 1046 ::rtl::OUString sAccessor; 1047 UnoControlModelHolderList::const_iterator aPos = 1048 ::std::find_if( 1049 maModels.begin(), maModels.end(), 1050 CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) ) 1051 ); 1052 OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" ); 1053 if ( maModels.end() != aPos ) 1054 sAccessor = aPos->second; 1055 1056 // our groups are not up-to-date 1057 mbGroupsUpToDate = sal_False; 1058 1059 // notify 1060 implNotifyTabModelChange( sAccessor ); 1061 } 1062 1063 // ---------------------------------------------------------------------------- 1064 void SAL_CALL ControlModelContainerBase::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException) 1065 { 1066 } 1067 1068 // ---------------------------------------------------------------------------- 1069 void ControlModelContainerBase::startControlListening( const Reference< XControlModel >& _rxChildModel ) 1070 { 1071 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1072 1073 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY ); 1074 Reference< XPropertySetInfo > xPSI; 1075 if ( xModelProps.is() ) 1076 xPSI = xModelProps->getPropertySetInfo(); 1077 1078 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) 1079 xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this ); 1080 } 1081 1082 // ---------------------------------------------------------------------------- 1083 void ControlModelContainerBase::stopControlListening( const Reference< XControlModel >& _rxChildModel ) 1084 { 1085 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1086 1087 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY ); 1088 Reference< XPropertySetInfo > xPSI; 1089 if ( xModelProps.is() ) 1090 xPSI = xModelProps->getPropertySetInfo(); 1091 1092 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) 1093 xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this ); 1094 } 1095 1096 // ============================================================================ 1097 // = class ResourceListener 1098 // ============================================================================ 1099 1100 ResourceListener::ResourceListener( 1101 const Reference< util::XModifyListener >& rListener ) : 1102 OWeakObject(), 1103 m_xListener( rListener ), 1104 m_bListening( false ) 1105 { 1106 } 1107 1108 ResourceListener::~ResourceListener() 1109 { 1110 } 1111 1112 // XInterface 1113 Any SAL_CALL ResourceListener::queryInterface( const Type& rType ) 1114 throw ( RuntimeException ) 1115 { 1116 Any a = ::cppu::queryInterface( 1117 rType , 1118 static_cast< XModifyListener* >( this ), 1119 static_cast< XEventListener* >( this )); 1120 1121 if ( a.hasValue() ) 1122 return a; 1123 1124 return OWeakObject::queryInterface( rType ); 1125 } 1126 1127 void SAL_CALL ResourceListener::acquire() throw () 1128 { 1129 OWeakObject::acquire(); 1130 } 1131 1132 void SAL_CALL ResourceListener::release() throw () 1133 { 1134 OWeakObject::release(); 1135 } 1136 1137 void ResourceListener::startListening( 1138 const Reference< resource::XStringResourceResolver >& rResource ) 1139 { 1140 Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY ); 1141 1142 { 1143 // --- SAFE --- 1144 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1145 bool bListening( m_bListening ); 1146 bool bResourceSet( m_xResource.is() ); 1147 aGuard.clear(); 1148 // --- SAFE --- 1149 1150 if ( bListening && bResourceSet ) 1151 stopListening(); 1152 1153 // --- SAFE --- 1154 aGuard.reset(); 1155 m_xResource = rResource; 1156 aGuard.clear(); 1157 // --- SAFE --- 1158 } 1159 1160 Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY ); 1161 if ( xModifyBroadcaster.is() ) 1162 { 1163 try 1164 { 1165 xModifyBroadcaster->addModifyListener( xThis ); 1166 1167 // --- SAFE --- 1168 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1169 m_bListening = true; 1170 // --- SAFE --- 1171 } 1172 catch ( RuntimeException& ) 1173 { 1174 throw; 1175 } 1176 catch ( Exception& ) 1177 { 1178 } 1179 } 1180 } 1181 1182 void ResourceListener::stopListening() 1183 { 1184 Reference< util::XModifyBroadcaster > xModifyBroadcaster; 1185 1186 // --- SAFE --- 1187 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1188 if ( m_bListening && m_xResource.is() ) 1189 xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY ); 1190 aGuard.clear(); 1191 // --- SAFE --- 1192 1193 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 1194 if ( xModifyBroadcaster.is() ) 1195 { 1196 try 1197 { 1198 // --- SAFE --- 1199 aGuard.reset(); 1200 m_bListening = false; 1201 m_xResource.clear(); 1202 aGuard.clear(); 1203 // --- SAFE --- 1204 1205 xModifyBroadcaster->removeModifyListener( xThis ); 1206 } 1207 catch ( RuntimeException& ) 1208 { 1209 throw; 1210 } 1211 catch ( Exception& ) 1212 { 1213 } 1214 } 1215 } 1216 1217 // XModifyListener 1218 void SAL_CALL ResourceListener::modified( 1219 const lang::EventObject& aEvent ) 1220 throw ( RuntimeException ) 1221 { 1222 Reference< util::XModifyListener > xListener; 1223 1224 // --- SAFE --- 1225 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1226 xListener = m_xListener; 1227 aGuard.clear(); 1228 // --- SAFE --- 1229 1230 if ( xListener.is() ) 1231 { 1232 try 1233 { 1234 xListener->modified( aEvent ); 1235 } 1236 catch ( RuntimeException& ) 1237 { 1238 throw; 1239 } 1240 catch ( Exception& ) 1241 { 1242 } 1243 } 1244 } 1245 1246 // XEventListener 1247 void SAL_CALL ResourceListener::disposing( 1248 const EventObject& Source ) 1249 throw ( RuntimeException ) 1250 { 1251 Reference< lang::XEventListener > xListener; 1252 Reference< resource::XStringResourceResolver > xResource; 1253 1254 // --- SAFE --- 1255 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1256 Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY ); 1257 Reference< XInterface > xIfacList( m_xListener, UNO_QUERY ); 1258 aGuard.clear(); 1259 // --- SAFE --- 1260 1261 if ( Source.Source == xIfacRes ) 1262 { 1263 // --- SAFE --- 1264 aGuard.reset(); 1265 m_bListening = false; 1266 xResource = m_xResource; 1267 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY ); 1268 m_xResource.clear(); 1269 aGuard.clear(); 1270 // --- SAFE --- 1271 1272 if ( xListener.is() ) 1273 { 1274 try 1275 { 1276 xListener->disposing( Source ); 1277 } 1278 catch ( RuntimeException& ) 1279 { 1280 throw; 1281 } 1282 catch ( Exception& ) 1283 { 1284 } 1285 } 1286 } 1287 else if ( Source.Source == xIfacList ) 1288 { 1289 // --- SAFE --- 1290 aGuard.reset(); 1291 m_bListening = false; 1292 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY ); 1293 xResource = m_xResource; 1294 m_xResource.clear(); 1295 m_xListener.clear(); 1296 aGuard.clear(); 1297 // --- SAFE --- 1298 1299 // Remove ourself as listener from resource resolver 1300 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY ); 1301 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 1302 if ( xModifyBroadcaster.is() ) 1303 { 1304 try 1305 { 1306 xModifyBroadcaster->removeModifyListener( xThis ); 1307 } 1308 catch ( RuntimeException& ) 1309 { 1310 throw; 1311 } 1312 catch ( Exception& ) 1313 { 1314 } 1315 } 1316 } 1317 } 1318 1319 //=============================================================== 1320 // ---------------------------------------------------- 1321 // class DialogContainerControl 1322 // ---------------------------------------------------- 1323 ControlContainerBase::ControlContainerBase( const Reference< XMultiServiceFactory >& i_factory ) 1324 :ContainerControl_IBase( i_factory ) 1325 ,mbSizeModified(false) 1326 ,mbPosModified(false) 1327 { 1328 maComponentInfos.nWidth = 280; 1329 maComponentInfos.nHeight = 400; 1330 mxListener = new ResourceListener( Reference< util::XModifyListener >( 1331 static_cast< OWeakObject* >( this ), UNO_QUERY )); 1332 } 1333 1334 ControlContainerBase::~ControlContainerBase() 1335 { 1336 } 1337 1338 void ControlContainerBase::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) 1339 { 1340 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1341 UnoControlContainer::createPeer( rxToolkit, rParentPeer ); 1342 } 1343 1344 void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName ) 1345 { 1346 Reference< XPropertySet > xP( rxModel, UNO_QUERY ); 1347 1348 ::rtl::OUString aDefCtrl; 1349 xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl; 1350 Reference < XControl > xCtrl; 1351 maContext.createComponent( aDefCtrl, xCtrl ); 1352 1353 DBG_ASSERT( xCtrl.is(), "ControlContainerBase::ImplInsertControl: could not create the control!" ); 1354 if ( xCtrl.is() ) 1355 { 1356 xCtrl->setModel( rxModel ); 1357 addControl( rName, xCtrl ); 1358 // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model 1359 // (which we formerly did herein) 1360 // 08.01.2001 - 96008 - fs@openoffice.org 1361 1362 ImplSetPosSize( xCtrl ); 1363 } 1364 } 1365 1366 void ControlContainerBase::ImplRemoveControl( Reference< XControlModel >& rxModel ) 1367 { 1368 Sequence< Reference< XControl > > aControls = getControls(); 1369 Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel ); 1370 if ( xCtrl.is() ) 1371 { 1372 removeControl( xCtrl ); 1373 try 1374 { 1375 Reference< XComponent > const xControlComp( xCtrl, UNO_QUERY_THROW ); 1376 xControlComp->dispose(); 1377 } 1378 catch( Exception const & ) 1379 { 1380 DBG_UNHANDLED_EXCEPTION(); 1381 } 1382 } 1383 } 1384 1385 void ControlContainerBase::ImplSetPosSize( Reference< XControl >& rxCtrl ) 1386 { 1387 Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY ); 1388 1389 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0; 1390 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX; 1391 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY; 1392 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth; 1393 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight; 1394 MapMode aMode( MAP_APPFONT ); 1395 OutputDevice*pOutDev = Application::GetDefaultDevice(); 1396 if ( pOutDev ) 1397 { 1398 ::Size aTmp( nX, nY ); 1399 aTmp = pOutDev->LogicToPixel( aTmp, aMode ); 1400 nX = aTmp.Width(); 1401 nY = aTmp.Height(); 1402 aTmp = ::Size( nWidth, nHeight ); 1403 aTmp = pOutDev->LogicToPixel( aTmp, aMode ); 1404 nWidth = aTmp.Width(); 1405 nHeight = aTmp.Height(); 1406 } 1407 else 1408 { 1409 Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True ); 1410 Reference< XDevice > xD( xPeer, UNO_QUERY ); 1411 1412 SimpleFontMetric aFM; 1413 FontDescriptor aFD; 1414 Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) ); 1415 aVal >>= aFD; 1416 if ( aFD.StyleName.getLength() ) 1417 { 1418 Reference< XFont > xFont = xD->getFont( aFD ); 1419 aFM = xFont->getFontMetric(); 1420 } 1421 else 1422 { 1423 Reference< XGraphics > xG = xD->createGraphics(); 1424 aFM = xG->getFontMetric(); 1425 } 1426 1427 sal_Int16 nH = aFM.Ascent + aFM.Descent; 1428 sal_Int16 nW = nH/2; // calculate avarage width?! 1429 1430 nX *= nW; 1431 nX /= 4; 1432 nWidth *= nW; 1433 nWidth /= 4; 1434 nY *= nH; 1435 nY /= 8; 1436 nHeight *= nH; 1437 nHeight /= 8; 1438 } 1439 Reference < XWindow > xW( rxCtrl, UNO_QUERY ); 1440 xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE ); 1441 } 1442 1443 void ControlContainerBase::dispose() throw(RuntimeException) 1444 { 1445 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1446 1447 EventObject aEvt; 1448 aEvt.Source = static_cast< ::cppu::OWeakObject* >( this ); 1449 // Notify our listener helper about dispose 1450 // --- SAFE --- 1451 ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() ); 1452 Reference< XEventListener > xListener( mxListener, UNO_QUERY ); 1453 mxListener.clear(); 1454 aGuard.clear(); 1455 // --- SAFE --- 1456 1457 if ( xListener.is() ) 1458 xListener->disposing( aEvt ); 1459 UnoControlContainer::dispose(); 1460 } 1461 1462 void SAL_CALL ControlContainerBase::disposing( 1463 const EventObject& Source ) 1464 throw(RuntimeException) 1465 { 1466 UnoControlContainer::disposing( Source ); 1467 } 1468 1469 sal_Bool ControlContainerBase::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException) 1470 { 1471 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1472 1473 // destroy the old tab controller, if existent 1474 if ( mxTabController.is() ) 1475 { 1476 mxTabController->setModel( NULL ); // just to be sure, should not be necessary 1477 removeTabController( mxTabController ); 1478 ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary 1479 mxTabController.clear(); 1480 } 1481 1482 if ( getModel().is() ) 1483 { 1484 Sequence< Reference< XControl > > aControls = getControls(); 1485 const Reference< XControl >* pCtrls = aControls.getConstArray(); 1486 const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength(); 1487 1488 for ( ; pCtrls < pCtrlsEnd; ++pCtrls ) 1489 removeControl( *pCtrls ); 1490 // will implicitly call removingControl, which will remove the PropertyChangeListener 1491 // (which we formerly did herein) 1492 // 08.01.2001 - 96008 - fs@openoffice.org 1493 1494 Reference< XContainer > xC( getModel(), UNO_QUERY ); 1495 if ( xC.is() ) 1496 xC->removeContainerListener( this ); 1497 1498 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY ); 1499 if ( xChangeNotifier.is() ) 1500 xChangeNotifier->removeChangesListener( this ); 1501 } 1502 1503 sal_Bool bRet = UnoControl::setModel( rxModel ); 1504 1505 if ( getModel().is() ) 1506 { 1507 Reference< XNameAccess > xNA( getModel(), UNO_QUERY ); 1508 if ( xNA.is() ) 1509 { 1510 Sequence< ::rtl::OUString > aNames = xNA->getElementNames(); 1511 const ::rtl::OUString* pNames = aNames.getConstArray(); 1512 sal_uInt32 nCtrls = aNames.getLength(); 1513 1514 Reference< XControlModel > xCtrlModel; 1515 for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames ) 1516 { 1517 xNA->getByName( *pNames ) >>= xCtrlModel; 1518 ImplInsertControl( xCtrlModel, *pNames ); 1519 } 1520 } 1521 1522 Reference< XContainer > xC( getModel(), UNO_QUERY ); 1523 if ( xC.is() ) 1524 xC->addContainerListener( this ); 1525 1526 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY ); 1527 if ( xChangeNotifier.is() ) 1528 xChangeNotifier->addChangesListener( this ); 1529 } 1530 1531 Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY ); 1532 if ( xTabbing.is() ) 1533 { 1534 mxTabController = new StdTabController; 1535 mxTabController->setModel( xTabbing ); 1536 addTabController( mxTabController ); 1537 } 1538 ImplStartListingForResourceEvents(); 1539 1540 return bRet; 1541 } 1542 void ControlContainerBase::setDesignMode( sal_Bool bOn ) throw(RuntimeException) 1543 { 1544 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1545 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 1546 1547 UnoControl::setDesignMode( bOn ); 1548 1549 Sequence< Reference< XControl > > xCtrls = getControls(); 1550 sal_Int32 nControls = xCtrls.getLength(); 1551 Reference< XControl >* pControls = xCtrls.getArray(); 1552 for ( sal_Int32 n = 0; n < nControls; n++ ) 1553 pControls[n]->setDesignMode( bOn ); 1554 1555 // #109067# in design mode the tab controller is not notified about 1556 // tab index changes, therefore the tab order must be activated 1557 // when switching from design mode to live mode 1558 if ( mxTabController.is() && !bOn ) 1559 mxTabController->activateTabOrder(); 1560 } 1561 1562 void ControlContainerBase::elementInserted( const ContainerEvent& Event ) throw(RuntimeException) 1563 { 1564 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1565 1566 Reference< XControlModel > xModel; 1567 ::rtl::OUString aName; 1568 1569 Event.Accessor >>= aName; 1570 Event.Element >>= xModel; 1571 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" ); 1572 try 1573 { 1574 ImplInsertControl( xModel, aName ); 1575 } 1576 catch ( const RuntimeException& e ) { throw; } 1577 catch( const Exception& ) 1578 { 1579 DBG_UNHANDLED_EXCEPTION(); 1580 } 1581 } 1582 1583 void ControlContainerBase::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException) 1584 { 1585 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1586 1587 Reference< XControlModel > xModel; 1588 Event.Element >>= xModel; 1589 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" ); 1590 try 1591 { 1592 ImplRemoveControl( xModel ); 1593 } 1594 catch ( const RuntimeException& e ) { throw; } 1595 catch( const Exception& ) 1596 { 1597 DBG_UNHANDLED_EXCEPTION(); 1598 } 1599 } 1600 1601 void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException) 1602 { 1603 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1604 1605 Reference< XControlModel > xModel; 1606 Event.ReplacedElement >>= xModel; 1607 try 1608 { 1609 OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" ); 1610 if ( xModel.is() ) 1611 ImplRemoveControl( xModel ); 1612 } 1613 catch ( const RuntimeException& e ) { throw; } 1614 catch( const Exception& ) 1615 { 1616 DBG_UNHANDLED_EXCEPTION(); 1617 } 1618 1619 ::rtl::OUString aName; 1620 Event.Accessor >>= aName; 1621 Event.Element >>= xModel; 1622 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" ); 1623 try 1624 { 1625 ImplInsertControl( xModel, aName ); 1626 } 1627 catch ( const RuntimeException& e ) { throw; } 1628 catch( const Exception& ) 1629 { 1630 DBG_UNHANDLED_EXCEPTION(); 1631 } 1632 } 1633 1634 // XPropertiesChangeListener 1635 void ControlContainerBase::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException) 1636 { 1637 if( !isDesignMode() && !mbCreatingCompatiblePeer ) 1638 { 1639 ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ); 1640 ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ); 1641 ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ); 1642 ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ); 1643 1644 sal_Int32 nLen = rEvents.getLength(); 1645 for( sal_Int32 i = 0; i < nLen; i++ ) 1646 { 1647 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i]; 1648 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY ); 1649 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get(); 1650 if ( ( rEvt.PropertyName == s1 ) || 1651 ( rEvt.PropertyName == s2 ) || 1652 ( rEvt.PropertyName == s3 ) || 1653 ( rEvt.PropertyName == s4 ) ) 1654 { 1655 if ( bOwnModel ) 1656 { 1657 if ( !mbPosModified && !mbSizeModified ) 1658 { 1659 // Don't set new pos/size if we get new values from window listener 1660 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY ); 1661 ImplSetPosSize( xThis ); 1662 } 1663 } 1664 else 1665 { 1666 Sequence<Reference<XControl> > aControlSequence(getControls()); 1667 Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) ); 1668 ImplSetPosSize( aControlRef ); 1669 } 1670 break; 1671 } 1672 } 1673 } 1674 1675 UnoControlContainer::ImplModelPropertiesChanged( rEvents ); 1676 } 1677 1678 void ControlContainerBase::addingControl( const Reference< XControl >& _rxControl ) 1679 { 1680 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1681 UnoControlContainer::addingControl( _rxControl ); 1682 1683 if ( _rxControl.is() ) 1684 { 1685 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY ); 1686 if ( xProps.is() ) 1687 { 1688 Sequence< ::rtl::OUString > aNames( 4 ); 1689 ::rtl::OUString* pNames = aNames.getArray(); 1690 *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" ); 1691 *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" ); 1692 *pNames++ = ::rtl::OUString::createFromAscii( "Width" ); 1693 *pNames++ = ::rtl::OUString::createFromAscii( "Height" ); 1694 1695 xProps->addPropertiesChangeListener( aNames, this ); 1696 } 1697 } 1698 } 1699 1700 void ControlContainerBase::removingControl( const Reference< XControl >& _rxControl ) 1701 { 1702 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1703 UnoControlContainer::removingControl( _rxControl ); 1704 1705 if ( _rxControl.is() ) 1706 { 1707 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY ); 1708 if ( xProps.is() ) 1709 xProps->removePropertiesChangeListener( this ); 1710 } 1711 1712 } 1713 1714 void SAL_CALL ControlContainerBase::changesOccurred( const ChangesEvent& ) throw (RuntimeException) 1715 { 1716 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1717 // a tab controller model may have changed 1718 1719 // #109067# in design mode don't notify the tab controller 1720 // about tab index changes 1721 if ( mxTabController.is() && !mbDesignMode ) 1722 mxTabController->activateTabOrder(); 1723 } 1724 void lcl_ApplyResolverToNestedContainees( const Reference< resource::XStringResourceResolver >& xStringResourceResolver, const Reference< XControlContainer >& xContainer ) 1725 { 1726 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); 1727 1728 Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver; 1729 1730 Sequence< rtl::OUString > aPropNames(1); 1731 aPropNames[0] = aPropName; 1732 1733 const Sequence< Reference< awt::XControl > > aSeq = xContainer->getControls(); 1734 for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ ) 1735 { 1736 Reference< XControl > xControl( aSeq[i] ); 1737 Reference< XPropertySet > xPropertySet; 1738 1739 if ( xControl.is() ) 1740 xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY ); 1741 1742 if ( !xPropertySet.is() ) 1743 continue; 1744 1745 try 1746 { 1747 Reference< resource::XStringResourceResolver > xCurrStringResourceResolver; 1748 Any aOldValue = xPropertySet->getPropertyValue( aPropName ); 1749 if ( ( aOldValue >>= xCurrStringResourceResolver ) 1750 && ( xStringResourceResolver == xCurrStringResourceResolver ) 1751 ) 1752 { 1753 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY ); 1754 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY ); 1755 xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener ); 1756 } 1757 else 1758 xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver ); 1759 } 1760 /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ... 1761 catch ( const Exception& ) 1762 { 1763 } 1764 1765 uno::Reference< XControlContainer > xNestedContainer( xControl, uno::UNO_QUERY ); 1766 if ( xNestedContainer.is() ) 1767 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, xNestedContainer ); 1768 1769 } 1770 1771 } 1772 void ControlContainerBase::ImplStartListingForResourceEvents() 1773 { 1774 Reference< resource::XStringResourceResolver > xStringResourceResolver; 1775 1776 ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver; 1777 1778 // Add our helper as listener to retrieve notifications about changes 1779 Reference< util::XModifyListener > rListener( mxListener ); 1780 ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() ); 1781 1782 // resource listener will stop listening if resolver reference is empty 1783 if ( pResourceListener ) 1784 pResourceListener->startListening( xStringResourceResolver ); 1785 ImplUpdateResourceResolver(); 1786 } 1787 1788 void ControlContainerBase::ImplUpdateResourceResolver() 1789 { 1790 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); 1791 Reference< resource::XStringResourceResolver > xStringResourceResolver; 1792 1793 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver; 1794 if ( !xStringResourceResolver.is() ) 1795 return; 1796 1797 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, this ); 1798 1799 // propagate resource resolver changes to language dependent props of the dialog 1800 Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY ); 1801 if ( xPropertySet.is() ) 1802 { 1803 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY ); 1804 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY ); 1805 xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener ); 1806 } 1807 } 1808 1809 1810 uno::Reference< graphic::XGraphic > ControlContainerBase::Impl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL ) 1811 { 1812 uno::Reference< graphic::XGraphic > xGraphic; 1813 if ( !_rURL.getLength() ) 1814 return xGraphic; 1815 1816 try 1817 { 1818 uno::Reference< graphic::XGraphicProvider > xProvider; 1819 if ( maContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) ) 1820 { 1821 uno::Sequence< beans::PropertyValue > aMediaProperties(1); 1822 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 1823 aMediaProperties[0].Value <<= _rURL; 1824 xGraphic = xProvider->queryGraphic( aMediaProperties ); 1825 } 1826 } 1827 catch( const Exception& ) 1828 { 1829 DBG_UNHANDLED_EXCEPTION(); 1830 } 1831 1832 return xGraphic; 1833 } 1834 //// ---------------------------------------------------- 1835 //// Helper Method to convert relative url to physical location 1836 //// ---------------------------------------------------- 1837 1838 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl ) 1839 { 1840 1841 ::rtl::OUString baseLocation; 1842 ::rtl::OUString url; 1843 1844 rbase >>= baseLocation; 1845 rUrl >>= url; 1846 1847 ::rtl::OUString absoluteURL( url ); 1848 if ( url.getLength() > 0 ) 1849 { 1850 INetURLObject urlObj(baseLocation); 1851 urlObj.removeSegment(); 1852 baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE ); 1853 1854 const INetURLObject protocolCheck( url ); 1855 const INetProtocol protocol = protocolCheck.GetProtocol(); 1856 if ( protocol == INET_PROT_NOT_VALID ) 1857 { 1858 ::rtl::OUString testAbsoluteURL; 1859 if ( ::osl::FileBase::E_None == ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, testAbsoluteURL ) ) 1860 absoluteURL = testAbsoluteURL; 1861 } 1862 } 1863 1864 return absoluteURL; 1865 } 1866 1867