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