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