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 { 225 } 226 227 ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel ) 228 : ControlModelContainer_IBase( rModel ) 229 , maContainerListeners( *this ) 230 , maChangeListeners ( GetMutex() ) 231 , mbGroupsUpToDate( sal_False ) 232 { 233 } 234 235 ControlModelContainerBase::~ControlModelContainerBase() 236 { 237 maModels.clear(); 238 mbGroupsUpToDate = sal_False; 239 } 240 241 Any ControlModelContainerBase::ImplGetDefaultValue( sal_uInt16 nPropId ) const 242 { 243 Any aAny; 244 245 switch ( nPropId ) 246 { 247 case BASEPROPERTY_DEFAULTCONTROL: 248 aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog ); 249 break; 250 default: 251 aAny = UnoControlModel::ImplGetDefaultValue( nPropId ); 252 } 253 254 return aAny; 255 } 256 257 ::cppu::IPropertyArrayHelper& ControlModelContainerBase::getInfoHelper() 258 { 259 static UnoPropertyArrayHelper* pHelper = NULL; 260 if ( !pHelper ) 261 { 262 Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); 263 pHelper = new UnoPropertyArrayHelper( aIDs ); 264 } 265 return *pHelper; 266 } 267 268 void SAL_CALL ControlModelContainerBase::dispose( ) throw(RuntimeException) 269 { 270 // ==================================================================== 271 // tell our listeners 272 { 273 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 274 275 EventObject aDisposeEvent; 276 aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) ); 277 278 maContainerListeners.disposeAndClear( aDisposeEvent ); 279 maChangeListeners.disposeAndClear( aDisposeEvent ); 280 } 281 282 // ==================================================================== 283 // call the base class 284 UnoControlModel::dispose(); 285 286 // ==================================================================== 287 // dispose our child models 288 // for this, collect the models (we collect them from maModels, and this is modified when disposing children) 289 ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() ); 290 291 ::std::transform( 292 maModels.begin(), maModels.end(), // source range 293 aChildModels.begin(), // target location 294 ::std::select1st< UnoControlModelHolder >( ) // operation to apply -> select the XControlModel part 295 ); 296 297 // now dispose 298 ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() ); 299 aChildModels.clear(); 300 301 mbGroupsUpToDate = sal_False; 302 } 303 304 // XMultiPropertySet 305 Reference< XPropertySetInfo > ControlModelContainerBase::getPropertySetInfo( ) throw(RuntimeException) 306 { 307 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 308 return xInfo; 309 } 310 void ControlModelContainerBase::Clone_Impl(ControlModelContainerBase& _rClone) const 311 { 312 // clone all children 313 ::std::for_each( 314 maModels.begin(), maModels.end(), 315 CloneControlModel( _rClone.maModels ) 316 ); 317 } 318 UnoControlModel* ControlModelContainerBase::Clone() const 319 { 320 // clone the container itself 321 ControlModelContainerBase* pClone = new ControlModelContainerBase( *this ); 322 Clone_Impl(*pClone); 323 324 return pClone; 325 } 326 327 ControlModelContainerBase::UnoControlModelHolderList::iterator ControlModelContainerBase::ImplFindElement( const ::rtl::OUString& rName ) 328 { 329 return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) ); 330 } 331 332 // ::XMultiServiceFactory 333 Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException) 334 { 335 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 336 337 OGeometryControlModel_Base* pNewModel = NULL; 338 339 const Reference< XMultiServiceFactory > xFactory( maContext.getLegacyServiceFactory() ); 340 if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 ) 341 pNewModel = new OGeometryControlModel< UnoControlEditModel >( xFactory ); 342 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 ) 343 pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >( xFactory ); 344 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 ) 345 pNewModel = new OGeometryControlModel< UnoControlFileControlModel >( xFactory ); 346 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 ) 347 pNewModel = new OGeometryControlModel< UnoControlButtonModel >( xFactory ); 348 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 ) 349 pNewModel = new OGeometryControlModel< UnoControlImageControlModel >( xFactory ); 350 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 ) 351 pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >( xFactory ); 352 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 ) 353 pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >( xFactory ); 354 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 ) 355 pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >( xFactory ); 356 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 ) 357 pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >( xFactory ); 358 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 ) 359 pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >( xFactory ); 360 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 ) 361 pNewModel = new OGeometryControlModel< UnoControlListBoxModel >( xFactory ); 362 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 ) 363 pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >( xFactory ); 364 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 ) 365 pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >( xFactory ); 366 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 ) 367 pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >( xFactory ); 368 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 ) 369 pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >( xFactory ); 370 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 ) 371 pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >( xFactory ); 372 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 ) 373 pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >( xFactory ); 374 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 ) 375 pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >( xFactory ); 376 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 ) 377 pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >( xFactory ); 378 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 ) 379 pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >( xFactory ); 380 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 ) 381 pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >( xFactory ); 382 else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 ) 383 pNewModel = new OGeometryControlModel< UnoTreeModel >( xFactory ); 384 else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 ) 385 pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory ); 386 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 ) 387 pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory ); 388 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 ) 389 pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory ); 390 391 if ( !pNewModel ) 392 { 393 if ( xFactory.is() ) 394 { 395 Reference< XInterface > xObject = xFactory->createInstance( aServiceSpecifier ); 396 Reference< XServiceInfo > xSI( xObject, UNO_QUERY ); 397 Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY ); 398 Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY ); 399 if ( xAgg.is() ) 400 { 401 if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) ) 402 { 403 // release 3 of the 4 references we have to the object 404 xAgg.clear(); 405 xSI.clear(); 406 xObject.clear(); 407 408 pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier ); 409 } 410 } 411 } 412 } 413 414 Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel; 415 return xNewModel; 416 } 417 418 Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments ) throw(Exception, RuntimeException) 419 { 420 const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) ); 421 const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY ); 422 ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance ); 423 xInstanceInit->initialize( i_arguments ); 424 return xInstance; 425 } 426 427 Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames() throw(RuntimeException) 428 { 429 static Sequence< ::rtl::OUString >* pNamesSeq = NULL; 430 if ( !pNamesSeq ) 431 { 432 pNamesSeq = new Sequence< ::rtl::OUString >( 24 ); 433 ::rtl::OUString* pNames = pNamesSeq->getArray(); 434 pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel ); 435 pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel ); 436 pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel ); 437 pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel ); 438 pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel ); 439 pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ); 440 pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel ); 441 pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel ); 442 pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel ); 443 pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel ); 444 pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel ); 445 pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel ); 446 pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel ); 447 pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel ); 448 pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel ); 449 pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel ); 450 pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel ); 451 pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel ); 452 pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel ); 453 pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel ); 454 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel ); 455 pNames[21] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel ); 456 pNames[22] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageContainerModel ); 457 pNames[23] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageModel ); 458 } 459 return *pNamesSeq; 460 } 461 462 // XContainer 463 void ControlModelContainerBase::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) 464 { 465 maContainerListeners.addInterface( l ); 466 } 467 468 void ControlModelContainerBase::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException) 469 { 470 maContainerListeners.removeInterface( l ); 471 } 472 473 // XElementAcces 474 Type ControlModelContainerBase::getElementType() throw(RuntimeException) 475 { 476 Type aType = getCppuType( ( Reference< XControlModel>* ) NULL ); 477 return aType; 478 } 479 480 sal_Bool ControlModelContainerBase::hasElements() throw(RuntimeException) 481 { 482 return !maModels.empty(); 483 } 484 485 // XNameContainer, XNameReplace, XNameAccess 486 void ControlModelContainerBase::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) 487 { 488 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 489 490 Reference< XControlModel > xNewModel; 491 aElement >>= xNewModel; 492 if ( !xNewModel.is() ) 493 lcl_throwIllegalArgumentException(); 494 495 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 496 if ( maModels.end() == aElementPos ) 497 lcl_throwNoSuchElementException(); 498 499 // stop listening at the old model 500 stopControlListening( aElementPos->first ); 501 Reference< XControlModel > xReplaced( aElementPos->first ); 502 // remember the new model, and start listening 503 aElementPos->first = xNewModel; 504 startControlListening( xNewModel ); 505 506 ContainerEvent aEvent; 507 aEvent.Source = *this; 508 aEvent.Element = aElement; 509 aEvent.ReplacedElement <<= xReplaced; 510 aEvent.Accessor <<= aName; 511 512 // notify the container listener 513 maContainerListeners.elementReplaced( aEvent ); 514 515 // our "tab controller model" has potentially changed -> notify this 516 implNotifyTabModelChange( aName ); 517 } 518 519 Any ControlModelContainerBase::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) 520 { 521 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 522 if ( maModels.end() == aElementPos ) 523 lcl_throwNoSuchElementException(); 524 525 return makeAny( aElementPos->first ); 526 } 527 528 Sequence< ::rtl::OUString > ControlModelContainerBase::getElementNames() throw(RuntimeException) 529 { 530 Sequence< ::rtl::OUString > aNames( maModels.size() ); 531 532 ::std::transform( 533 maModels.begin(), maModels.end(), // source range 534 aNames.getArray(), // target range 535 ::std::select2nd< UnoControlModelHolder >() // operator to apply: select the second element (the name) 536 ); 537 538 return aNames; 539 } 540 541 sal_Bool ControlModelContainerBase::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) 542 { 543 return maModels.end() != ImplFindElement( aName ); 544 } 545 546 void ControlModelContainerBase::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) 547 { 548 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 549 550 Reference< XControlModel > xM; 551 aElement >>= xM; 552 553 if ( xM.is() ) 554 { 555 Reference< beans::XPropertySet > xProps( xM, UNO_QUERY ); 556 if ( xProps.is() ) 557 { 558 559 Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo(); 560 561 ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL ); 562 if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty ) && ImplHasProperty(BASEPROPERTY_DIALOGSOURCEURL) ) 563 { 564 Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty ); 565 566 ::rtl::OUString absoluteUrl = 567 getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl ); 568 569 aUrl <<= absoluteUrl; 570 571 xProps.get()->setPropertyValue( sImageSourceProperty , aUrl ); 572 } 573 } 574 } 575 576 577 578 if ( !aName.getLength() || !xM.is() ) 579 lcl_throwIllegalArgumentException(); 580 581 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 582 if ( maModels.end() != aElementPos ) 583 lcl_throwElementExistException(); 584 585 maModels.push_back( UnoControlModelHolder( xM, aName ) ); 586 mbGroupsUpToDate = sal_False; 587 startControlListening( xM ); 588 589 ContainerEvent aEvent; 590 aEvent.Source = *this; 591 aEvent.Element <<= aElement; 592 aEvent.Accessor <<= aName; 593 maContainerListeners.elementInserted( aEvent ); 594 595 // our "tab controller model" has potentially changed -> notify this 596 implNotifyTabModelChange( aName ); 597 } 598 599 void ControlModelContainerBase::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) 600 { 601 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 602 603 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName ); 604 if ( maModels.end() == aElementPos ) 605 lcl_throwNoSuchElementException(); 606 607 ContainerEvent aEvent; 608 aEvent.Source = *this; 609 aEvent.Element <<= aElementPos->first; 610 aEvent.Accessor <<= aName; 611 maContainerListeners.elementRemoved( aEvent ); 612 613 stopControlListening( aElementPos->first ); 614 Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY ); 615 maModels.erase( aElementPos ); 616 mbGroupsUpToDate = sal_False; 617 618 if ( xPS.is() ) 619 try 620 { 621 xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) ); 622 } 623 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } 624 625 // our "tab controller model" has potentially changed -> notify this 626 implNotifyTabModelChange( aName ); 627 } 628 629 // ---------------------------------------------------------------------------- 630 sal_Bool SAL_CALL ControlModelContainerBase::getGroupControl( ) throw (RuntimeException) 631 { 632 return sal_True; 633 } 634 635 // ---------------------------------------------------------------------------- 636 void SAL_CALL ControlModelContainerBase::setGroupControl( sal_Bool ) throw (RuntimeException) 637 { 638 DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" ); 639 } 640 641 // ---------------------------------------------------------------------------- 642 void SAL_CALL ControlModelContainerBase::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException) 643 { 644 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 645 646 // set the tab indexes according to the order of models in the sequence 647 const Reference< XControlModel >* pControls = _rControls.getConstArray( ); 648 const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength(); 649 650 sal_Int16 nTabIndex = 1; 651 652 for ( ; pControls != pControlsEnd; ++pControls ) 653 { 654 // look up the control in our own structure. This is to prevent invalid arguments 655 UnoControlModelHolderList::const_iterator aPos = 656 ::std::find_if( 657 maModels.begin(), maModels.end(), 658 CompareControlModel( *pControls ) 659 ); 660 if ( maModels.end() != aPos ) 661 { 662 // okay, this is an existent model 663 // now set the TabIndex property (if applicable) 664 Reference< XPropertySet > xProps( aPos->first, UNO_QUERY ); 665 Reference< XPropertySetInfo > xPSI; 666 if ( xProps.is() ) 667 xPSI = xProps->getPropertySetInfo(); 668 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) 669 xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) ); 670 } 671 mbGroupsUpToDate = sal_False; 672 } 673 } 674 675 676 typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel; 677 678 // ---------------------------------------------------------------------------- 679 Sequence< Reference< XControlModel > > SAL_CALL ControlModelContainerBase::getControlModels( ) throw (RuntimeException) 680 { 681 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 682 683 MapIndexToModel aSortedModels; 684 // will be the sorted container of all models which have a tab index property 685 ::std::vector< Reference< XControlModel > > aUnindexedModels; 686 // will be the container of all models which do not have a tab index property 687 688 UnoControlModelHolderList::const_iterator aLoop = maModels.begin(); 689 for ( ; aLoop != maModels.end(); ++aLoop ) 690 { 691 Reference< XControlModel > xModel( aLoop->first ); 692 693 // see if the model has a TabIndex property 694 Reference< XPropertySet > xControlProps( xModel, UNO_QUERY ); 695 Reference< XPropertySetInfo > xPSI; 696 if ( xControlProps.is() ) 697 xPSI = xControlProps->getPropertySetInfo( ); 698 DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" ); 699 700 // has it? 701 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) ) 702 { // yes 703 sal_Int32 nTabIndex = -1; 704 xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex; 705 706 aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) ); 707 } 708 else if ( xModel.is() ) 709 // no, it hasn't, but we have to include it, anyway 710 aUnindexedModels.push_back( xModel ); 711 } 712 713 // okay, here we have a container of all our models, sorted by tab index, 714 // plus a container of "unindexed" models 715 // -> merge them 716 Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() ); 717 ::std::transform( 718 aSortedModels.begin(), aSortedModels.end(), 719 ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ), 720 ::std::select2nd< MapIndexToModel::value_type >( ) 721 ); 722 723 return aReturn; 724 } 725 726 // ---------------------------------------------------------------------------- 727 void SAL_CALL ControlModelContainerBase::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException) 728 { 729 // not supported. We have only implicit grouping: 730 // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on 731 // implementation details) that VCL does grouping according to the order of controls automatically 732 // At least VCL does this for all we're interested in: Radio buttons. 733 DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" ); 734 } 735 736 ////----- XInitialization ------------------------------------------------------------------- 737 void SAL_CALL ControlModelContainerBase::initialize (const Sequence<Any>& rArguments) throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException) 738 { 739 sal_Int16 nPageId = -1; 740 if ( rArguments.getLength() == 1 ) 741 { 742 if ( !( rArguments[ 0 ] >>= nPageId )) 743 throw lang::IllegalArgumentException(); 744 m_nTabPageId = nPageId; 745 } 746 else 747 m_nTabPageId = -1; 748 } 749 ::sal_Int16 SAL_CALL ControlModelContainerBase::getTabPageID() throw (::com::sun::star::uno::RuntimeException) 750 { 751 return m_nTabPageId; 752 } 753 ::sal_Bool SAL_CALL ControlModelContainerBase::getEnabled() throw (::com::sun::star::uno::RuntimeException) 754 { 755 return m_bEnabled; 756 } 757 void SAL_CALL ControlModelContainerBase::setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException) 758 { 759 m_bEnabled = _enabled; 760 } 761 ::rtl::OUString SAL_CALL ControlModelContainerBase::getTitle() throw (::com::sun::star::uno::RuntimeException) 762 { 763 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 764 Reference<XPropertySet> xThis(*this,UNO_QUERY); 765 ::rtl::OUString sTitle; 766 xThis->getPropertyValue(GetPropertyName(BASEPROPERTY_TITLE)) >>= sTitle; 767 return sTitle; 768 //return m_sTitle; 769 } 770 void SAL_CALL ControlModelContainerBase::setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException) 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() throw (::com::sun::star::uno::RuntimeException) 777 { 778 return m_sImageURL; 779 } 780 void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException) 781 { 782 m_sImageURL = _imageurl; 783 } 784 ::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip() throw (::com::sun::star::uno::RuntimeException) 785 { 786 return m_sTooltip; 787 } 788 void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException) 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( ) throw (RuntimeException) 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 ) throw (RuntimeException) 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 ) throw (RuntimeException) 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 ) throw (RuntimeException) 864 { 865 maChangeListeners.addInterface( _rxListener ); 866 } 867 868 // ---------------------------------------------------------------------------- 869 void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException) 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 ) throw (RuntimeException) 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*/ ) throw (RuntimeException) 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 throw ( RuntimeException ) 1111 { 1112 Any a = ::cppu::queryInterface( 1113 rType , 1114 static_cast< XModifyListener* >( this ), 1115 static_cast< XEventListener* >( this )); 1116 1117 if ( a.hasValue() ) 1118 return a; 1119 1120 return OWeakObject::queryInterface( rType ); 1121 } 1122 1123 void SAL_CALL ResourceListener::acquire() throw () 1124 { 1125 OWeakObject::acquire(); 1126 } 1127 1128 void SAL_CALL ResourceListener::release() throw () 1129 { 1130 OWeakObject::release(); 1131 } 1132 1133 void ResourceListener::startListening( 1134 const Reference< resource::XStringResourceResolver >& rResource ) 1135 { 1136 Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY ); 1137 1138 { 1139 // --- SAFE --- 1140 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1141 bool bListening( m_bListening ); 1142 bool bResourceSet( m_xResource.is() ); 1143 aGuard.clear(); 1144 // --- SAFE --- 1145 1146 if ( bListening && bResourceSet ) 1147 stopListening(); 1148 1149 // --- SAFE --- 1150 aGuard.reset(); 1151 m_xResource = rResource; 1152 aGuard.clear(); 1153 // --- SAFE --- 1154 } 1155 1156 Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY ); 1157 if ( xModifyBroadcaster.is() ) 1158 { 1159 try 1160 { 1161 xModifyBroadcaster->addModifyListener( xThis ); 1162 1163 // --- SAFE --- 1164 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1165 m_bListening = true; 1166 // --- SAFE --- 1167 } 1168 catch ( RuntimeException& ) 1169 { 1170 throw; 1171 } 1172 catch ( Exception& ) 1173 { 1174 } 1175 } 1176 } 1177 1178 void ResourceListener::stopListening() 1179 { 1180 Reference< util::XModifyBroadcaster > xModifyBroadcaster; 1181 1182 // --- SAFE --- 1183 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1184 if ( m_bListening && m_xResource.is() ) 1185 xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY ); 1186 aGuard.clear(); 1187 // --- SAFE --- 1188 1189 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 1190 if ( xModifyBroadcaster.is() ) 1191 { 1192 try 1193 { 1194 // --- SAFE --- 1195 aGuard.reset(); 1196 m_bListening = false; 1197 m_xResource.clear(); 1198 aGuard.clear(); 1199 // --- SAFE --- 1200 1201 xModifyBroadcaster->removeModifyListener( xThis ); 1202 } 1203 catch ( RuntimeException& ) 1204 { 1205 throw; 1206 } 1207 catch ( Exception& ) 1208 { 1209 } 1210 } 1211 } 1212 1213 // XModifyListener 1214 void SAL_CALL ResourceListener::modified( 1215 const lang::EventObject& aEvent ) 1216 throw ( RuntimeException ) 1217 { 1218 Reference< util::XModifyListener > xListener; 1219 1220 // --- SAFE --- 1221 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1222 xListener = m_xListener; 1223 aGuard.clear(); 1224 // --- SAFE --- 1225 1226 if ( xListener.is() ) 1227 { 1228 try 1229 { 1230 xListener->modified( aEvent ); 1231 } 1232 catch ( RuntimeException& ) 1233 { 1234 throw; 1235 } 1236 catch ( Exception& ) 1237 { 1238 } 1239 } 1240 } 1241 1242 // XEventListener 1243 void SAL_CALL ResourceListener::disposing( 1244 const EventObject& Source ) 1245 throw ( RuntimeException ) 1246 { 1247 Reference< lang::XEventListener > xListener; 1248 Reference< resource::XStringResourceResolver > xResource; 1249 1250 // --- SAFE --- 1251 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex ); 1252 Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY ); 1253 Reference< XInterface > xIfacList( m_xListener, UNO_QUERY ); 1254 aGuard.clear(); 1255 // --- SAFE --- 1256 1257 if ( Source.Source == xIfacRes ) 1258 { 1259 // --- SAFE --- 1260 aGuard.reset(); 1261 m_bListening = false; 1262 xResource = m_xResource; 1263 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY ); 1264 m_xResource.clear(); 1265 aGuard.clear(); 1266 // --- SAFE --- 1267 1268 if ( xListener.is() ) 1269 { 1270 try 1271 { 1272 xListener->disposing( Source ); 1273 } 1274 catch ( RuntimeException& ) 1275 { 1276 throw; 1277 } 1278 catch ( Exception& ) 1279 { 1280 } 1281 } 1282 } 1283 else if ( Source.Source == xIfacList ) 1284 { 1285 // --- SAFE --- 1286 aGuard.reset(); 1287 m_bListening = false; 1288 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY ); 1289 xResource = m_xResource; 1290 m_xResource.clear(); 1291 m_xListener.clear(); 1292 aGuard.clear(); 1293 // --- SAFE --- 1294 1295 // Remove ourself as listener from resource resolver 1296 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY ); 1297 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 1298 if ( xModifyBroadcaster.is() ) 1299 { 1300 try 1301 { 1302 xModifyBroadcaster->removeModifyListener( xThis ); 1303 } 1304 catch ( RuntimeException& ) 1305 { 1306 throw; 1307 } 1308 catch ( Exception& ) 1309 { 1310 } 1311 } 1312 } 1313 } 1314 1315 //=============================================================== 1316 // ---------------------------------------------------- 1317 // class DialogContainerControl 1318 // ---------------------------------------------------- 1319 ControlContainerBase::ControlContainerBase( const Reference< XMultiServiceFactory >& i_factory ) 1320 :ContainerControl_IBase( i_factory ) 1321 ,mbSizeModified(false) 1322 ,mbPosModified(false) 1323 { 1324 maComponentInfos.nWidth = 280; 1325 maComponentInfos.nHeight = 400; 1326 mxListener = new ResourceListener( Reference< util::XModifyListener >( 1327 static_cast< OWeakObject* >( this ), UNO_QUERY )); 1328 } 1329 1330 ControlContainerBase::~ControlContainerBase() 1331 { 1332 } 1333 1334 void ControlContainerBase::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) 1335 { 1336 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1337 UnoControlContainer::createPeer( rxToolkit, rParentPeer ); 1338 } 1339 1340 void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName ) 1341 { 1342 Reference< XPropertySet > xP( rxModel, UNO_QUERY ); 1343 1344 ::rtl::OUString aDefCtrl; 1345 xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl; 1346 Reference < XControl > xCtrl; 1347 maContext.createComponent( aDefCtrl, xCtrl ); 1348 1349 DBG_ASSERT( xCtrl.is(), "ControlContainerBase::ImplInsertControl: could not create the control!" ); 1350 if ( xCtrl.is() ) 1351 { 1352 xCtrl->setModel( rxModel ); 1353 addControl( rName, xCtrl ); 1354 // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model 1355 // (which we formerly did herein) 1356 // 08.01.2001 - 96008 - fs@openoffice.org 1357 1358 ImplSetPosSize( xCtrl ); 1359 } 1360 } 1361 1362 void ControlContainerBase::ImplRemoveControl( Reference< XControlModel >& rxModel ) 1363 { 1364 Sequence< Reference< XControl > > aControls = getControls(); 1365 Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel ); 1366 if ( xCtrl.is() ) 1367 { 1368 removeControl( xCtrl ); 1369 try 1370 { 1371 Reference< XComponent > const xControlComp( xCtrl, UNO_QUERY_THROW ); 1372 xControlComp->dispose(); 1373 } 1374 catch( Exception const & ) 1375 { 1376 DBG_UNHANDLED_EXCEPTION(); 1377 } 1378 } 1379 } 1380 1381 void ControlContainerBase::ImplSetPosSize( Reference< XControl >& rxCtrl ) 1382 { 1383 Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY ); 1384 1385 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0; 1386 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX; 1387 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY; 1388 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth; 1389 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight; 1390 MapMode aMode( MAP_APPFONT ); 1391 OutputDevice*pOutDev = Application::GetDefaultDevice(); 1392 if ( pOutDev ) 1393 { 1394 ::Size aTmp( nX, nY ); 1395 aTmp = pOutDev->LogicToPixel( aTmp, aMode ); 1396 nX = aTmp.Width(); 1397 nY = aTmp.Height(); 1398 aTmp = ::Size( nWidth, nHeight ); 1399 aTmp = pOutDev->LogicToPixel( aTmp, aMode ); 1400 nWidth = aTmp.Width(); 1401 nHeight = aTmp.Height(); 1402 } 1403 else 1404 { 1405 Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True ); 1406 Reference< XDevice > xD( xPeer, UNO_QUERY ); 1407 1408 SimpleFontMetric aFM; 1409 FontDescriptor aFD; 1410 Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) ); 1411 aVal >>= aFD; 1412 if ( aFD.StyleName.getLength() ) 1413 { 1414 Reference< XFont > xFont = xD->getFont( aFD ); 1415 aFM = xFont->getFontMetric(); 1416 } 1417 else 1418 { 1419 Reference< XGraphics > xG = xD->createGraphics(); 1420 aFM = xG->getFontMetric(); 1421 } 1422 1423 sal_Int16 nH = aFM.Ascent + aFM.Descent; 1424 sal_Int16 nW = nH/2; // calculate avarage width?! 1425 1426 nX *= nW; 1427 nX /= 4; 1428 nWidth *= nW; 1429 nWidth /= 4; 1430 nY *= nH; 1431 nY /= 8; 1432 nHeight *= nH; 1433 nHeight /= 8; 1434 } 1435 Reference < XWindow > xW( rxCtrl, UNO_QUERY ); 1436 xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE ); 1437 } 1438 1439 void ControlContainerBase::dispose() throw(RuntimeException) 1440 { 1441 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1442 1443 EventObject aEvt; 1444 aEvt.Source = static_cast< ::cppu::OWeakObject* >( this ); 1445 // Notify our listener helper about dispose 1446 // --- SAFE --- 1447 ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() ); 1448 Reference< XEventListener > xListener( mxListener, UNO_QUERY ); 1449 mxListener.clear(); 1450 aGuard.clear(); 1451 // --- SAFE --- 1452 1453 if ( xListener.is() ) 1454 xListener->disposing( aEvt ); 1455 UnoControlContainer::dispose(); 1456 } 1457 1458 void SAL_CALL ControlContainerBase::disposing( 1459 const EventObject& Source ) 1460 throw(RuntimeException) 1461 { 1462 UnoControlContainer::disposing( Source ); 1463 } 1464 1465 sal_Bool ControlContainerBase::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException) 1466 { 1467 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1468 1469 // destroy the old tab controller, if existent 1470 if ( mxTabController.is() ) 1471 { 1472 mxTabController->setModel( NULL ); // just to be sure, should not be necessary 1473 removeTabController( mxTabController ); 1474 ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary 1475 mxTabController.clear(); 1476 } 1477 1478 if ( getModel().is() ) 1479 { 1480 Sequence< Reference< XControl > > aControls = getControls(); 1481 const Reference< XControl >* pCtrls = aControls.getConstArray(); 1482 const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength(); 1483 1484 for ( ; pCtrls < pCtrlsEnd; ++pCtrls ) 1485 removeControl( *pCtrls ); 1486 // will implicitly call removingControl, which will remove the PropertyChangeListener 1487 // (which we formerly did herein) 1488 // 08.01.2001 - 96008 - fs@openoffice.org 1489 1490 Reference< XContainer > xC( getModel(), UNO_QUERY ); 1491 if ( xC.is() ) 1492 xC->removeContainerListener( this ); 1493 1494 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY ); 1495 if ( xChangeNotifier.is() ) 1496 xChangeNotifier->removeChangesListener( this ); 1497 } 1498 1499 sal_Bool bRet = UnoControl::setModel( rxModel ); 1500 1501 if ( getModel().is() ) 1502 { 1503 Reference< XNameAccess > xNA( getModel(), UNO_QUERY ); 1504 if ( xNA.is() ) 1505 { 1506 Sequence< ::rtl::OUString > aNames = xNA->getElementNames(); 1507 const ::rtl::OUString* pNames = aNames.getConstArray(); 1508 sal_uInt32 nCtrls = aNames.getLength(); 1509 1510 Reference< XControlModel > xCtrlModel; 1511 for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames ) 1512 { 1513 xNA->getByName( *pNames ) >>= xCtrlModel; 1514 ImplInsertControl( xCtrlModel, *pNames ); 1515 } 1516 } 1517 1518 Reference< XContainer > xC( getModel(), UNO_QUERY ); 1519 if ( xC.is() ) 1520 xC->addContainerListener( this ); 1521 1522 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY ); 1523 if ( xChangeNotifier.is() ) 1524 xChangeNotifier->addChangesListener( this ); 1525 } 1526 1527 Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY ); 1528 if ( xTabbing.is() ) 1529 { 1530 mxTabController = new StdTabController; 1531 mxTabController->setModel( xTabbing ); 1532 addTabController( mxTabController ); 1533 } 1534 ImplStartListingForResourceEvents(); 1535 1536 return bRet; 1537 } 1538 void ControlContainerBase::setDesignMode( sal_Bool bOn ) throw(RuntimeException) 1539 { 1540 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1541 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 1542 1543 UnoControl::setDesignMode( bOn ); 1544 1545 Sequence< Reference< XControl > > xCtrls = getControls(); 1546 sal_Int32 nControls = xCtrls.getLength(); 1547 Reference< XControl >* pControls = xCtrls.getArray(); 1548 for ( sal_Int32 n = 0; n < nControls; n++ ) 1549 pControls[n]->setDesignMode( bOn ); 1550 1551 // #109067# in design mode the tab controller is not notified about 1552 // tab index changes, therefore the tab order must be activated 1553 // when switching from design mode to live mode 1554 if ( mxTabController.is() && !bOn ) 1555 mxTabController->activateTabOrder(); 1556 } 1557 1558 void ControlContainerBase::elementInserted( const ContainerEvent& Event ) throw(RuntimeException) 1559 { 1560 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1561 1562 Reference< XControlModel > xModel; 1563 ::rtl::OUString aName; 1564 1565 Event.Accessor >>= aName; 1566 Event.Element >>= xModel; 1567 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" ); 1568 try 1569 { 1570 ImplInsertControl( xModel, aName ); 1571 } 1572 catch ( const RuntimeException& e ) { throw; } 1573 catch( const Exception& ) 1574 { 1575 DBG_UNHANDLED_EXCEPTION(); 1576 } 1577 } 1578 1579 void ControlContainerBase::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException) 1580 { 1581 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1582 1583 Reference< XControlModel > xModel; 1584 Event.Element >>= xModel; 1585 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" ); 1586 try 1587 { 1588 ImplRemoveControl( xModel ); 1589 } 1590 catch ( const RuntimeException& e ) { throw; } 1591 catch( const Exception& ) 1592 { 1593 DBG_UNHANDLED_EXCEPTION(); 1594 } 1595 } 1596 1597 void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException) 1598 { 1599 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1600 1601 Reference< XControlModel > xModel; 1602 Event.ReplacedElement >>= xModel; 1603 try 1604 { 1605 OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" ); 1606 if ( xModel.is() ) 1607 ImplRemoveControl( xModel ); 1608 } 1609 catch ( const RuntimeException& e ) { throw; } 1610 catch( const Exception& ) 1611 { 1612 DBG_UNHANDLED_EXCEPTION(); 1613 } 1614 1615 ::rtl::OUString aName; 1616 Event.Accessor >>= aName; 1617 Event.Element >>= xModel; 1618 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" ); 1619 try 1620 { 1621 ImplInsertControl( xModel, aName ); 1622 } 1623 catch ( const RuntimeException& e ) { throw; } 1624 catch( const Exception& ) 1625 { 1626 DBG_UNHANDLED_EXCEPTION(); 1627 } 1628 } 1629 1630 // XPropertiesChangeListener 1631 void ControlContainerBase::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException) 1632 { 1633 if( !isDesignMode() && !mbCreatingCompatiblePeer ) 1634 { 1635 ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ); 1636 ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ); 1637 ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ); 1638 ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ); 1639 1640 sal_Int32 nLen = rEvents.getLength(); 1641 for( sal_Int32 i = 0; i < nLen; i++ ) 1642 { 1643 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i]; 1644 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY ); 1645 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get(); 1646 if ( ( rEvt.PropertyName == s1 ) || 1647 ( rEvt.PropertyName == s2 ) || 1648 ( rEvt.PropertyName == s3 ) || 1649 ( rEvt.PropertyName == s4 ) ) 1650 { 1651 if ( bOwnModel ) 1652 { 1653 if ( !mbPosModified && !mbSizeModified ) 1654 { 1655 // Don't set new pos/size if we get new values from window listener 1656 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY ); 1657 ImplSetPosSize( xThis ); 1658 } 1659 } 1660 else 1661 { 1662 Sequence<Reference<XControl> > aControlSequence(getControls()); 1663 Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) ); 1664 ImplSetPosSize( aControlRef ); 1665 } 1666 break; 1667 } 1668 } 1669 } 1670 1671 UnoControlContainer::ImplModelPropertiesChanged( rEvents ); 1672 } 1673 1674 void ControlContainerBase::addingControl( const Reference< XControl >& _rxControl ) 1675 { 1676 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1677 UnoControlContainer::addingControl( _rxControl ); 1678 1679 if ( _rxControl.is() ) 1680 { 1681 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY ); 1682 if ( xProps.is() ) 1683 { 1684 Sequence< ::rtl::OUString > aNames( 4 ); 1685 ::rtl::OUString* pNames = aNames.getArray(); 1686 *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" ); 1687 *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" ); 1688 *pNames++ = ::rtl::OUString::createFromAscii( "Width" ); 1689 *pNames++ = ::rtl::OUString::createFromAscii( "Height" ); 1690 1691 xProps->addPropertiesChangeListener( aNames, this ); 1692 } 1693 } 1694 } 1695 1696 void ControlContainerBase::removingControl( const Reference< XControl >& _rxControl ) 1697 { 1698 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1699 UnoControlContainer::removingControl( _rxControl ); 1700 1701 if ( _rxControl.is() ) 1702 { 1703 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY ); 1704 if ( xProps.is() ) 1705 xProps->removePropertiesChangeListener( this ); 1706 } 1707 1708 } 1709 1710 void SAL_CALL ControlContainerBase::changesOccurred( const ChangesEvent& ) throw (RuntimeException) 1711 { 1712 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1713 // a tab controller model may have changed 1714 1715 // #109067# in design mode don't notify the tab controller 1716 // about tab index changes 1717 if ( mxTabController.is() && !mbDesignMode ) 1718 mxTabController->activateTabOrder(); 1719 } 1720 void lcl_ApplyResolverToNestedContainees( const Reference< resource::XStringResourceResolver >& xStringResourceResolver, const Reference< XControlContainer >& xContainer ) 1721 { 1722 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); 1723 1724 Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver; 1725 1726 Sequence< rtl::OUString > aPropNames(1); 1727 aPropNames[0] = aPropName; 1728 1729 const Sequence< Reference< awt::XControl > > aSeq = xContainer->getControls(); 1730 for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ ) 1731 { 1732 Reference< XControl > xControl( aSeq[i] ); 1733 Reference< XPropertySet > xPropertySet; 1734 1735 if ( xControl.is() ) 1736 xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY ); 1737 1738 if ( !xPropertySet.is() ) 1739 continue; 1740 1741 try 1742 { 1743 Reference< resource::XStringResourceResolver > xCurrStringResourceResolver; 1744 Any aOldValue = xPropertySet->getPropertyValue( aPropName ); 1745 if ( ( aOldValue >>= xCurrStringResourceResolver ) 1746 && ( xStringResourceResolver == xCurrStringResourceResolver ) 1747 ) 1748 { 1749 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY ); 1750 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY ); 1751 xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener ); 1752 } 1753 else 1754 xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver ); 1755 } 1756 /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ... 1757 catch ( const Exception& ) 1758 { 1759 } 1760 1761 uno::Reference< XControlContainer > xNestedContainer( xControl, uno::UNO_QUERY ); 1762 if ( xNestedContainer.is() ) 1763 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, xNestedContainer ); 1764 1765 } 1766 1767 } 1768 void ControlContainerBase::ImplStartListingForResourceEvents() 1769 { 1770 Reference< resource::XStringResourceResolver > xStringResourceResolver; 1771 1772 ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver; 1773 1774 // Add our helper as listener to retrieve notifications about changes 1775 Reference< util::XModifyListener > rListener( mxListener ); 1776 ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() ); 1777 1778 // resource listener will stop listening if resolver reference is empty 1779 if ( pResourceListener ) 1780 pResourceListener->startListening( xStringResourceResolver ); 1781 ImplUpdateResourceResolver(); 1782 } 1783 1784 void ControlContainerBase::ImplUpdateResourceResolver() 1785 { 1786 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER ); 1787 Reference< resource::XStringResourceResolver > xStringResourceResolver; 1788 1789 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver; 1790 if ( !xStringResourceResolver.is() ) 1791 return; 1792 1793 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, this ); 1794 1795 // propagate resource resolver changes to language dependent props of the dialog 1796 Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY ); 1797 if ( xPropertySet.is() ) 1798 { 1799 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY ); 1800 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY ); 1801 xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener ); 1802 } 1803 } 1804 1805 1806 uno::Reference< graphic::XGraphic > ControlContainerBase::Impl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL ) 1807 { 1808 uno::Reference< graphic::XGraphic > xGraphic; 1809 if ( !_rURL.getLength() ) 1810 return xGraphic; 1811 1812 try 1813 { 1814 uno::Reference< graphic::XGraphicProvider > xProvider; 1815 if ( maContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) ) 1816 { 1817 uno::Sequence< beans::PropertyValue > aMediaProperties(1); 1818 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 1819 aMediaProperties[0].Value <<= _rURL; 1820 xGraphic = xProvider->queryGraphic( aMediaProperties ); 1821 } 1822 } 1823 catch( const Exception& ) 1824 { 1825 DBG_UNHANDLED_EXCEPTION(); 1826 } 1827 1828 return xGraphic; 1829 } 1830 //// ---------------------------------------------------- 1831 //// Helper Method to convert relative url to physical location 1832 //// ---------------------------------------------------- 1833 1834 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl ) 1835 { 1836 1837 ::rtl::OUString baseLocation; 1838 ::rtl::OUString url; 1839 1840 rbase >>= baseLocation; 1841 rUrl >>= url; 1842 1843 ::rtl::OUString absoluteURL( url ); 1844 if ( url.getLength() > 0 ) 1845 { 1846 INetURLObject urlObj(baseLocation); 1847 urlObj.removeSegment(); 1848 baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE ); 1849 1850 const INetURLObject protocolCheck( url ); 1851 const INetProtocol protocol = protocolCheck.GetProtocol(); 1852 if ( protocol == INET_PROT_NOT_VALID ) 1853 { 1854 ::rtl::OUString testAbsoluteURL; 1855 if ( ::osl::FileBase::E_None == ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, testAbsoluteURL ) ) 1856 absoluteURL = testAbsoluteURL; 1857 } 1858 } 1859 1860 return absoluteURL; 1861 } 1862 1863