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_forms.hxx" 26 27 #ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTMODEL_CXX 28 #include "richtextmodel.hxx" 29 #endif 30 #include "richtextengine.hxx" 31 #include "richtextunowrapper.hxx" 32 33 /** === begin UNO includes === **/ 34 #include <com/sun/star/awt/LineEndFormat.hpp> 35 #include <com/sun/star/text/WritingMode2.hpp> 36 #include <com/sun/star/style/VerticalAlignment.hpp> 37 /** === end UNO includes === **/ 38 39 #include <cppuhelper/typeprovider.hxx> 40 #include <comphelper/guarding.hxx> 41 #include <toolkit/awt/vclxdevice.hxx> 42 #include <toolkit/helper/vclunohelper.hxx> 43 #include <editeng/editstat.hxx> 44 #include <vcl/outdev.hxx> 45 #include <vcl/svapp.hxx> 46 47 //-------------------------------------------------------------------------- 48 extern "C" void SAL_CALL createRegistryInfo_ORichTextModel() 49 { 50 static ::frm::OMultiInstanceAutoRegistration< ::frm::ORichTextModel > aRegisterModel; 51 } 52 53 //........................................................................ 54 namespace frm 55 { 56 //........................................................................ 57 58 using namespace ::com::sun::star::uno; 59 using namespace ::com::sun::star::awt; 60 using namespace ::com::sun::star::lang; 61 using namespace ::com::sun::star::io; 62 using namespace ::com::sun::star::beans; 63 using namespace ::com::sun::star::form; 64 using namespace ::com::sun::star::util; 65 using namespace ::com::sun::star::style; 66 67 namespace WritingMode2 = ::com::sun::star::text::WritingMode2; 68 69 //==================================================================== 70 //= ORichTextModel 71 //==================================================================== 72 DBG_NAME( ORichTextModel ) 73 //-------------------------------------------------------------------- 74 ORichTextModel::ORichTextModel( const Reference< XMultiServiceFactory >& _rxFactory ) 75 :OControlModel ( _rxFactory, ::rtl::OUString() ) 76 ,FontControlModel ( true ) 77 ,m_pEngine ( RichTextEngine::Create() ) 78 ,m_bSettingEngineText( false ) 79 ,m_aModifyListeners ( m_aMutex ) 80 { 81 DBG_CTOR( ORichTextModel, NULL ); 82 m_nClassId = FormComponentType::TEXTFIELD; 83 84 getPropertyDefaultByHandle( PROPERTY_ID_DEFAULTCONTROL ) >>= m_sDefaultControl; 85 getPropertyDefaultByHandle( PROPERTY_ID_BORDER ) >>= m_nBorder; 86 getPropertyDefaultByHandle( PROPERTY_ID_ENABLED ) >>= m_bEnabled; 87 getPropertyDefaultByHandle( PROPERTY_ID_ENABLEVISIBLE ) >>= m_bEnableVisible; 88 getPropertyDefaultByHandle( PROPERTY_ID_HARDLINEBREAKS ) >>= m_bHardLineBreaks; 89 getPropertyDefaultByHandle( PROPERTY_ID_HSCROLL ) >>= m_bHScroll; 90 getPropertyDefaultByHandle( PROPERTY_ID_VSCROLL ) >>= m_bVScroll; 91 getPropertyDefaultByHandle( PROPERTY_ID_READONLY ) >>= m_bReadonly; 92 getPropertyDefaultByHandle( PROPERTY_ID_PRINTABLE ) >>= m_bPrintable; 93 getPropertyDefaultByHandle( PROPERTY_ID_ALIGN ) >>= m_aAlign; 94 getPropertyDefaultByHandle( PROPERTY_ID_ECHO_CHAR ) >>= m_nEchoChar; 95 getPropertyDefaultByHandle( PROPERTY_ID_MAXTEXTLEN ) >>= m_nMaxTextLength; 96 getPropertyDefaultByHandle( PROPERTY_ID_MULTILINE ) >>= m_bMultiLine; 97 getPropertyDefaultByHandle( PROPERTY_ID_RICH_TEXT ) >>= m_bReallyActAsRichText; 98 getPropertyDefaultByHandle( PROPERTY_ID_HIDEINACTIVESELECTION ) >>= m_bHideInactiveSelection; 99 getPropertyDefaultByHandle( PROPERTY_ID_LINEEND_FORMAT ) >>= m_nLineEndFormat; 100 getPropertyDefaultByHandle( PROPERTY_ID_WRITING_MODE ) >>= m_nTextWritingMode; 101 getPropertyDefaultByHandle( PROPERTY_ID_CONTEXT_WRITING_MODE ) >>= m_nContextWritingMode; 102 103 implInit(); 104 } 105 106 //------------------------------------------------------------------ 107 ORichTextModel::ORichTextModel( const ORichTextModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory ) 108 :OControlModel ( _pOriginal, _rxFactory, sal_False ) 109 ,FontControlModel ( _pOriginal ) 110 ,m_pEngine ( NULL ) 111 ,m_bSettingEngineText( false ) 112 ,m_aModifyListeners ( m_aMutex ) 113 { 114 DBG_CTOR( ORichTextModel, NULL ); 115 116 m_aTabStop = _pOriginal->m_aTabStop; 117 m_aBackgroundColor = _pOriginal->m_aBackgroundColor; 118 m_aBorderColor = _pOriginal->m_aBorderColor; 119 m_aVerticalAlignment = _pOriginal->m_aVerticalAlignment; 120 m_sDefaultControl = _pOriginal->m_sDefaultControl; 121 m_sHelpText = _pOriginal->m_sHelpText; 122 m_sHelpURL = _pOriginal->m_sHelpURL; 123 m_nBorder = _pOriginal->m_nBorder; 124 m_bEnabled = _pOriginal->m_bEnabled; 125 m_bEnableVisible = _pOriginal->m_bEnableVisible; 126 m_bHardLineBreaks = _pOriginal->m_bHardLineBreaks; 127 m_bHScroll = _pOriginal->m_bHScroll; 128 m_bVScroll = _pOriginal->m_bVScroll; 129 m_bReadonly = _pOriginal->m_bReadonly; 130 m_bPrintable = _pOriginal->m_bPrintable; 131 m_bReallyActAsRichText = _pOriginal->m_bReallyActAsRichText; 132 m_bHideInactiveSelection = _pOriginal->m_bHideInactiveSelection; 133 m_nLineEndFormat = _pOriginal->m_nLineEndFormat; 134 m_nTextWritingMode = _pOriginal->m_nTextWritingMode; 135 m_nContextWritingMode = _pOriginal->m_nContextWritingMode; 136 137 m_aAlign = _pOriginal->m_aAlign; 138 m_nEchoChar = _pOriginal->m_nEchoChar; 139 m_nMaxTextLength = _pOriginal->m_nMaxTextLength; 140 m_bMultiLine = _pOriginal->m_bMultiLine; 141 142 m_pEngine.reset(_pOriginal->m_pEngine->Clone()); 143 m_sLastKnownEngineText = m_pEngine->GetText(); 144 145 implInit(); 146 } 147 148 //------------------------------------------------------------------ 149 void ORichTextModel::implInit() 150 { 151 OSL_ENSURE( m_pEngine.get(), "ORichTextModel::implInit: where's the engine?" ); 152 if ( m_pEngine.get() ) 153 { 154 m_pEngine->SetModifyHdl( LINK( this, ORichTextModel, OnEngineContentModified ) ); 155 156 sal_uLong nEngineControlWord = m_pEngine->GetControlWord(); 157 nEngineControlWord = nEngineControlWord & ~EE_CNTRL_AUTOPAGESIZE; 158 m_pEngine->SetControlWord( nEngineControlWord ); 159 160 VCLXDevice* pUnoRefDevice = new VCLXDevice; 161 pUnoRefDevice->SetOutputDevice( m_pEngine->GetRefDevice() ); 162 m_xReferenceDevice = pUnoRefDevice; 163 } 164 165 implDoAggregation(); 166 implRegisterProperties(); 167 } 168 169 //------------------------------------------------------------------ 170 void ORichTextModel::implDoAggregation() 171 { 172 increment( m_refCount ); 173 174 { 175 m_xAggregate = new ORichTextUnoWrapper( *m_pEngine, this ); 176 setAggregation( m_xAggregate ); 177 doSetDelegator(); 178 } 179 180 decrement( m_refCount ); 181 } 182 183 //------------------------------------------------------------------ 184 void ORichTextModel::implRegisterProperties() 185 { 186 REGISTER_PROP_2( DEFAULTCONTROL, m_sDefaultControl, BOUND, MAYBEDEFAULT ); 187 REGISTER_PROP_2( HELPTEXT, m_sHelpText, BOUND, MAYBEDEFAULT ); 188 REGISTER_PROP_2( HELPURL, m_sHelpURL, BOUND, MAYBEDEFAULT ); 189 REGISTER_PROP_2( ENABLED, m_bEnabled, BOUND, MAYBEDEFAULT ); 190 REGISTER_PROP_2( ENABLEVISIBLE, m_bEnableVisible, BOUND, MAYBEDEFAULT ); 191 REGISTER_PROP_2( BORDER, m_nBorder, BOUND, MAYBEDEFAULT ); 192 REGISTER_PROP_2( HARDLINEBREAKS, m_bHardLineBreaks, BOUND, MAYBEDEFAULT ); 193 REGISTER_PROP_2( HSCROLL, m_bHScroll, BOUND, MAYBEDEFAULT ); 194 REGISTER_PROP_2( VSCROLL, m_bVScroll, BOUND, MAYBEDEFAULT ); 195 REGISTER_PROP_2( READONLY, m_bReadonly, BOUND, MAYBEDEFAULT ); 196 REGISTER_PROP_2( PRINTABLE, m_bPrintable, BOUND, MAYBEDEFAULT ); 197 REGISTER_PROP_2( REFERENCE_DEVICE, m_xReferenceDevice, BOUND, TRANSIENT ); 198 REGISTER_PROP_2( RICH_TEXT, m_bReallyActAsRichText, BOUND, MAYBEDEFAULT ); 199 REGISTER_PROP_2( HIDEINACTIVESELECTION, m_bHideInactiveSelection, BOUND, MAYBEDEFAULT ); 200 201 REGISTER_VOID_PROP_2( TABSTOP, m_aTabStop, sal_Bool, BOUND, MAYBEDEFAULT ); 202 REGISTER_VOID_PROP_2( BACKGROUNDCOLOR, m_aBackgroundColor, sal_Int32, BOUND, MAYBEDEFAULT ); 203 REGISTER_VOID_PROP_2( BORDERCOLOR, m_aBorderColor, sal_Int32, BOUND, MAYBEDEFAULT ); 204 REGISTER_VOID_PROP_2( VERTICAL_ALIGN, m_aVerticalAlignment, VerticalAlignment, BOUND, MAYBEDEFAULT ); 205 206 // properties which exist only for compatibility with the css.swt.UnoControlEditModel, 207 // since we replace the default implementation for this service 208 REGISTER_PROP_2( ECHO_CHAR, m_nEchoChar, BOUND, MAYBEDEFAULT ); 209 REGISTER_PROP_2( MAXTEXTLEN, m_nMaxTextLength, BOUND, MAYBEDEFAULT ); 210 REGISTER_PROP_2( MULTILINE, m_bMultiLine, BOUND, MAYBEDEFAULT ); 211 REGISTER_PROP_2( TEXT, m_sLastKnownEngineText, BOUND, MAYBEDEFAULT ); 212 REGISTER_PROP_2( LINEEND_FORMAT, m_nLineEndFormat, BOUND, MAYBEDEFAULT ); 213 REGISTER_PROP_2( WRITING_MODE, m_nTextWritingMode, BOUND, MAYBEDEFAULT ); 214 REGISTER_PROP_3( CONTEXT_WRITING_MODE, m_nContextWritingMode, BOUND, MAYBEDEFAULT, TRANSIENT ); 215 216 REGISTER_VOID_PROP_2( ALIGN, m_aAlign, sal_Int16, BOUND, MAYBEDEFAULT ); 217 } 218 219 //-------------------------------------------------------------------- 220 ORichTextModel::~ORichTextModel( ) 221 { 222 if ( !OComponentHelper::rBHelper.bDisposed ) 223 { 224 acquire(); 225 dispose(); 226 } 227 if ( m_pEngine.get() ) 228 { 229 SfxItemPool* pPool = m_pEngine->getPool(); 230 m_pEngine.reset(); 231 SfxItemPool::Free(pPool); 232 } 233 234 235 DBG_DTOR( ORichTextModel, NULL ); 236 } 237 238 //------------------------------------------------------------------ 239 Any SAL_CALL ORichTextModel::queryAggregation( const Type& _rType ) throw ( RuntimeException ) 240 { 241 Any aReturn = ORichTextModel_BASE::queryInterface( _rType ); 242 243 if ( !aReturn.hasValue() ) 244 aReturn = OControlModel::queryAggregation( _rType ); 245 246 return aReturn; 247 } 248 249 //------------------------------------------------------------------ 250 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextModel, OControlModel, ORichTextModel_BASE ) 251 252 //-------------------------------------------------------------------- 253 IMPLEMENT_SERVICE_REGISTRATION_8( ORichTextModel, OControlModel, 254 FRM_SUN_COMPONENT_RICHTEXTCONTROL, 255 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextRange" ) ), 256 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CharacterProperties" ) ), 257 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.ParagraphProperties" ) ), 258 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CharacterPropertiesAsian" ) ), 259 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CharacterPropertiesComplex" ) ), 260 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.ParagraphPropertiesAsian" ) ), 261 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.ParagraphPropertiesComplex" ) ) 262 ) 263 264 //------------------------------------------------------------------------------ 265 IMPLEMENT_DEFAULT_CLONING( ORichTextModel ) 266 267 //------------------------------------------------------------------------------ 268 void SAL_CALL ORichTextModel::disposing() 269 { 270 m_aModifyListeners.disposeAndClear( EventObject( *this ) ); 271 OControlModel::disposing(); 272 } 273 274 //------------------------------------------------------------------------------ 275 namespace 276 { 277 void lcl_removeProperty( Sequence< Property >& _rSeq, const ::rtl::OUString& _rPropertyName ) 278 { 279 Property* pLoop = _rSeq.getArray(); 280 Property* pEnd = _rSeq.getArray() + _rSeq.getLength(); 281 while ( pLoop != pEnd ) 282 { 283 if ( pLoop->Name == _rPropertyName ) 284 { 285 ::std::copy( pLoop + 1, pEnd, pLoop ); 286 _rSeq.realloc( _rSeq.getLength() - 1 ); 287 break; 288 } 289 ++pLoop; 290 } 291 } 292 } 293 //------------------------------------------------------------------------------ 294 void ORichTextModel::describeFixedProperties( Sequence< Property >& _rProps ) const 295 { 296 BEGIN_DESCRIBE_PROPERTIES( 1, OControlModel ) 297 DECL_PROP2( TABINDEX, sal_Int16, BOUND, MAYBEDEFAULT ); 298 END_DESCRIBE_PROPERTIES(); 299 300 // properties which the OPropertyContainerHelper is responsible for 301 Sequence< Property > aContainedProperties; 302 describeProperties( aContainedProperties ); 303 304 // properties which the FontControlModel is responsible for 305 Sequence< Property > aFontProperties; 306 describeFontRelatedProperties( aFontProperties ); 307 308 _rProps = concatSequences( aContainedProperties, aFontProperties, _rProps ); 309 } 310 311 //------------------------------------------------------------------------------ 312 void ORichTextModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const 313 { 314 OControlModel::describeAggregateProperties( _rAggregateProps ); 315 316 // our aggregate (the SvxUnoText) declares a FontDescriptor property, as does 317 // our FormControlFont base class. We remove it from the base class' sequence 318 // here, and later on care for both instances being in sync 319 lcl_removeProperty( _rAggregateProps, PROPERTY_FONT ); 320 321 // similar, the WritingMode property is declared in our aggregate, too, but we override 322 // it, since the aggregate does no proper PropertyState handling. 323 lcl_removeProperty( _rAggregateProps, PROPERTY_WRITING_MODE ); 324 } 325 326 //-------------------------------------------------------------------- 327 void SAL_CALL ORichTextModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const 328 { 329 if ( isRegisteredProperty( _nHandle ) ) 330 { 331 OPropertyContainerHelper::getFastPropertyValue( _rValue, _nHandle ); 332 } 333 else if ( isFontRelatedProperty( _nHandle ) ) 334 { 335 FontControlModel::getFastPropertyValue( _rValue, _nHandle ); 336 } 337 else 338 { 339 OControlModel::getFastPropertyValue( _rValue, _nHandle ); 340 } 341 } 342 343 //-------------------------------------------------------------------- 344 sal_Bool SAL_CALL ORichTextModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw( IllegalArgumentException ) 345 { 346 sal_Bool bModified = sal_False; 347 348 if ( isRegisteredProperty( _nHandle ) ) 349 { 350 bModified = OPropertyContainerHelper::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); 351 } 352 else if ( isFontRelatedProperty( _nHandle ) ) 353 { 354 bModified = FontControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); 355 } 356 else 357 { 358 bModified = OControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); 359 } 360 361 return bModified; 362 } 363 364 //-------------------------------------------------------------------- 365 void SAL_CALL ORichTextModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception) 366 { 367 if ( isRegisteredProperty( _nHandle ) ) 368 { 369 OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue ); 370 371 switch ( _nHandle ) 372 { 373 case PROPERTY_ID_REFERENCE_DEVICE: 374 { 375 #if OSL_DEBUG_LEVEL > 0 376 MapMode aOldMapMode = m_pEngine->GetRefDevice()->GetMapMode(); 377 #endif 378 379 OutputDevice* pRefDevice = VCLUnoHelper::GetOutputDevice( m_xReferenceDevice ); 380 OSL_ENSURE( pRefDevice, "ORichTextModel::setFastPropertyValue_NoBroadcast: empty reference device?" ); 381 m_pEngine->SetRefDevice( pRefDevice ); 382 383 #if OSL_DEBUG_LEVEL > 0 384 MapMode aNewMapMode = m_pEngine->GetRefDevice()->GetMapMode(); 385 OSL_ENSURE( aNewMapMode.GetMapUnit() == aOldMapMode.GetMapUnit(), 386 "ORichTextModel::setFastPropertyValue_NoBroadcast: You should not tamper with the MapUnit of the ref device!" ); 387 // if this assertion here is triggered, then we would need to adjust all 388 // items in all text portions in all paragraphs in the attributes of the EditEngine, 389 // as long as they are MapUnit-dependent. This holds at least for the FontSize. 390 #endif 391 } 392 break; 393 394 case PROPERTY_ID_TEXT: 395 { 396 MutexRelease aReleaseMutex( m_aMutex ); 397 impl_smlock_setEngineText( m_sLastKnownEngineText ); 398 } 399 break; 400 } // switch ( _nHandle ) 401 } 402 else if ( isFontRelatedProperty( _nHandle ) ) 403 { 404 FontDescriptor aOldFont( getFont() ); 405 406 FontControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); 407 408 if ( isFontAggregateProperty( _nHandle ) ) 409 firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) ); 410 } 411 else 412 { 413 switch ( _nHandle ) 414 { 415 case PROPERTY_ID_WRITING_MODE: 416 { 417 // forward to our aggregate, so the EditEngine knows about it 418 if ( m_xAggregateSet.is() ) 419 m_xAggregateSet->setPropertyValue( 420 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ), _rValue ); 421 } 422 break; 423 424 default: 425 OControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); 426 break; 427 } 428 } 429 } 430 431 //-------------------------------------------------------------------- 432 Any ORichTextModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const 433 { 434 Any aDefault; 435 436 switch ( _nHandle ) 437 { 438 case PROPERTY_ID_WRITING_MODE: 439 case PROPERTY_ID_CONTEXT_WRITING_MODE: 440 aDefault <<= WritingMode2::CONTEXT; 441 break; 442 443 case PROPERTY_ID_LINEEND_FORMAT: 444 aDefault <<= (sal_Int16)LineEndFormat::LINE_FEED; 445 break; 446 447 case PROPERTY_ID_ECHO_CHAR: 448 case PROPERTY_ID_ALIGN: 449 case PROPERTY_ID_MAXTEXTLEN: 450 aDefault <<= (sal_Int16)0; 451 break; 452 453 case PROPERTY_ID_TABSTOP: 454 case PROPERTY_ID_BACKGROUNDCOLOR: 455 case PROPERTY_ID_BORDERCOLOR: 456 case PROPERTY_ID_VERTICAL_ALIGN: 457 /* void */ 458 break; 459 460 case PROPERTY_ID_ENABLED: 461 case PROPERTY_ID_ENABLEVISIBLE: 462 case PROPERTY_ID_PRINTABLE: 463 case PROPERTY_ID_HIDEINACTIVESELECTION: 464 aDefault <<= (sal_Bool)sal_True; 465 break; 466 467 case PROPERTY_ID_HARDLINEBREAKS: 468 case PROPERTY_ID_HSCROLL: 469 case PROPERTY_ID_VSCROLL: 470 case PROPERTY_ID_READONLY: 471 case PROPERTY_ID_MULTILINE: 472 case PROPERTY_ID_RICH_TEXT: 473 aDefault <<= (sal_Bool)sal_False; 474 break; 475 476 case PROPERTY_ID_DEFAULTCONTROL: 477 aDefault <<= (::rtl::OUString)FRM_SUN_CONTROL_RICHTEXTCONTROL; 478 break; 479 480 case PROPERTY_ID_HELPTEXT: 481 case PROPERTY_ID_HELPURL: 482 case PROPERTY_ID_TEXT: 483 aDefault <<= ::rtl::OUString(); 484 break; 485 486 case PROPERTY_ID_BORDER: 487 aDefault <<= (sal_Int16)1; 488 break; 489 490 default: 491 if ( isFontRelatedProperty( _nHandle ) ) 492 aDefault = FontControlModel::getPropertyDefaultByHandle( _nHandle ); 493 else 494 aDefault = OControlModel::getPropertyDefaultByHandle( _nHandle ); 495 } 496 497 return aDefault; 498 } 499 500 //-------------------------------------------------------------------- 501 void ORichTextModel::impl_smlock_setEngineText( const ::rtl::OUString& _rText ) 502 { 503 if ( m_pEngine.get() ) 504 { 505 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 506 m_bSettingEngineText = true; 507 m_pEngine->SetText( _rText ); 508 m_bSettingEngineText = false; 509 } 510 } 511 512 //-------------------------------------------------------------------- 513 ::rtl::OUString SAL_CALL ORichTextModel::getServiceName() throw ( RuntimeException) 514 { 515 return FRM_SUN_COMPONENT_RICHTEXTCONTROL; 516 } 517 518 //-------------------------------------------------------------------- 519 void SAL_CALL ORichTextModel::write(const Reference< XObjectOutputStream >& _rxOutStream) throw ( IOException, RuntimeException) 520 { 521 OControlModel::write( _rxOutStream ); 522 // TODO: place your code here 523 } 524 525 //-------------------------------------------------------------------- 526 void SAL_CALL ORichTextModel::read(const Reference< XObjectInputStream >& _rxInStream) throw ( IOException, RuntimeException) 527 { 528 OControlModel::read( _rxInStream ); 529 // TODO: place your code here 530 } 531 532 //-------------------------------------------------------------------- 533 RichTextEngine* ORichTextModel::getEditEngine( const Reference< XControlModel >& _rxModel ) 534 { 535 RichTextEngine* pEngine = NULL; 536 537 Reference< XUnoTunnel > xTunnel( _rxModel, UNO_QUERY ); 538 OSL_ENSURE( xTunnel.is(), "ORichTextModel::getEditEngine: invalid model!" ); 539 if ( xTunnel.is() ) 540 { 541 try 542 { 543 pEngine = reinterpret_cast< RichTextEngine* >( xTunnel->getSomething( getEditEngineTunnelId() ) ); 544 } 545 catch( const Exception& ) 546 { 547 OSL_ENSURE( sal_False, "ORichTextModel::getEditEngine: caught an exception!" ); 548 } 549 } 550 return pEngine; 551 } 552 553 //-------------------------------------------------------------------- 554 Sequence< sal_Int8 > ORichTextModel::getEditEngineTunnelId() 555 { 556 static ::cppu::OImplementationId * pId = 0; 557 if (! pId) 558 { 559 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 560 if (! pId) 561 { 562 static ::cppu::OImplementationId aId; 563 pId = &aId; 564 } 565 } 566 return pId->getImplementationId(); 567 } 568 569 //-------------------------------------------------------------------- 570 IMPL_LINK( ORichTextModel, OnEngineContentModified, void*, /*_pNotInterestedIn*/ ) 571 { 572 if ( !m_bSettingEngineText ) 573 { 574 m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *this ) ); 575 576 potentialTextChange(); 577 // is this a good idea? It may become expensive in case of larger texts, 578 // and this method here is called for every single changed character ... 579 // On the other hand, the API *requires* us to notify changes in the "Text" 580 // property immediately ... 581 } 582 583 return 0L; 584 } 585 586 //-------------------------------------------------------------------- 587 sal_Int64 SAL_CALL ORichTextModel::getSomething( const Sequence< sal_Int8 >& _rId ) throw (RuntimeException) 588 { 589 Sequence< sal_Int8 > aEditEngineAccessId( getEditEngineTunnelId() ); 590 if ( ( _rId.getLength() == aEditEngineAccessId.getLength() ) 591 && ( 0 == rtl_compareMemory( aEditEngineAccessId.getConstArray(), _rId.getConstArray(), _rId.getLength() ) ) 592 ) 593 return reinterpret_cast< sal_Int64 >( m_pEngine.get() ); 594 595 Reference< XUnoTunnel > xAggTunnel; 596 if ( query_aggregation( m_xAggregate, xAggTunnel ) ) 597 return xAggTunnel->getSomething( _rId ); 598 599 return 0; 600 } 601 602 //-------------------------------------------------------------------- 603 void SAL_CALL ORichTextModel::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException) 604 { 605 m_aModifyListeners.addInterface( _rxListener ); 606 } 607 608 //-------------------------------------------------------------------- 609 void SAL_CALL ORichTextModel::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException) 610 { 611 m_aModifyListeners.removeInterface( _rxListener ); 612 } 613 614 //-------------------------------------------------------------------- 615 void ORichTextModel::potentialTextChange( ) 616 { 617 ::rtl::OUString sCurrentEngineText; 618 if ( m_pEngine.get() ) 619 sCurrentEngineText = m_pEngine->GetText(); 620 621 if ( sCurrentEngineText != m_sLastKnownEngineText ) 622 { 623 sal_Int32 nHandle = PROPERTY_ID_TEXT; 624 Any aOldValue; aOldValue <<= m_sLastKnownEngineText; 625 Any aNewValue; aNewValue <<= sCurrentEngineText; 626 fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False ); 627 628 m_sLastKnownEngineText = sCurrentEngineText; 629 } 630 } 631 632 //........................................................................ 633 } // namespace frm 634 //........................................................................ 635