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 #include "Edit.hxx" 28 29 #include <com/sun/star/uno/Type.hxx> 30 #include <com/sun/star/awt/XWindow.hpp> 31 #include <com/sun/star/container/XIndexAccess.hpp> 32 #include <com/sun/star/form/XSubmit.hpp> 33 #include <com/sun/star/util/NumberFormat.hpp> 34 #include <com/sun/star/sdbc/DataType.hpp> 35 #include <com/sun/star/awt/XVclWindowPeer.hpp> 36 37 #include <vcl/svapp.hxx> 38 #include <tools/wintypes.hxx> 39 40 #include <connectivity/dbtools.hxx> 41 #include <connectivity/formattedcolumnvalue.hxx> 42 #include <connectivity/dbconversion.hxx> 43 44 #include <tools/diagnose_ex.h> 45 #include <tools/debug.hxx> 46 47 #include <comphelper/container.hxx> 48 #include <comphelper/numbers.hxx> 49 50 using namespace dbtools; 51 52 //......................................................................... 53 namespace frm 54 { 55 using namespace ::com::sun::star::uno; 56 using namespace ::com::sun::star::sdb; 57 using namespace ::com::sun::star::sdbc; 58 using namespace ::com::sun::star::sdbcx; 59 using namespace ::com::sun::star::beans; 60 using namespace ::com::sun::star::container; 61 using namespace ::com::sun::star::form; 62 using namespace ::com::sun::star::awt; 63 using namespace ::com::sun::star::io; 64 using namespace ::com::sun::star::lang; 65 using namespace ::com::sun::star::util; 66 using namespace ::com::sun::star::form::binding; 67 68 //------------------------------------------------------------------ 69 InterfaceRef SAL_CALL OEditControl_CreateInstance(const Reference< XMultiServiceFactory > & _rxFactory) 70 { 71 return *(new OEditControl(_rxFactory)); 72 } 73 74 //------------------------------------------------------------------------------ 75 Sequence<Type> OEditControl::_getTypes() 76 { 77 static Sequence<Type> aTypes; 78 if (!aTypes.getLength()) 79 { 80 // my two base classes 81 aTypes = concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes()); 82 } 83 return aTypes; 84 } 85 86 //------------------------------------------------------------------------------ 87 Any SAL_CALL OEditControl::queryAggregation(const Type& _rType) throw (RuntimeException) 88 { 89 Any aReturn = OBoundControl::queryAggregation(_rType); 90 if (!aReturn.hasValue()) 91 aReturn = OEditControl_BASE::queryInterface(_rType); 92 93 return aReturn; 94 } 95 96 DBG_NAME(OEditControl); 97 //------------------------------------------------------------------------------ 98 OEditControl::OEditControl(const Reference<XMultiServiceFactory>& _rxFactory) 99 :OBoundControl( _rxFactory, FRM_SUN_CONTROL_RICHTEXTCONTROL ) 100 ,m_aChangeListeners(m_aMutex) 101 ,m_nKeyEvent( 0 ) 102 { 103 DBG_CTOR(OEditControl,NULL); 104 105 increment(m_refCount); 106 { 107 Reference<XWindow> xComp; 108 if (query_aggregation(m_xAggregate, xComp)) 109 { 110 xComp->addFocusListener(this); 111 xComp->addKeyListener(this); 112 } 113 } 114 decrement(m_refCount); 115 } 116 117 //------------------------------------------------------------------------------ 118 OEditControl::~OEditControl() 119 { 120 if( m_nKeyEvent ) 121 Application::RemoveUserEvent( m_nKeyEvent ); 122 123 if (!OComponentHelper::rBHelper.bDisposed) 124 { 125 acquire(); 126 dispose(); 127 } 128 129 DBG_DTOR(OEditControl,NULL); 130 } 131 132 // XChangeBroadcaster 133 //------------------------------------------------------------------------------ 134 void OEditControl::addChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException) 135 { 136 m_aChangeListeners.addInterface( l ); 137 } 138 139 //------------------------------------------------------------------------------ 140 void OEditControl::removeChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException) 141 { 142 m_aChangeListeners.removeInterface( l ); 143 } 144 145 // OComponentHelper 146 //------------------------------------------------------------------------------ 147 void OEditControl::disposing() 148 { 149 OBoundControl::disposing(); 150 151 EventObject aEvt(static_cast<XWeak*>(this)); 152 m_aChangeListeners.disposeAndClear(aEvt); 153 } 154 155 // XServiceInfo 156 //------------------------------------------------------------------------------ 157 StringSequence OEditControl::getSupportedServiceNames() throw() 158 { 159 StringSequence aSupported = OBoundControl::getSupportedServiceNames(); 160 aSupported.realloc(aSupported.getLength() + 1); 161 162 ::rtl::OUString*pArray = aSupported.getArray(); 163 pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_TEXTFIELD; 164 return aSupported; 165 } 166 167 // XEventListener 168 //------------------------------------------------------------------------------ 169 void OEditControl::disposing(const EventObject& Source) throw( RuntimeException ) 170 { 171 OBoundControl::disposing(Source); 172 } 173 174 // XFocusListener 175 //------------------------------------------------------------------------------ 176 void OEditControl::focusGained( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException) 177 { 178 Reference<XPropertySet> xSet(getModel(), UNO_QUERY); 179 if (xSet.is()) 180 xSet->getPropertyValue( PROPERTY_TEXT ) >>= m_aHtmlChangeValue; 181 } 182 183 //------------------------------------------------------------------------------ 184 void OEditControl::focusLost( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException) 185 { 186 Reference<XPropertySet> xSet(getModel(), UNO_QUERY); 187 if (xSet.is()) 188 { 189 ::rtl::OUString sNewHtmlChangeValue; 190 xSet->getPropertyValue( PROPERTY_TEXT ) >>= sNewHtmlChangeValue; 191 if( sNewHtmlChangeValue != m_aHtmlChangeValue ) 192 { 193 EventObject aEvt( *this ); 194 m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvt ); 195 } 196 } 197 } 198 199 // XKeyListener 200 //------------------------------------------------------------------------------ 201 void OEditControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException) 202 { 203 if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 ) 204 return; 205 206 // Steht das Control in einem Formular mit einer Submit-URL? 207 Reference<XPropertySet> xSet(getModel(), UNO_QUERY); 208 if( !xSet.is() ) 209 return; 210 211 // nicht fuer multiline edits 212 Any aTmp( xSet->getPropertyValue(PROPERTY_MULTILINE)); 213 if ((aTmp.getValueType().equals(::getBooleanCppuType())) && getBOOL(aTmp)) 214 return; 215 216 Reference<XFormComponent> xFComp(xSet, UNO_QUERY); 217 InterfaceRef xParent = xFComp->getParent(); 218 if( !xParent.is() ) 219 return; 220 221 Reference<XPropertySet> xFormSet(xParent, UNO_QUERY); 222 if( !xFormSet.is() ) 223 return; 224 225 aTmp = xFormSet->getPropertyValue( PROPERTY_TARGET_URL ); 226 if (!aTmp.getValueType().equals(::getCppuType((const ::rtl::OUString*)NULL)) || 227 !getString(aTmp).getLength() ) 228 return; 229 230 Reference<XIndexAccess> xElements(xParent, UNO_QUERY); 231 sal_Int32 nCount = xElements->getCount(); 232 if( nCount > 1 ) 233 { 234 Reference<XPropertySet> xFCSet; 235 for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ ) 236 { 237 // Any aElement(xElements->getByIndex(nIndex)); 238 xElements->getByIndex(nIndex) >>= xFCSet; 239 OSL_ENSURE(xFCSet.is(),"OEditControl::keyPressed: No XPropertySet!"); 240 241 if (hasProperty(PROPERTY_CLASSID, xFCSet) && 242 getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD) 243 { 244 // Noch ein weiteres Edit gefunden ==> dann nicht submitten 245 if (xFCSet != xSet) 246 return; 247 } 248 } 249 } 250 251 // Da wir noch im Haender stehen, submit asynchron ausloesen 252 if( m_nKeyEvent ) 253 Application::RemoveUserEvent( m_nKeyEvent ); 254 m_nKeyEvent = Application::PostUserEvent( LINK(this, OEditControl,OnKeyPressed) ); 255 } 256 257 //------------------------------------------------------------------------------ 258 void OEditControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException) 259 { 260 } 261 262 //------------------------------------------------------------------------------ 263 IMPL_LINK(OEditControl, OnKeyPressed, void*, /*EMPTYARG*/) 264 { 265 m_nKeyEvent = 0; 266 267 Reference<XFormComponent> xFComp(getModel(), UNO_QUERY); 268 InterfaceRef xParent = xFComp->getParent(); 269 Reference<XSubmit> xSubmit(xParent, UNO_QUERY); 270 if (xSubmit.is()) 271 xSubmit->submit( Reference<XControl>(), ::com::sun::star::awt::MouseEvent() ); 272 return 0L; 273 } 274 275 //------------------------------------------------------------------ 276 void SAL_CALL OEditControl::createPeer( const Reference< XToolkit>& _rxToolkit, const Reference< XWindowPeer>& _rxParent ) throw ( RuntimeException ) 277 { 278 OBoundControl::createPeer(_rxToolkit, _rxParent); 279 } 280 281 /*************************************************************************/ 282 //------------------------------------------------------------------ 283 InterfaceRef SAL_CALL OEditModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) 284 { 285 return *(new OEditModel(_rxFactory)); 286 } 287 288 //------------------------------------------------------------------------------ 289 Sequence<Type> OEditModel::_getTypes() 290 { 291 return OEditBaseModel::_getTypes(); 292 } 293 294 295 DBG_NAME(OEditModel); 296 //------------------------------------------------------------------ 297 OEditModel::OEditModel(const Reference<XMultiServiceFactory>& _rxFactory) 298 :OEditBaseModel( _rxFactory, FRM_SUN_COMPONENT_RICHTEXTCONTROL, FRM_SUN_CONTROL_TEXTFIELD, sal_True, sal_True ) 299 ,m_bMaxTextLenModified(sal_False) 300 ,m_bWritingFormattedFake(sal_False) 301 { 302 DBG_CTOR(OEditModel,NULL); 303 304 m_nClassId = FormComponentType::TEXTFIELD; 305 initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT ); 306 } 307 308 //------------------------------------------------------------------ 309 OEditModel::OEditModel( const OEditModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory ) 310 :OEditBaseModel( _pOriginal, _rxFactory ) 311 ,m_bMaxTextLenModified(sal_False) 312 ,m_bWritingFormattedFake(sal_False) 313 { 314 DBG_CTOR( OEditModel, NULL ); 315 316 // Note that most of the properties are not clone from the original object: 317 // Things as the format key, it's type, and such, depend on the field being part of a loaded form 318 // (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself 319 // certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded, 320 // they will be set to new values, anyway .... 321 } 322 323 //------------------------------------------------------------------ 324 OEditModel::~OEditModel() 325 { 326 if (!OComponentHelper::rBHelper.bDisposed) 327 { 328 acquire(); 329 dispose(); 330 } 331 332 DBG_DTOR(OEditModel,NULL); 333 } 334 335 //------------------------------------------------------------------------------ 336 IMPLEMENT_DEFAULT_CLONING( OEditModel ) 337 338 //------------------------------------------------------------------------------ 339 void OEditModel::disposing() 340 { 341 OEditBaseModel::disposing(); 342 m_pValueFormatter.reset(); 343 } 344 345 // XPersistObject 346 //------------------------------------------------------------------------------ 347 ::rtl::OUString SAL_CALL OEditModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException) 348 { 349 return FRM_COMPONENT_EDIT; // old (non-sun) name for compatibility ! 350 } 351 352 // XServiceInfo 353 //------------------------------------------------------------------------------ 354 StringSequence SAL_CALL OEditModel::getSupportedServiceNames() throw() 355 { 356 StringSequence aSupported = OBoundControlModel::getSupportedServiceNames(); 357 358 sal_Int32 nOldLen = aSupported.getLength(); 359 aSupported.realloc( nOldLen + 8 ); 360 ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen; 361 362 *pStoreTo++ = BINDABLE_CONTROL_MODEL; 363 *pStoreTo++ = DATA_AWARE_CONTROL_MODEL; 364 *pStoreTo++ = VALIDATABLE_CONTROL_MODEL; 365 366 *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL; 367 *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL; 368 369 *pStoreTo++ = FRM_SUN_COMPONENT_TEXTFIELD; 370 *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD; 371 *pStoreTo++ = BINDABLE_DATABASE_TEXT_FIELD; 372 373 return aSupported; 374 } 375 376 // XPropertySet 377 void SAL_CALL OEditModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const 378 { 379 if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH == nHandle ) 380 { 381 if ( m_bMaxTextLenModified ) 382 rValue <<= sal_Int16(0); 383 else if ( m_xAggregateSet.is() ) 384 rValue = m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN); 385 } 386 else 387 { 388 OEditBaseModel::getFastPropertyValue(rValue, nHandle ); 389 } 390 } 391 392 //------------------------------------------------------------------------------ 393 void OEditModel::describeFixedProperties( Sequence< Property >& _rProps ) const 394 { 395 BEGIN_DESCRIBE_PROPERTIES( 5, OEditBaseModel ) 396 DECL_PROP2(PERSISTENCE_MAXTEXTLENGTH,sal_Int16, READONLY, TRANSIENT); 397 DECL_PROP2(DEFAULT_TEXT, ::rtl::OUString, BOUND, MAYBEDEFAULT); 398 DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND); 399 DECL_PROP1(TABINDEX, sal_Int16, BOUND); 400 DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT); 401 END_DESCRIBE_PROPERTIES(); 402 } 403 404 //------------------------------------------------------------------------------ 405 void OEditModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const 406 { 407 OEditBaseModel::describeAggregateProperties( _rAggregateProps ); 408 409 // our aggregate is a rich text model, which also derives from OControlModel, as 410 // do we, so we need to remove some duplicate properties 411 RemoveProperty( _rAggregateProps, PROPERTY_TABINDEX ); 412 RemoveProperty( _rAggregateProps, PROPERTY_CLASSID ); 413 RemoveProperty( _rAggregateProps, PROPERTY_NAME ); 414 RemoveProperty( _rAggregateProps, PROPERTY_TAG ); 415 RemoveProperty( _rAggregateProps, PROPERTY_NATIVE_LOOK ); 416 417 } 418 419 //------------------------------------------------------------------------------ 420 bool OEditModel::implActsAsRichText( ) const 421 { 422 sal_Bool bActAsRichText = sal_False; 423 if ( m_xAggregateSet.is() ) 424 { 425 OSL_VERIFY( m_xAggregateSet->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActAsRichText ); 426 } 427 return bActAsRichText; 428 } 429 430 //------------------------------------------------------------------------------ 431 void SAL_CALL OEditModel::reset( ) throw(RuntimeException) 432 { 433 // no reset if we currently act as rich text control 434 if ( implActsAsRichText() ) 435 return; 436 437 OEditBaseModel::reset(); 438 } 439 440 //------------------------------------------------------------------------------ 441 namespace 442 { 443 void lcl_transferProperties( const Reference< XPropertySet >& _rxSource, const Reference< XPropertySet >& _rxDest ) 444 { 445 try 446 { 447 Reference< XPropertySetInfo > xSourceInfo; 448 if ( _rxSource.is() ) 449 xSourceInfo = _rxSource->getPropertySetInfo(); 450 451 Reference< XPropertySetInfo > xDestInfo; 452 if ( _rxDest.is() ) 453 xDestInfo = _rxDest->getPropertySetInfo(); 454 455 if ( !xSourceInfo.is() || !xDestInfo.is() ) 456 { 457 OSL_ENSURE( sal_False, "lcl_transferProperties: invalid property set(s)!" ); 458 return; 459 } 460 461 Sequence< Property > aSourceProps( xSourceInfo->getProperties() ); 462 const Property* pSourceProps = aSourceProps.getConstArray(); 463 const Property* pSourcePropsEnd = aSourceProps.getConstArray() + aSourceProps.getLength(); 464 while ( pSourceProps != pSourcePropsEnd ) 465 { 466 if ( !xDestInfo->hasPropertyByName( pSourceProps->Name ) ) 467 { 468 ++pSourceProps; 469 continue; 470 } 471 472 Property aDestProp( xDestInfo->getPropertyByName( pSourceProps->Name ) ); 473 if ( 0 != ( aDestProp.Attributes & PropertyAttribute::READONLY ) ) 474 { 475 ++pSourceProps; 476 continue; 477 } 478 479 try 480 { 481 _rxDest->setPropertyValue( pSourceProps->Name, _rxSource->getPropertyValue( pSourceProps->Name ) ); 482 } 483 catch( IllegalArgumentException e ) 484 { 485 #if OSL_DEBUG_LEVEL > 0 486 ::rtl::OString sMessage( "could not transfer the property named '" ); 487 sMessage += ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US ); 488 sMessage += ::rtl::OString( "'." ); 489 if ( e.Message.getLength() ) 490 { 491 sMessage += ::rtl::OString( "\n\nMessage:\n" ); 492 sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US ); 493 } 494 OSL_ENSURE( sal_False, sMessage.getStr() ); 495 #endif 496 } 497 498 ++pSourceProps; 499 } 500 } 501 catch( const Exception& ) 502 { 503 DBG_UNHANDLED_EXCEPTION(); 504 } 505 } 506 } 507 508 //------------------------------------------------------------------------------ 509 void OEditModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const 510 { 511 // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate, 512 // but for compatibility, we need to use an "old" aggregate for writing and reading 513 514 Reference< XPropertySet > xFakedAggregate( 515 getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ), 516 UNO_QUERY 517 ); 518 OSL_ENSURE( xFakedAggregate.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" ); 519 if ( !xFakedAggregate.is() ) 520 return; 521 522 lcl_transferProperties( m_xAggregateSet, xFakedAggregate ); 523 524 Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY ); 525 OSL_ENSURE( xFakedPersist.is(), "OEditModel::writeAggregate: no XPersistObject!" ); 526 if ( xFakedPersist.is() ) 527 xFakedPersist->write( _rxOutStream ); 528 } 529 530 //------------------------------------------------------------------------------ 531 void OEditModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream ) 532 { 533 // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate, 534 // but for compatibility, we need to use an "old" aggregate for writing and reading 535 536 Reference< XPropertySet > xFakedAggregate( 537 getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ), 538 UNO_QUERY 539 ); 540 Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY ); 541 OSL_ENSURE( xFakedPersist.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" ); 542 if ( xFakedPersist.is() ) 543 { 544 xFakedPersist->read( _rxInStream ); 545 lcl_transferProperties( xFakedAggregate, m_xAggregateSet ); 546 } 547 } 548 549 //------------------------------------------------------------------------------ 550 void OEditModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 551 { 552 Any aCurrentText; 553 sal_Int16 nOldTextLen = 0; 554 // bin ich gerade loaded und habe dazu zeitweilig die MaxTextLen umgesetzt ? 555 if ( m_bMaxTextLenModified ) 556 { // -> fuer die Dauer des Speicherns meinem aggregierten Model die alte TextLen einreden 557 558 // before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len 559 // FS - 08.12.99 - 70606 560 aCurrentText = m_xAggregateSet->getPropertyValue(PROPERTY_TEXT); 561 562 m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN) >>= nOldTextLen; 563 m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny((sal_Int16)0)); 564 } 565 566 OEditBaseModel::write(_rxOutStream); 567 568 if ( m_bMaxTextLenModified ) 569 { // wieder zuruecksetzen 570 m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny(nOldTextLen)); 571 // and reset the text 572 // First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks 573 // we aren't changing the prop (it didn't notify the - implicite - change of the text prop while setting the max text len) 574 // This seems to be a bug with in toolkit's EditControl-implementation. 575 m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, makeAny(::rtl::OUString())); 576 m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, aCurrentText); 577 } 578 } 579 580 //------------------------------------------------------------------------------ 581 void OEditModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 582 { 583 OEditBaseModel::read(_rxInStream); 584 585 // Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown 586 // to older versions (5.0). 587 // correct this ... 588 if (m_xAggregateSet.is()) 589 { 590 Any aDefaultControl = m_xAggregateSet->getPropertyValue(PROPERTY_DEFAULTCONTROL); 591 if ( (aDefaultControl.getValueType().getTypeClass() == TypeClass_STRING) 592 && (getString(aDefaultControl).compareTo(STARDIV_ONE_FORM_CONTROL_TEXTFIELD) == COMPARE_EQUAL) 593 ) 594 { 595 m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( (::rtl::OUString)STARDIV_ONE_FORM_CONTROL_EDIT ) ); 596 // Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT, 597 // the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD. 598 } 599 } 600 } 601 602 //------------------------------------------------------------------------------ 603 sal_uInt16 OEditModel::getPersistenceFlags() const 604 { 605 sal_uInt16 nFlags = OEditBaseModel::getPersistenceFlags(); 606 607 if (m_bWritingFormattedFake) 608 nFlags |= PF_FAKE_FORMATTED_FIELD; 609 610 return nFlags; 611 } 612 613 //------------------------------------------------------------------------------ 614 void OEditModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) 615 { 616 Reference< XPropertySet > xField = getField(); 617 if ( xField.is() ) 618 { 619 m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) ); 620 621 if ( m_pValueFormatter->getKeyType() != NumberFormat::SCIENTIFIC ) 622 { 623 m_bMaxTextLenModified = getINT16(m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN)) != 0; 624 if ( !m_bMaxTextLenModified ) 625 { 626 sal_Int32 nFieldLen = 0; 627 xField->getPropertyValue(::rtl::OUString::createFromAscii("Precision")) >>= nFieldLen; 628 629 if (nFieldLen && nFieldLen <= USHRT_MAX) 630 { 631 Any aVal; 632 aVal <<= (sal_Int16)nFieldLen; 633 m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal); 634 635 m_bMaxTextLenModified = sal_True; 636 } 637 } 638 else 639 m_bMaxTextLenModified = sal_False; // to get sure that the text len won't be set in unloaded 640 } 641 } 642 } 643 644 //------------------------------------------------------------------------------ 645 void OEditModel::onDisconnectedDbColumn() 646 { 647 OEditBaseModel::onDisconnectedDbColumn(); 648 649 m_pValueFormatter.reset(); 650 651 if ( hasField() && m_bMaxTextLenModified ) 652 { 653 Any aVal; 654 aVal <<= (sal_Int16)0; // nur wenn es 0 war, habe ich es in onConnectedDbColumn umgesetzt 655 m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal); 656 m_bMaxTextLenModified = sal_False; 657 } 658 } 659 660 //------------------------------------------------------------------------------ 661 sal_Bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType ) 662 { 663 // if we act as rich text curently, we do not allow binding to a database column 664 if ( implActsAsRichText() ) 665 return sal_False; 666 667 return OEditBaseModel::approveDbColumnType( _nColumnType ); 668 } 669 670 //------------------------------------------------------------------------------ 671 void OEditModel::resetNoBroadcast() 672 { 673 OEditBaseModel::resetNoBroadcast(); 674 } 675 676 //------------------------------------------------------------------------------ 677 sal_Bool OEditModel::commitControlValueToDbColumn( bool /*_bPostReset*/ ) 678 { 679 Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) ); 680 681 ::rtl::OUString sNewValue; 682 aNewValue >>= sNewValue; 683 684 if ( !aNewValue.hasValue() 685 || ( !sNewValue.getLength() // an empty string 686 && m_bEmptyIsNull // which should be interpreted as NULL 687 ) 688 ) 689 { 690 m_xColumnUpdate->updateNull(); 691 } 692 else 693 { 694 OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::commitControlValueToDbColumn: no value formatter!" ); 695 try 696 { 697 if ( m_pValueFormatter.get() ) 698 { 699 if ( !m_pValueFormatter->setFormattedValue( sNewValue ) ) 700 return sal_False; 701 } 702 else 703 m_xColumnUpdate->updateString( sNewValue ); 704 } 705 catch ( const Exception& ) 706 { 707 return sal_False; 708 } 709 } 710 711 return sal_True; 712 } 713 714 //------------------------------------------------------------------------------ 715 Any OEditModel::translateDbColumnToControlValue() 716 { 717 OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::translateDbColumnToControlValue: no value formatter!" ); 718 Any aRet; 719 if ( m_pValueFormatter.get() ) 720 { 721 ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() ); 722 if ( !sValue.getLength() 723 && m_pValueFormatter->getColumn().is() 724 && m_pValueFormatter->getColumn()->wasNull() 725 ) 726 { 727 } 728 else 729 { 730 // #i2817# OJ 731 sal_uInt16 nMaxTextLen = getINT16( m_xAggregateSet->getPropertyValue( PROPERTY_MAXTEXTLEN ) ); 732 if ( nMaxTextLen && sValue.getLength() > nMaxTextLen ) 733 { 734 sal_Int32 nDiff = sValue.getLength() - nMaxTextLen; 735 sValue = sValue.replaceAt( nMaxTextLen, nDiff, ::rtl::OUString() ); 736 } 737 738 aRet <<= sValue; 739 } 740 } 741 742 return aRet.hasValue() ? aRet : makeAny( ::rtl::OUString() ); 743 } 744 745 //------------------------------------------------------------------------------ 746 Any OEditModel::getDefaultForReset() const 747 { 748 return makeAny( m_aDefaultText ); 749 } 750 751 //......................................................................... 752 } 753 //......................................................................... 754 755