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 "FormattedField.hxx" 28 #include "services.hxx" 29 #include "property.hrc" 30 #include "property.hxx" 31 #include "frm_resource.hxx" 32 #include "frm_resource.hrc" 33 #include "propertybaghelper.hxx" 34 #include <comphelper/sequence.hxx> 35 #include <comphelper/numbers.hxx> 36 #include <connectivity/dbtools.hxx> 37 #include <connectivity/dbconversion.hxx> 38 #include <svl/zforlist.hxx> 39 #include <svl/numuno.hxx> 40 #include <vcl/svapp.hxx> 41 #include <tools/debug.hxx> 42 #include <tools/wintypes.hxx> 43 #include <i18npool/mslangid.hxx> 44 #include <rtl/textenc.h> 45 #include <com/sun/star/sdbc/DataType.hpp> 46 #include <com/sun/star/util/NumberFormat.hpp> 47 #include <com/sun/star/util/Date.hpp> 48 #include <com/sun/star/util/Time.hpp> 49 #include <com/sun/star/awt/MouseEvent.hpp> 50 #include <com/sun/star/form/XSubmit.hpp> 51 #include <com/sun/star/awt/XWindow.hpp> 52 #include <com/sun/star/awt/XKeyListener.hpp> 53 #include <com/sun/star/form/FormComponentType.hpp> 54 #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 55 #include <com/sun/star/util/XNumberFormatTypes.hpp> 56 #include <com/sun/star/form/XForm.hpp> 57 #include <com/sun/star/container/XIndexAccess.hpp> 58 #include <vos/mutex.hxx> 59 // needed as long as we use the SolarMutex 60 #include <comphelper/streamsection.hxx> 61 #include <cppuhelper/weakref.hxx> 62 #include <unotools/desktopterminationobserver.hxx> 63 64 #include <list> 65 #include <algorithm> 66 67 using namespace dbtools; 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::sdb; 70 using namespace ::com::sun::star::sdbc; 71 using namespace ::com::sun::star::sdbcx; 72 using namespace ::com::sun::star::beans; 73 using namespace ::com::sun::star::container; 74 using namespace ::com::sun::star::form; 75 using namespace ::com::sun::star::awt; 76 using namespace ::com::sun::star::io; 77 using namespace ::com::sun::star::lang; 78 using namespace ::com::sun::star::util; 79 using namespace ::com::sun::star::form::binding; 80 81 namespace 82 { 83 typedef com::sun::star::util::Date UNODate; 84 typedef com::sun::star::util::Time UNOTime; 85 typedef com::sun::star::util::DateTime UNODateTime; 86 } 87 88 //......................................................................... 89 namespace frm 90 { 91 92 /*************************************************************************/ 93 94 class StandardFormatsSupplier : protected SvNumberFormatsSupplierObj, public ::utl::ITerminationListener 95 { 96 protected: 97 SvNumberFormatter* m_pMyPrivateFormatter; 98 static WeakReference< XNumberFormatsSupplier > s_xDefaultFormatsSupplier; 99 100 public: 101 static Reference< XNumberFormatsSupplier > get( const Reference< XMultiServiceFactory >& _rxORB ); 102 103 using SvNumberFormatsSupplierObj::operator new; 104 using SvNumberFormatsSupplierObj::operator delete; 105 106 protected: 107 StandardFormatsSupplier(const Reference<XMultiServiceFactory>& _rxFactory,LanguageType _eSysLanguage); 108 ~StandardFormatsSupplier(); 109 110 protected: 111 virtual bool queryTermination() const; 112 virtual void notifyTermination(); 113 }; 114 115 //------------------------------------------------------------------ 116 WeakReference< XNumberFormatsSupplier > StandardFormatsSupplier::s_xDefaultFormatsSupplier; 117 118 //------------------------------------------------------------------ 119 StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XMultiServiceFactory > & _rxFactory,LanguageType _eSysLanguage) 120 :SvNumberFormatsSupplierObj() 121 ,m_pMyPrivateFormatter(new SvNumberFormatter(_rxFactory, _eSysLanguage)) 122 { 123 SetNumberFormatter(m_pMyPrivateFormatter); 124 125 // #i29147# - 2004-06-18 - fs@openoffice.org 126 ::utl::DesktopTerminationObserver::registerTerminationListener( this ); 127 } 128 129 //------------------------------------------------------------------ 130 StandardFormatsSupplier::~StandardFormatsSupplier() 131 { 132 ::utl::DesktopTerminationObserver::revokeTerminationListener( this ); 133 134 DELETEZ( m_pMyPrivateFormatter ); 135 } 136 137 //------------------------------------------------------------------ 138 Reference< XNumberFormatsSupplier > StandardFormatsSupplier::get( const Reference< XMultiServiceFactory >& _rxORB ) 139 { 140 LanguageType eSysLanguage = LANGUAGE_SYSTEM; 141 { 142 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 143 Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier; 144 if ( xSupplier.is() ) 145 return xSupplier; 146 147 // get the Office's locale 148 const Locale& rSysLocale = SvtSysLocale().GetLocaleData().getLocale(); 149 // translate 150 eSysLanguage = MsLangId::convertLocaleToLanguage( rSysLocale ); 151 } 152 153 StandardFormatsSupplier* pSupplier = new StandardFormatsSupplier( _rxORB, eSysLanguage ); 154 Reference< XNumberFormatsSupplier > xNewlyCreatedSupplier( pSupplier ); 155 156 { 157 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 158 Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier; 159 if ( xSupplier.is() ) 160 // somebody used the small time frame where the mutex was not locked to create and set 161 // the supplier 162 return xSupplier; 163 164 s_xDefaultFormatsSupplier = xNewlyCreatedSupplier; 165 } 166 167 return xNewlyCreatedSupplier; 168 } 169 170 //------------------------------------------------------------------ 171 bool StandardFormatsSupplier::queryTermination() const 172 { 173 return true; 174 } 175 176 //------------------------------------------------------------------ 177 void StandardFormatsSupplier::notifyTermination() 178 { 179 Reference< XNumberFormatsSupplier > xKeepAlive = this; 180 // when the application is terminating, release our static reference so that we are cleared/destructed 181 // earlier than upon unloading the library 182 // #i29147# - 2004-06-18 - fs@openoffice.org 183 s_xDefaultFormatsSupplier = WeakReference< XNumberFormatsSupplier >( ); 184 185 SetNumberFormatter( NULL ); 186 DELETEZ( m_pMyPrivateFormatter ); 187 } 188 189 /*************************************************************************/ 190 //------------------------------------------------------------------ 191 InterfaceRef SAL_CALL OFormattedControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) 192 { 193 return *(new OFormattedControl(_rxFactory)); 194 } 195 196 //------------------------------------------------------------------ 197 Sequence<Type> OFormattedControl::_getTypes() 198 { 199 return ::comphelper::concatSequences( 200 OFormattedControl_BASE::getTypes(), 201 OBoundControl::_getTypes() 202 ); 203 } 204 205 //------------------------------------------------------------------ 206 Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException) 207 { 208 Any aReturn = OBoundControl::queryAggregation(_rType); 209 if (!aReturn.hasValue()) 210 aReturn = OFormattedControl_BASE::queryInterface(_rType); 211 return aReturn; 212 } 213 214 215 DBG_NAME(OFormattedControl); 216 //------------------------------------------------------------------------------ 217 OFormattedControl::OFormattedControl(const Reference<XMultiServiceFactory>& _rxFactory) 218 :OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD) 219 ,m_nKeyEvent(0) 220 { 221 DBG_CTOR(OFormattedControl,NULL); 222 223 increment(m_refCount); 224 { 225 Reference<XWindow> xComp; 226 if (query_aggregation(m_xAggregate, xComp)) 227 { 228 xComp->addKeyListener(this); 229 } 230 } 231 decrement(m_refCount); 232 } 233 234 //------------------------------------------------------------------------------ 235 OFormattedControl::~OFormattedControl() 236 { 237 if( m_nKeyEvent ) 238 Application::RemoveUserEvent( m_nKeyEvent ); 239 240 if (!OComponentHelper::rBHelper.bDisposed) 241 { 242 acquire(); 243 dispose(); 244 } 245 246 DBG_DTOR(OFormattedControl,NULL); 247 } 248 249 // XKeyListener 250 //------------------------------------------------------------------------------ 251 void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException) 252 { 253 OBoundControl::disposing(_rSource); 254 } 255 256 //------------------------------------------------------------------------------ 257 void OFormattedControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException) 258 { 259 if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 ) 260 return; 261 262 // Steht das Control in einem Formular mit einer Submit-URL? 263 Reference<com::sun::star::beans::XPropertySet> xSet(getModel(), UNO_QUERY); 264 if( !xSet.is() ) 265 return; 266 267 Reference<XFormComponent> xFComp(xSet, UNO_QUERY); 268 InterfaceRef xParent = xFComp->getParent(); 269 if( !xParent.is() ) 270 return; 271 272 Reference<com::sun::star::beans::XPropertySet> xFormSet(xParent, UNO_QUERY); 273 if( !xFormSet.is() ) 274 return; 275 276 Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL )); 277 if (!isA(aTmp, static_cast< ::rtl::OUString* >(NULL)) || 278 !getString(aTmp).getLength() ) 279 return; 280 281 Reference<XIndexAccess> xElements(xParent, UNO_QUERY); 282 sal_Int32 nCount = xElements->getCount(); 283 if( nCount > 1 ) 284 { 285 286 Reference<com::sun::star::beans::XPropertySet> xFCSet; 287 for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ ) 288 { 289 // Any aElement(xElements->getByIndex(nIndex)); 290 xElements->getByIndex(nIndex) >>= xFCSet; 291 292 if (hasProperty(PROPERTY_CLASSID, xFCSet) && 293 getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD) 294 { 295 // Noch ein weiteres Edit gefunden ==> dann nicht submitten 296 if (xFCSet != xSet) 297 return; 298 } 299 } 300 } 301 302 // Da wir noch im Haender stehen, submit asynchron ausloesen 303 if( m_nKeyEvent ) 304 Application::RemoveUserEvent( m_nKeyEvent ); 305 m_nKeyEvent = Application::PostUserEvent( LINK(this, OFormattedControl, 306 OnKeyPressed) ); 307 } 308 309 //------------------------------------------------------------------------------ 310 void OFormattedControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException) 311 { 312 } 313 314 //------------------------------------------------------------------------------ 315 IMPL_LINK(OFormattedControl, OnKeyPressed, void*, /*EMPTYARG*/) 316 { 317 m_nKeyEvent = 0; 318 319 Reference<XFormComponent> xFComp(getModel(), UNO_QUERY); 320 InterfaceRef xParent = xFComp->getParent(); 321 Reference<XSubmit> xSubmit(xParent, UNO_QUERY); 322 if (xSubmit.is()) 323 xSubmit->submit( Reference<XControl> (), ::com::sun::star::awt::MouseEvent() ); 324 return 0L; 325 } 326 327 //------------------------------------------------------------------------------ 328 StringSequence OFormattedControl::getSupportedServiceNames() throw() 329 { 330 StringSequence aSupported = OBoundControl::getSupportedServiceNames(); 331 aSupported.realloc(aSupported.getLength() + 1); 332 333 ::rtl::OUString*pArray = aSupported.getArray(); 334 pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_FORMATTEDFIELD; 335 return aSupported; 336 } 337 338 //------------------------------------------------------------------------------ 339 void OFormattedControl::setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException) 340 { 341 OBoundControl::setDesignMode(bOn); 342 } 343 344 /*************************************************************************/ 345 DBG_NAME(OFormattedModel) 346 //------------------------------------------------------------------ 347 void OFormattedModel::implConstruct() 348 { 349 // members 350 m_bOriginalNumeric = sal_False; 351 m_bNumeric = sal_False; 352 m_xOriginalFormatter = NULL; 353 m_nKeyType = NumberFormat::UNDEFINED; 354 m_aNullDate = DBTypeConversion::getStandardDate(); 355 m_nFieldType = DataType::OTHER; 356 357 // default our formats supplier 358 increment(m_refCount); 359 setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER); 360 decrement(m_refCount); 361 362 startAggregatePropertyListening( PROPERTY_FORMATKEY ); 363 startAggregatePropertyListening( PROPERTY_FORMATSSUPPLIER ); 364 } 365 366 //------------------------------------------------------------------ 367 OFormattedModel::OFormattedModel(const Reference<XMultiServiceFactory>& _rxFactory) 368 :OEditBaseModel(_rxFactory, VCL_CONTROLMODEL_FORMATTEDFIELD, FRM_SUN_CONTROL_FORMATTEDFIELD, sal_True, sal_True ) 369 // use the old control name for compytibility reasons 370 ,OErrorBroadcaster( OComponentHelper::rBHelper ) 371 { 372 DBG_CTOR(OFormattedModel, NULL); 373 374 implConstruct(); 375 376 m_nClassId = FormComponentType::TEXTFIELD; 377 initValueProperty( PROPERTY_EFFECTIVE_VALUE, PROPERTY_ID_EFFECTIVE_VALUE ); 378 } 379 380 //------------------------------------------------------------------ 381 OFormattedModel::OFormattedModel( const OFormattedModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory ) 382 :OEditBaseModel( _pOriginal, _rxFactory ) 383 ,OErrorBroadcaster( OComponentHelper::rBHelper ) 384 { 385 DBG_CTOR(OFormattedModel, NULL); 386 387 implConstruct(); 388 } 389 390 //------------------------------------------------------------------------------ 391 OFormattedModel::~OFormattedModel() 392 { 393 DBG_DTOR(OFormattedModel, NULL); 394 } 395 396 // XCloneable 397 //------------------------------------------------------------------------------ 398 IMPLEMENT_DEFAULT_CLONING( OFormattedModel ) 399 400 //------------------------------------------------------------------------------ 401 void SAL_CALL OFormattedModel::disposing() 402 { 403 OErrorBroadcaster::disposing(); 404 OEditBaseModel::disposing(); 405 } 406 407 // XServiceInfo 408 //------------------------------------------------------------------------------ 409 StringSequence OFormattedModel::getSupportedServiceNames() throw() 410 { 411 StringSequence aSupported = OEditBaseModel::getSupportedServiceNames(); 412 413 sal_Int32 nOldLen = aSupported.getLength(); 414 aSupported.realloc( nOldLen + 8 ); 415 ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen; 416 417 *pStoreTo++ = BINDABLE_CONTROL_MODEL; 418 *pStoreTo++ = DATA_AWARE_CONTROL_MODEL; 419 *pStoreTo++ = VALIDATABLE_CONTROL_MODEL; 420 421 *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL; 422 *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL; 423 424 *pStoreTo++ = FRM_SUN_COMPONENT_FORMATTEDFIELD; 425 *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD; 426 *pStoreTo++ = BINDABLE_DATABASE_FORMATTED_FIELD; 427 428 return aSupported; 429 } 430 431 // XAggregation 432 //------------------------------------------------------------------------------ 433 Any SAL_CALL OFormattedModel::queryAggregation(const Type& _rType) throw(RuntimeException) 434 { 435 Any aReturn = OEditBaseModel::queryAggregation( _rType ); 436 return aReturn.hasValue() ? aReturn : OErrorBroadcaster::queryInterface( _rType ); 437 } 438 439 // XTypeProvider 440 //------------------------------------------------------------------------------ 441 Sequence< Type > OFormattedModel::_getTypes() 442 { 443 return ::comphelper::concatSequences( 444 OEditBaseModel::_getTypes(), 445 OErrorBroadcaster::getTypes() 446 ); 447 } 448 449 // XPersistObject 450 //------------------------------------------------------------------------------ 451 ::rtl::OUString SAL_CALL OFormattedModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException) 452 { 453 return ::rtl::OUString(FRM_COMPONENT_EDIT); 454 } 455 456 // XPropertySet 457 //------------------------------------------------------------------------------ 458 void OFormattedModel::describeFixedProperties( Sequence< Property >& _rProps ) const 459 { 460 BEGIN_DESCRIBE_PROPERTIES( 3, OEditBaseModel ) 461 DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND); 462 DECL_PROP1(TABINDEX, sal_Int16, BOUND); 463 DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT); 464 END_DESCRIBE_PROPERTIES(); 465 } 466 467 //------------------------------------------------------------------------------ 468 void OFormattedModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const 469 { 470 OEditBaseModel::describeAggregateProperties( _rAggregateProps ); 471 472 // TreatAsNumeric nicht transient : wir wollen es an der UI anbinden (ist noetig, um dem EffectiveDefault 473 // - der kann Text oder Zahl sein - einen Sinn zu geben) 474 ModifyPropertyAttributes(_rAggregateProps, PROPERTY_TREATASNUMERIC, 0, PropertyAttribute::TRANSIENT); 475 // same for FormatKey 476 // (though the paragraph above for the TreatAsNumeric does not hold anymore - we do not have an UI for this. 477 // But we have for the format key ...) 478 // 25.06.2001 - 87862 - frank.schoenheit@sun.com 479 ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, PropertyAttribute::TRANSIENT); 480 481 RemoveProperty(_rAggregateProps, PROPERTY_STRICTFORMAT); 482 // no strict format property for formatted fields: it does not make sense, 'cause 483 // there is no general way to decide which characters/sub strings are allowed during the input of an 484 // arbitraryly formatted control 485 // 81441 - 12/07/00 - FS 486 } 487 488 //------------------------------------------------------------------------------ 489 void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const 490 { 491 OEditBaseModel::getFastPropertyValue(rValue, nHandle); 492 } 493 494 //------------------------------------------------------------------------------ 495 void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception) 496 { 497 OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue); 498 } 499 500 //------------------------------------------------------------------------------ 501 sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) 502 throw( IllegalArgumentException ) 503 { 504 return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); 505 } 506 507 //------------------------------------------------------------------------------ 508 void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle) 509 { 510 if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) 511 { 512 Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier(); 513 DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !"); 514 if (m_xAggregateSet.is()) 515 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier)); 516 } 517 else 518 OEditBaseModel::setPropertyToDefaultByHandle(nHandle); 519 } 520 521 //------------------------------------------------------------------------------ 522 void OFormattedModel::setPropertyToDefault(const ::rtl::OUString& aPropertyName) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException ) 523 { 524 OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper(); 525 sal_Int32 nHandle = rPH.getHandleByName( aPropertyName ); 526 527 if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) 528 setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER); 529 else 530 OEditBaseModel::setPropertyToDefault(aPropertyName); 531 } 532 533 //------------------------------------------------------------------------------ 534 Any OFormattedModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const 535 { 536 if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) 537 { 538 Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier(); 539 return makeAny(xSupplier); 540 } 541 else 542 return OEditBaseModel::getPropertyDefaultByHandle(nHandle); 543 } 544 545 //------------------------------------------------------------------------------ 546 Any SAL_CALL OFormattedModel::getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException ) 547 { 548 OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper(); 549 sal_Int32 nHandle = rPH.getHandleByName( aPropertyName ); 550 551 if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) 552 return getPropertyDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER); 553 else 554 return OEditBaseModel::getPropertyDefault(aPropertyName); 555 } 556 557 //------------------------------------------------------------------------------ 558 void OFormattedModel::_propertyChanged( const com::sun::star::beans::PropertyChangeEvent& evt ) throw(RuntimeException) 559 { 560 // TODO: check how this works with external bindings 561 562 OSL_ENSURE( evt.Source == m_xAggregateSet, "OFormattedModel::_propertyChanged: where did this come from?" ); 563 if ( evt.Source == m_xAggregateSet ) 564 { 565 Reference< XPropertySet > xSourceSet( evt.Source, UNO_QUERY ); 566 if ( evt.PropertyName.equals( PROPERTY_FORMATKEY ) ) 567 { 568 if ( evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG ) 569 { 570 try 571 { 572 ::osl::MutexGuard aGuard( m_aMutex ); 573 574 Reference<XNumberFormatsSupplier> xSupplier( calcFormatsSupplier() ); 575 m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), getINT32( evt.NewValue ) ); 576 577 // as m_aSaveValue (which is used by commitControlValueToDbColumn) is format dependent we have 578 // to recalc it, which is done by translateDbColumnToControlValue 579 if ( m_xColumn.is() && m_xAggregateFastSet.is() && !m_xCursor->isBeforeFirst() && !m_xCursor->isAfterLast()) 580 { 581 setControlValue( translateDbColumnToControlValue(), eOther ); 582 } 583 584 // if we're connected to an external value binding, then re-calculate the type 585 // used to exchange the value - it depends on the format, too 586 if ( hasExternalValueBinding() ) 587 { 588 calculateExternalValueType(); 589 } 590 } 591 catch(Exception&) 592 { 593 } 594 } 595 return; 596 } 597 598 if ( evt.PropertyName.equals( PROPERTY_FORMATSSUPPLIER ) ) 599 { 600 updateFormatterNullDate(); 601 return; 602 } 603 604 OBoundControlModel::_propertyChanged( evt ); 605 } 606 } 607 608 //------------------------------------------------------------------------------ 609 void OFormattedModel::updateFormatterNullDate() 610 { 611 // calc the current NULL date 612 Reference< XNumberFormatsSupplier > xSupplier( calcFormatsSupplier() ); 613 if ( xSupplier.is() ) 614 xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ) ) ) >>= m_aNullDate; 615 } 616 617 //------------------------------------------------------------------------------ 618 Reference< XNumberFormatsSupplier > OFormattedModel::calcFormatsSupplier() const 619 { 620 Reference<XNumberFormatsSupplier> xSupplier; 621 622 DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !"); 623 // hat mein aggregiertes Model einen FormatSupplier ? 624 if( m_xAggregateSet.is() ) 625 m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier; 626 627 if (!xSupplier.is()) 628 // check if my parent form has a supplier 629 xSupplier = calcFormFormatsSupplier(); 630 631 if (!xSupplier.is()) 632 xSupplier = calcDefaultFormatsSupplier(); 633 634 DBG_ASSERT(xSupplier.is(), "OFormattedModel::calcFormatsSupplier : no supplier !"); 635 // jetzt sollte aber einer da sein 636 return xSupplier; 637 } 638 639 //------------------------------------------------------------------------------ 640 Reference<XNumberFormatsSupplier> OFormattedModel::calcFormFormatsSupplier() const 641 { 642 Reference<XChild> xMe; 643 query_interface(static_cast<XWeak*>(const_cast<OFormattedModel*>(this)), xMe); 644 // damit stellen wir sicher, dass wir auch fuer den Fall der Aggregation das richtige 645 // Objekt bekommen 646 DBG_ASSERT(xMe.is(), "OFormattedModel::calcFormFormatsSupplier : I should have a content interface !"); 647 648 // jetzt durchhangeln nach oben, bis wir auf eine starform treffen (angefangen mit meinem eigenen Parent) 649 Reference<XChild> xParent(xMe->getParent(), UNO_QUERY); 650 Reference<XForm> xNextParentForm(xParent, UNO_QUERY); 651 while (!xNextParentForm.is() && xParent.is()) 652 { 653 xParent = xParent.query( xParent->getParent() ); 654 xNextParentForm = xNextParentForm.query( xParent ); 655 } 656 657 if (!xNextParentForm.is()) 658 { 659 DBG_ERROR("OFormattedModel::calcFormFormatsSupplier : have no ancestor which is a form !"); 660 return NULL; 661 } 662 663 // den FormatSupplier von meinem Vorfahren (falls der einen hat) 664 Reference< XRowSet > xRowSet( xNextParentForm, UNO_QUERY ); 665 Reference< XNumberFormatsSupplier > xSupplier; 666 if (xRowSet.is()) 667 xSupplier = getNumberFormats( getConnection(xRowSet), sal_True, getContext().getLegacyServiceFactory() ); 668 return xSupplier; 669 } 670 671 //------------------------------------------------------------------------------ 672 Reference< XNumberFormatsSupplier > OFormattedModel::calcDefaultFormatsSupplier() const 673 { 674 return StandardFormatsSupplier::get( getContext().getLegacyServiceFactory() ); 675 } 676 677 // XBoundComponent 678 //------------------------------------------------------------------------------ 679 void OFormattedModel::loaded(const EventObject& rEvent) throw ( ::com::sun::star::uno::RuntimeException) 680 { 681 // HACK : our onConnectedDbColumn accesses our NumberFormatter which locks the solar mutex (as it doesn't have 682 // an own one). To prevent deadlocks with other threads which may request a property from us in an 683 // UI-triggered action (e.g. an tooltip) we lock the solar mutex _here_ before our base class locks 684 // it's own muext (which is used for property requests) 685 // alternative a): we use two mutexes, one which is passed to the OPropertysetHelper and used for 686 // property requests and one for our own code. This would need a lot of code rewriting 687 // alternative b): The NumberFormatter has to be really threadsafe (with an own mutex), which is 688 // the only "clean" solution for me. 689 // FS - 69603 - 02.11.99 690 691 ::vos::OGuard aGuard(Application::GetSolarMutex()); 692 OEditBaseModel::loaded(rEvent); 693 } 694 695 //------------------------------------------------------------------------------ 696 void OFormattedModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) 697 { 698 m_xOriginalFormatter = NULL; 699 700 // get some properties of the field 701 m_nFieldType = DataType::OTHER; 702 Reference<XPropertySet> xField = getField(); 703 if ( xField.is() ) 704 xField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= m_nFieldType; 705 706 sal_Int32 nFormatKey = 0; 707 708 DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::onConnectedDbColumn : have no aggregate !"); 709 if (m_xAggregateSet.is()) 710 { // all the following doesn't make any sense if we have no aggregate ... 711 Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER); 712 DBG_ASSERT( aSupplier.hasValue(), "OFormattedModel::onConnectedDbColumn : invalid property value !" ); 713 // das sollte im Constructor oder im read auf was richtiges gesetzt worden sein 714 715 Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY); 716 if ( !(aFmtKey >>= nFormatKey ) ) 717 { // nobody gave us a format to use. So we examine the field we're bound to for a 718 // format key, and use it ourself, too 719 sal_Int32 nType = DataType::VARCHAR; 720 if (xField.is()) 721 { 722 aFmtKey = xField->getPropertyValue(PROPERTY_FORMATKEY); 723 xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType ; 724 } 725 726 Reference<XNumberFormatsSupplier> xSupplier = calcFormFormatsSupplier(); 727 DBG_ASSERT(xSupplier.is(), "OFormattedModel::onConnectedDbColumn : bound to a field but no parent with a formatter ? how this ?"); 728 if (xSupplier.is()) 729 { 730 m_bOriginalNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC)); 731 732 if (!aFmtKey.hasValue()) 733 { // we aren't bound to a field (or this field's format is invalid) 734 // -> determine the standard text (or numeric) format of the supplier 735 Reference<XNumberFormatTypes> xTypes(xSupplier->getNumberFormats(), UNO_QUERY); 736 if (xTypes.is()) 737 { 738 Locale aApplicationLocale = Application::GetSettings().GetUILocale(); 739 740 if (m_bOriginalNumeric) 741 aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::NUMBER, aApplicationLocale); 742 else 743 aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::TEXT, aApplicationLocale); 744 } 745 } 746 747 aSupplier >>= m_xOriginalFormatter; 748 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier)); 749 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, aFmtKey); 750 751 // das Numeric-Flag an mein gebundenes Feld anpassen 752 if (xField.is()) 753 { 754 m_bNumeric = sal_False; 755 switch (nType) 756 { 757 case DataType::BIT: 758 case DataType::BOOLEAN: 759 case DataType::TINYINT: 760 case DataType::SMALLINT: 761 case DataType::INTEGER: 762 case DataType::BIGINT: 763 case DataType::FLOAT: 764 case DataType::REAL: 765 case DataType::DOUBLE: 766 case DataType::NUMERIC: 767 case DataType::DECIMAL: 768 case DataType::DATE: 769 case DataType::TIME: 770 case DataType::TIMESTAMP: 771 m_bNumeric = sal_True; 772 break; 773 } 774 } 775 else 776 m_bNumeric = m_bOriginalNumeric; 777 778 setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bNumeric)); 779 780 OSL_VERIFY( aFmtKey >>= nFormatKey ); 781 } 782 } 783 } 784 785 Reference<XNumberFormatsSupplier> xSupplier = calcFormatsSupplier(); 786 m_bNumeric = getBOOL( getPropertyValue( PROPERTY_TREATASNUMERIC ) ); 787 m_nKeyType = getNumberFormatType( xSupplier->getNumberFormats(), nFormatKey ); 788 xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString::createFromAscii("NullDate") ) >>= m_aNullDate; 789 790 OEditBaseModel::onConnectedDbColumn( _rxForm ); 791 } 792 793 //------------------------------------------------------------------------------ 794 void OFormattedModel::onDisconnectedDbColumn() 795 { 796 OEditBaseModel::onDisconnectedDbColumn(); 797 if (m_xOriginalFormatter.is()) 798 { // unser aggregiertes Model hatte keinerlei Format-Informationen 799 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(m_xOriginalFormatter)); 800 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, Any()); 801 setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bOriginalNumeric)); 802 m_xOriginalFormatter = NULL; 803 } 804 805 m_nFieldType = DataType::OTHER; 806 m_nKeyType = NumberFormat::UNDEFINED; 807 m_aNullDate = DBTypeConversion::getStandardDate(); 808 } 809 810 //------------------------------------------------------------------------------ 811 void OFormattedModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 812 { 813 OEditBaseModel::write(_rxOutStream); 814 _rxOutStream->writeShort(0x0003); 815 816 DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::write : have no aggregate !"); 817 818 // mein Format (evtl. void) in ein persistentes Format bringen (der Supplier zusammen mit dem Key ist es zwar auch, 819 // aber deswegen muessen wir ja nicht gleich den ganzen Supplier speichern, das waere ein klein wenig Overhead ;) 820 821 Reference<XNumberFormatsSupplier> xSupplier; 822 Any aFmtKey; 823 sal_Bool bVoidKey = sal_True; 824 if (m_xAggregateSet.is()) 825 { 826 Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER); 827 if (aSupplier.getValueType().getTypeClass() != TypeClass_VOID) 828 { 829 OSL_VERIFY( aSupplier >>= xSupplier ); 830 } 831 832 aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY); 833 bVoidKey = (!xSupplier.is() || !aFmtKey.hasValue()) || (isLoaded() && m_xOriginalFormatter.is()); 834 // (kein Fomatter und/oder Key) oder (loaded und faked Formatter) 835 } 836 837 _rxOutStream->writeBoolean(!bVoidKey); 838 if (!bVoidKey) 839 { 840 // aus dem FormatKey und dem Formatter persistente Angaben basteln 841 842 Any aKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY); 843 sal_Int32 nKey = aKey.hasValue() ? getINT32(aKey) : 0; 844 845 Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats(); 846 847 ::rtl::OUString sFormatDescription; 848 LanguageType eFormatLanguage = LANGUAGE_DONTKNOW; 849 850 static const ::rtl::OUString s_aLocaleProp = ::rtl::OUString::createFromAscii("Locale"); 851 Reference<com::sun::star::beans::XPropertySet> xFormat = xFormats->getByKey(nKey); 852 if (hasProperty(s_aLocaleProp, xFormat)) 853 { 854 Any aLocale = xFormat->getPropertyValue(s_aLocaleProp); 855 DBG_ASSERT(isA(aLocale, static_cast<Locale*>(NULL)), "OFormattedModel::write : invalid language property !"); 856 if (isA(aLocale, static_cast<Locale*>(NULL))) 857 { 858 Locale* pLocale = (Locale*)aLocale.getValue(); 859 eFormatLanguage = MsLangId::convertLocaleToLanguage( *pLocale ); 860 } 861 } 862 863 static const ::rtl::OUString s_aFormatStringProp = ::rtl::OUString::createFromAscii("FormatString"); 864 if (hasProperty(s_aFormatStringProp, xFormat)) 865 xFormat->getPropertyValue(s_aFormatStringProp) >>= sFormatDescription; 866 867 _rxOutStream->writeUTF(sFormatDescription); 868 _rxOutStream->writeLong((sal_Int32)eFormatLanguage); 869 } 870 871 // version 2 : write the properties common to all OEditBaseModels 872 writeCommonEditProperties(_rxOutStream); 873 874 // version 3 : write the effective value property of the aggregate 875 // Due to a bug within the UnoControlFormattedFieldModel implementation (our default aggregate) this props value isn't correctly read 876 // and this can't be corrected without being incompatible. 877 // so we have our own handling. 878 879 // and to be a little bit more compatible we make the following section skippable 880 { 881 Reference< XDataOutputStream > xOut(_rxOutStream, UNO_QUERY); 882 OStreamSection aDownCompat(xOut); 883 884 // a sub version within the skippable block 885 _rxOutStream->writeShort(0x0000); 886 887 // version 0: the effective value of the aggregate 888 Any aEffectiveValue; 889 if (m_xAggregateSet.is()) 890 { 891 try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(Exception&) { } 892 } 893 894 { 895 OStreamSection aDownCompat2(xOut); 896 switch (aEffectiveValue.getValueType().getTypeClass()) 897 { 898 case TypeClass_STRING: 899 _rxOutStream->writeShort(0x0000); 900 _rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue)); 901 break; 902 case TypeClass_DOUBLE: 903 _rxOutStream->writeShort(0x0001); 904 _rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue)); 905 break; 906 default: // void and all unknown states 907 DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !"); 908 _rxOutStream->writeShort(0x0002); 909 break; 910 } 911 } 912 } 913 } 914 915 //------------------------------------------------------------------------------ 916 void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 917 { 918 OEditBaseModel::read(_rxInStream); 919 sal_uInt16 nVersion = _rxInStream->readShort(); 920 921 Reference<XNumberFormatsSupplier> xSupplier; 922 sal_Int32 nKey = -1; 923 switch (nVersion) 924 { 925 case 0x0001 : 926 case 0x0002 : 927 case 0x0003 : 928 { 929 sal_Bool bNonVoidKey = _rxInStream->readBoolean(); 930 if (bNonVoidKey) 931 { 932 // den String und die Language lesen .... 933 ::rtl::OUString sFormatDescription = _rxInStream->readUTF(); 934 LanguageType eDescriptionLanguage = (LanguageType)_rxInStream->readLong(); 935 936 // und daraus von einem Formatter zu einem Key zusammenwuerfeln lassen ... 937 xSupplier = calcFormatsSupplier(); 938 // calcFormatsSupplier nimmt erst den vom Model, dann einen von der starform, dann einen ganz neuen .... 939 Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats(); 940 941 if (xFormats.is()) 942 { 943 Locale aDescriptionLanguage( MsLangId::convertLanguageToLocale(eDescriptionLanguage)); 944 945 nKey = xFormats->queryKey(sFormatDescription, aDescriptionLanguage, sal_False); 946 if (nKey == (sal_Int32)-1) 947 { // noch nicht vorhanden in meinem Formatter ... 948 nKey = xFormats->addNew(sFormatDescription, aDescriptionLanguage); 949 } 950 } 951 } 952 if ((nVersion == 0x0002) || (nVersion == 0x0003)) 953 readCommonEditProperties(_rxInStream); 954 955 if (nVersion == 0x0003) 956 { // since version 3 there is a "skippable" block at this position 957 Reference< XDataInputStream > xIn(_rxInStream, UNO_QUERY); 958 OStreamSection aDownCompat(xIn); 959 960 sal_Int16 nSubVersion = _rxInStream->readShort(); 961 (void)nSubVersion; 962 963 // version 0 and higher : the "effective value" property 964 Any aEffectiveValue; 965 { 966 OStreamSection aDownCompat2(xIn); 967 switch (_rxInStream->readShort()) 968 { 969 case 0: // String 970 aEffectiveValue <<= _rxInStream->readUTF(); 971 break; 972 case 1: // double 973 aEffectiveValue <<= (double)_rxInStream->readDouble(); 974 break; 975 case 2: 976 break; 977 case 3: 978 DBG_ERROR("FmXFormattedModel::read : unknown effective value type !"); 979 } 980 } 981 982 // this property is only to be set if we have no control source : in all other cases the base class did a 983 // reset after it's read and this set the effective value to a default value 984 if ( m_xAggregateSet.is() && ( getControlSource().getLength() == 0 ) ) 985 { 986 try 987 { 988 m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue); 989 } 990 catch(Exception&) 991 { 992 } 993 } 994 } 995 } 996 break; 997 default : 998 DBG_ERROR("OFormattedModel::read : unknown version !"); 999 // dann bleibt das Format des aggregierten Sets, wie es bei der Erzeugung ist : void 1000 defaultCommonEditProperties(); 1001 break; 1002 } 1003 1004 if ((nKey != -1) && m_xAggregateSet.is()) 1005 { 1006 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier)); 1007 m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey)); 1008 } 1009 else 1010 { 1011 setPropertyToDefault(PROPERTY_FORMATSSUPPLIER); 1012 setPropertyToDefault(PROPERTY_FORMATKEY); 1013 } 1014 } 1015 1016 //------------------------------------------------------------------------------ 1017 sal_uInt16 OFormattedModel::getPersistenceFlags() const 1018 { 1019 return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS); 1020 // a) we do our own call to writeCommonEditProperties 1021 } 1022 1023 //------------------------------------------------------------------------------ 1024 sal_Bool OFormattedModel::commitControlValueToDbColumn( bool /*_bPostReset*/ ) 1025 { 1026 Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) ); 1027 if ( aControlValue != m_aSaveValue ) 1028 { 1029 // Leerstring + EmptyIsNull = void 1030 if ( !aControlValue.hasValue() 1031 || ( ( aControlValue.getValueType().getTypeClass() == TypeClass_STRING ) 1032 && ( getString( aControlValue ).getLength() == 0 ) 1033 && m_bEmptyIsNull 1034 ) 1035 ) 1036 m_xColumnUpdate->updateNull(); 1037 else 1038 { 1039 try 1040 { 1041 double f = 0.0; 1042 if ( aControlValue.getValueType().getTypeClass() == TypeClass_DOUBLE || (aControlValue >>= f)) // #i110323 1043 { 1044 DBTypeConversion::setValue( m_xColumnUpdate, m_aNullDate, getDouble( aControlValue ), m_nKeyType ); 1045 } 1046 else 1047 { 1048 DBG_ASSERT( aControlValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::commitControlValueToDbColumn: invalud value type !" ); 1049 m_xColumnUpdate->updateString( getString( aControlValue ) ); 1050 } 1051 } 1052 catch(Exception&) 1053 { 1054 return sal_False; 1055 } 1056 } 1057 m_aSaveValue = aControlValue; 1058 } 1059 return sal_True; 1060 } 1061 1062 //------------------------------------------------------------------------------ 1063 void OFormattedModel::onConnectedExternalValue( ) 1064 { 1065 OEditBaseModel::onConnectedExternalValue(); 1066 updateFormatterNullDate(); 1067 } 1068 1069 //------------------------------------------------------------------------------ 1070 Any OFormattedModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const 1071 { 1072 Any aControlValue; 1073 switch( _rExternalValue.getValueTypeClass() ) 1074 { 1075 case TypeClass_VOID: 1076 break; 1077 1078 case TypeClass_STRING: 1079 aControlValue = _rExternalValue; 1080 break; 1081 1082 case TypeClass_BOOLEAN: 1083 { 1084 sal_Bool bExternalValue = sal_False; 1085 _rExternalValue >>= bExternalValue; 1086 aControlValue <<= (double)( bExternalValue ? 1 : 0 ); 1087 } 1088 break; 1089 1090 default: 1091 { 1092 if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) ) 1093 { 1094 UNODate aDate; 1095 _rExternalValue >>= aDate; 1096 aControlValue <<= DBTypeConversion::toDouble( aDate, m_aNullDate ); 1097 } 1098 else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) ) 1099 { 1100 UNOTime aTime; 1101 _rExternalValue >>= aTime; 1102 aControlValue <<= DBTypeConversion::toDouble( aTime ); 1103 } 1104 else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) ) 1105 { 1106 UNODateTime aDateTime; 1107 _rExternalValue >>= aDateTime; 1108 aControlValue <<= DBTypeConversion::toDouble( aDateTime, m_aNullDate ); 1109 } 1110 else 1111 { 1112 OSL_ENSURE( _rExternalValue.getValueTypeClass() == TypeClass_DOUBLE, 1113 "OFormattedModel::translateExternalValueToControlValue: don't know how to translate this type!" ); 1114 double fValue = 0; 1115 OSL_VERIFY( _rExternalValue >>= fValue ); 1116 aControlValue <<= fValue; 1117 } 1118 } 1119 } 1120 1121 return aControlValue; 1122 } 1123 1124 //------------------------------------------------------------------------------ 1125 Any OFormattedModel::translateControlValueToExternalValue( ) const 1126 { 1127 OSL_PRECOND( hasExternalValueBinding(), 1128 "OFormattedModel::translateControlValueToExternalValue: precondition not met!" ); 1129 1130 Any aControlValue( getControlValue() ); 1131 if ( !aControlValue.hasValue() ) 1132 return aControlValue; 1133 1134 Any aExternalValue; 1135 1136 // translate into the the external value type 1137 Type aExternalValueType( getExternalValueType() ); 1138 switch ( aExternalValueType.getTypeClass() ) 1139 { 1140 case TypeClass_STRING: 1141 { 1142 ::rtl::OUString sString; 1143 if ( aControlValue >>= sString ) 1144 { 1145 aExternalValue <<= sString; 1146 break; 1147 } 1148 } 1149 // NO break here! 1150 1151 case TypeClass_BOOLEAN: 1152 { 1153 double fValue = 0; 1154 OSL_VERIFY( aControlValue >>= fValue ); 1155 // if this asserts ... well, the somebody set the TreatAsNumeric property to false, 1156 // and the control value is a string. This implies some weird misconfiguration 1157 // of the FormattedModel, so we won't care for it for the moment. 1158 aExternalValue <<= (sal_Bool)( fValue ? sal_True : sal_False ); 1159 } 1160 break; 1161 1162 default: 1163 { 1164 double fValue = 0; 1165 OSL_VERIFY( aControlValue >>= fValue ); 1166 // if this asserts ... well, the somebody set the TreatAsNumeric property to false, 1167 // and the control value is a string. This implies some weird misconfiguration 1168 // of the FormattedModel, so we won't care for it for the moment. 1169 1170 if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) ) 1171 { 1172 aExternalValue <<= DBTypeConversion::toDate( fValue, m_aNullDate ); 1173 } 1174 else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) ) 1175 { 1176 aExternalValue <<= DBTypeConversion::toTime( fValue ); 1177 } 1178 else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) ) 1179 { 1180 aExternalValue <<= DBTypeConversion::toDateTime( fValue, m_aNullDate ); 1181 } 1182 else 1183 { 1184 OSL_ENSURE( aExternalValueType.equals( ::getCppuType( static_cast< double* >( NULL ) ) ), 1185 "OFormattedModel::translateControlValueToExternalValue: don't know how to translate this type!" ); 1186 aExternalValue <<= fValue; 1187 } 1188 } 1189 break; 1190 } 1191 return aExternalValue; 1192 } 1193 1194 //------------------------------------------------------------------------------ 1195 Any OFormattedModel::translateDbColumnToControlValue() 1196 { 1197 if ( m_bNumeric ) 1198 m_aSaveValue <<= DBTypeConversion::getValue( m_xColumn, m_aNullDate ); // #100056# OJ 1199 else 1200 m_aSaveValue <<= m_xColumn->getString(); 1201 1202 if ( m_xColumn->wasNull() ) 1203 m_aSaveValue.clear(); 1204 1205 return m_aSaveValue; 1206 } 1207 1208 // ----------------------------------------------------------------------------- 1209 Sequence< Type > OFormattedModel::getSupportedBindingTypes() 1210 { 1211 ::std::list< Type > aTypes; 1212 aTypes.push_back( ::getCppuType( static_cast< double* >( NULL ) ) ); 1213 1214 switch ( m_nKeyType & ~NumberFormat::DEFINED ) 1215 { 1216 case NumberFormat::DATE: 1217 aTypes.push_front(::getCppuType( static_cast< UNODate* >( NULL ) ) ); 1218 break; 1219 case NumberFormat::TIME: 1220 aTypes.push_front(::getCppuType( static_cast< UNOTime* >( NULL ) ) ); 1221 break; 1222 case NumberFormat::DATETIME: 1223 aTypes.push_front(::getCppuType( static_cast< UNODateTime* >( NULL ) ) ); 1224 break; 1225 case NumberFormat::TEXT: 1226 aTypes.push_front(::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ); 1227 break; 1228 case NumberFormat::LOGICAL: 1229 aTypes.push_front(::getCppuType( static_cast< sal_Bool* >( NULL ) ) ); 1230 break; 1231 } 1232 1233 Sequence< Type > aTypesRet( aTypes.size() ); 1234 ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() ); 1235 return aTypesRet; 1236 } 1237 1238 //------------------------------------------------------------------------------ 1239 Any OFormattedModel::getDefaultForReset() const 1240 { 1241 return m_xAggregateSet->getPropertyValue( PROPERTY_EFFECTIVE_DEFAULT ); 1242 } 1243 1244 //------------------------------------------------------------------------------ 1245 void OFormattedModel::resetNoBroadcast() 1246 { 1247 OEditBaseModel::resetNoBroadcast(); 1248 m_aSaveValue.clear(); 1249 } 1250 1251 //......................................................................... 1252 } 1253 //......................................................................... 1254