| /************************************************************** | |
| * | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| * | |
| *************************************************************/ | |
| // MARKER(update_precomp.py): autogen include statement, do not remove | |
| #include "precompiled_forms.hxx" | |
| #include "FormattedField.hxx" | |
| #include "services.hxx" | |
| #include "property.hrc" | |
| #include "property.hxx" | |
| #include "frm_resource.hxx" | |
| #include "frm_resource.hrc" | |
| #include "propertybaghelper.hxx" | |
| #include <comphelper/sequence.hxx> | |
| #include <comphelper/numbers.hxx> | |
| #include <connectivity/dbtools.hxx> | |
| #include <connectivity/dbconversion.hxx> | |
| #include <svl/zforlist.hxx> | |
| #include <svl/numuno.hxx> | |
| #include <vcl/svapp.hxx> | |
| #include <tools/debug.hxx> | |
| #include <tools/wintypes.hxx> | |
| #include <i18npool/mslangid.hxx> | |
| #include <rtl/textenc.h> | |
| #include <com/sun/star/sdbc/DataType.hpp> | |
| #include <com/sun/star/util/NumberFormat.hpp> | |
| #include <com/sun/star/util/Date.hpp> | |
| #include <com/sun/star/util/Time.hpp> | |
| #include <com/sun/star/awt/MouseEvent.hpp> | |
| #include <com/sun/star/form/XSubmit.hpp> | |
| #include <com/sun/star/awt/XWindow.hpp> | |
| #include <com/sun/star/awt/XKeyListener.hpp> | |
| #include <com/sun/star/form/FormComponentType.hpp> | |
| #include <com/sun/star/util/XNumberFormatsSupplier.hpp> | |
| #include <com/sun/star/util/XNumberFormatTypes.hpp> | |
| #include <com/sun/star/form/XForm.hpp> | |
| #include <com/sun/star/container/XIndexAccess.hpp> | |
| #include <vos/mutex.hxx> | |
| // needed as long as we use the SolarMutex | |
| #include <comphelper/streamsection.hxx> | |
| #include <cppuhelper/weakref.hxx> | |
| #include <unotools/desktopterminationobserver.hxx> | |
| #include <list> | |
| #include <algorithm> | |
| using namespace dbtools; | |
| using namespace ::com::sun::star::uno; | |
| using namespace ::com::sun::star::sdb; | |
| using namespace ::com::sun::star::sdbc; | |
| using namespace ::com::sun::star::sdbcx; | |
| using namespace ::com::sun::star::beans; | |
| using namespace ::com::sun::star::container; | |
| using namespace ::com::sun::star::form; | |
| using namespace ::com::sun::star::awt; | |
| using namespace ::com::sun::star::io; | |
| using namespace ::com::sun::star::lang; | |
| using namespace ::com::sun::star::util; | |
| using namespace ::com::sun::star::form::binding; | |
| namespace | |
| { | |
| typedef com::sun::star::util::Date UNODate; | |
| typedef com::sun::star::util::Time UNOTime; | |
| typedef com::sun::star::util::DateTime UNODateTime; | |
| } | |
| //......................................................................... | |
| namespace frm | |
| { | |
| /*************************************************************************/ | |
| class StandardFormatsSupplier : protected SvNumberFormatsSupplierObj, public ::utl::ITerminationListener | |
| { | |
| protected: | |
| SvNumberFormatter* m_pMyPrivateFormatter; | |
| static WeakReference< XNumberFormatsSupplier > s_xDefaultFormatsSupplier; | |
| public: | |
| static Reference< XNumberFormatsSupplier > get( const Reference< XMultiServiceFactory >& _rxORB ); | |
| using SvNumberFormatsSupplierObj::operator new; | |
| using SvNumberFormatsSupplierObj::operator delete; | |
| protected: | |
| StandardFormatsSupplier(const Reference<XMultiServiceFactory>& _rxFactory,LanguageType _eSysLanguage); | |
| ~StandardFormatsSupplier(); | |
| protected: | |
| virtual bool queryTermination() const; | |
| virtual void notifyTermination(); | |
| }; | |
| //------------------------------------------------------------------ | |
| WeakReference< XNumberFormatsSupplier > StandardFormatsSupplier::s_xDefaultFormatsSupplier; | |
| //------------------------------------------------------------------ | |
| StandardFormatsSupplier::StandardFormatsSupplier(const Reference< XMultiServiceFactory > & _rxFactory,LanguageType _eSysLanguage) | |
| :SvNumberFormatsSupplierObj() | |
| ,m_pMyPrivateFormatter(new SvNumberFormatter(_rxFactory, _eSysLanguage)) | |
| { | |
| SetNumberFormatter(m_pMyPrivateFormatter); | |
| // #i29147# - 2004-06-18 - fs@openoffice.org | |
| ::utl::DesktopTerminationObserver::registerTerminationListener( this ); | |
| } | |
| //------------------------------------------------------------------ | |
| StandardFormatsSupplier::~StandardFormatsSupplier() | |
| { | |
| ::utl::DesktopTerminationObserver::revokeTerminationListener( this ); | |
| DELETEZ( m_pMyPrivateFormatter ); | |
| } | |
| //------------------------------------------------------------------ | |
| Reference< XNumberFormatsSupplier > StandardFormatsSupplier::get( const Reference< XMultiServiceFactory >& _rxORB ) | |
| { | |
| LanguageType eSysLanguage = LANGUAGE_SYSTEM; | |
| { | |
| ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); | |
| Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier; | |
| if ( xSupplier.is() ) | |
| return xSupplier; | |
| // get the Office's locale | |
| const Locale& rSysLocale = SvtSysLocale().GetLocaleData().getLocale(); | |
| // translate | |
| eSysLanguage = MsLangId::convertLocaleToLanguage( rSysLocale ); | |
| } | |
| StandardFormatsSupplier* pSupplier = new StandardFormatsSupplier( _rxORB, eSysLanguage ); | |
| Reference< XNumberFormatsSupplier > xNewlyCreatedSupplier( pSupplier ); | |
| { | |
| ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); | |
| Reference< XNumberFormatsSupplier > xSupplier = s_xDefaultFormatsSupplier; | |
| if ( xSupplier.is() ) | |
| // somebody used the small time frame where the mutex was not locked to create and set | |
| // the supplier | |
| return xSupplier; | |
| s_xDefaultFormatsSupplier = xNewlyCreatedSupplier; | |
| } | |
| return xNewlyCreatedSupplier; | |
| } | |
| //------------------------------------------------------------------ | |
| bool StandardFormatsSupplier::queryTermination() const | |
| { | |
| return true; | |
| } | |
| //------------------------------------------------------------------ | |
| void StandardFormatsSupplier::notifyTermination() | |
| { | |
| Reference< XNumberFormatsSupplier > xKeepAlive = this; | |
| // when the application is terminating, release our static reference so that we are cleared/destructed | |
| // earlier than upon unloading the library | |
| // #i29147# - 2004-06-18 - fs@openoffice.org | |
| s_xDefaultFormatsSupplier = WeakReference< XNumberFormatsSupplier >( ); | |
| SetNumberFormatter( NULL ); | |
| DELETEZ( m_pMyPrivateFormatter ); | |
| } | |
| /*************************************************************************/ | |
| //------------------------------------------------------------------ | |
| InterfaceRef SAL_CALL OFormattedControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) | |
| { | |
| return *(new OFormattedControl(_rxFactory)); | |
| } | |
| //------------------------------------------------------------------ | |
| Sequence<Type> OFormattedControl::_getTypes() | |
| { | |
| return ::comphelper::concatSequences( | |
| OFormattedControl_BASE::getTypes(), | |
| OBoundControl::_getTypes() | |
| ); | |
| } | |
| //------------------------------------------------------------------ | |
| Any SAL_CALL OFormattedControl::queryAggregation(const Type& _rType) throw (RuntimeException) | |
| { | |
| Any aReturn = OBoundControl::queryAggregation(_rType); | |
| if (!aReturn.hasValue()) | |
| aReturn = OFormattedControl_BASE::queryInterface(_rType); | |
| return aReturn; | |
| } | |
| DBG_NAME(OFormattedControl); | |
| //------------------------------------------------------------------------------ | |
| OFormattedControl::OFormattedControl(const Reference<XMultiServiceFactory>& _rxFactory) | |
| :OBoundControl(_rxFactory, VCL_CONTROL_FORMATTEDFIELD) | |
| ,m_nKeyEvent(0) | |
| { | |
| DBG_CTOR(OFormattedControl,NULL); | |
| increment(m_refCount); | |
| { | |
| Reference<XWindow> xComp; | |
| if (query_aggregation(m_xAggregate, xComp)) | |
| { | |
| xComp->addKeyListener(this); | |
| } | |
| } | |
| decrement(m_refCount); | |
| } | |
| //------------------------------------------------------------------------------ | |
| OFormattedControl::~OFormattedControl() | |
| { | |
| if( m_nKeyEvent ) | |
| Application::RemoveUserEvent( m_nKeyEvent ); | |
| if (!OComponentHelper::rBHelper.bDisposed) | |
| { | |
| acquire(); | |
| dispose(); | |
| } | |
| DBG_DTOR(OFormattedControl,NULL); | |
| } | |
| // XKeyListener | |
| //------------------------------------------------------------------------------ | |
| void OFormattedControl::disposing(const EventObject& _rSource) throw(RuntimeException) | |
| { | |
| OBoundControl::disposing(_rSource); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException) | |
| { | |
| if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 ) | |
| return; | |
| // Steht das Control in einem Formular mit einer Submit-URL? | |
| Reference<com::sun::star::beans::XPropertySet> xSet(getModel(), UNO_QUERY); | |
| if( !xSet.is() ) | |
| return; | |
| Reference<XFormComponent> xFComp(xSet, UNO_QUERY); | |
| InterfaceRef xParent = xFComp->getParent(); | |
| if( !xParent.is() ) | |
| return; | |
| Reference<com::sun::star::beans::XPropertySet> xFormSet(xParent, UNO_QUERY); | |
| if( !xFormSet.is() ) | |
| return; | |
| Any aTmp(xFormSet->getPropertyValue( PROPERTY_TARGET_URL )); | |
| if (!isA(aTmp, static_cast< ::rtl::OUString* >(NULL)) || | |
| !getString(aTmp).getLength() ) | |
| return; | |
| Reference<XIndexAccess> xElements(xParent, UNO_QUERY); | |
| sal_Int32 nCount = xElements->getCount(); | |
| if( nCount > 1 ) | |
| { | |
| Reference<com::sun::star::beans::XPropertySet> xFCSet; | |
| for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ ) | |
| { | |
| // Any aElement(xElements->getByIndex(nIndex)); | |
| xElements->getByIndex(nIndex) >>= xFCSet; | |
| if (hasProperty(PROPERTY_CLASSID, xFCSet) && | |
| getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD) | |
| { | |
| // Noch ein weiteres Edit gefunden ==> dann nicht submitten | |
| if (xFCSet != xSet) | |
| return; | |
| } | |
| } | |
| } | |
| // Da wir noch im Haender stehen, submit asynchron ausloesen | |
| if( m_nKeyEvent ) | |
| Application::RemoveUserEvent( m_nKeyEvent ); | |
| m_nKeyEvent = Application::PostUserEvent( LINK(this, OFormattedControl, | |
| OnKeyPressed) ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException) | |
| { | |
| } | |
| //------------------------------------------------------------------------------ | |
| IMPL_LINK(OFormattedControl, OnKeyPressed, void*, /*EMPTYARG*/) | |
| { | |
| m_nKeyEvent = 0; | |
| Reference<XFormComponent> xFComp(getModel(), UNO_QUERY); | |
| InterfaceRef xParent = xFComp->getParent(); | |
| Reference<XSubmit> xSubmit(xParent, UNO_QUERY); | |
| if (xSubmit.is()) | |
| xSubmit->submit( Reference<XControl> (), ::com::sun::star::awt::MouseEvent() ); | |
| return 0L; | |
| } | |
| //------------------------------------------------------------------------------ | |
| StringSequence OFormattedControl::getSupportedServiceNames() throw() | |
| { | |
| StringSequence aSupported = OBoundControl::getSupportedServiceNames(); | |
| aSupported.realloc(aSupported.getLength() + 1); | |
| ::rtl::OUString*pArray = aSupported.getArray(); | |
| pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_FORMATTEDFIELD; | |
| return aSupported; | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedControl::setDesignMode(sal_Bool bOn) throw ( ::com::sun::star::uno::RuntimeException) | |
| { | |
| OBoundControl::setDesignMode(bOn); | |
| } | |
| /*************************************************************************/ | |
| DBG_NAME(OFormattedModel) | |
| //------------------------------------------------------------------ | |
| void OFormattedModel::implConstruct() | |
| { | |
| // members | |
| m_bOriginalNumeric = sal_False; | |
| m_bNumeric = sal_False; | |
| m_xOriginalFormatter = NULL; | |
| m_nKeyType = NumberFormat::UNDEFINED; | |
| m_aNullDate = DBTypeConversion::getStandardDate(); | |
| m_nFieldType = DataType::OTHER; | |
| // default our formats supplier | |
| increment(m_refCount); | |
| setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER); | |
| decrement(m_refCount); | |
| startAggregatePropertyListening( PROPERTY_FORMATKEY ); | |
| startAggregatePropertyListening( PROPERTY_FORMATSSUPPLIER ); | |
| } | |
| //------------------------------------------------------------------ | |
| OFormattedModel::OFormattedModel(const Reference<XMultiServiceFactory>& _rxFactory) | |
| :OEditBaseModel(_rxFactory, VCL_CONTROLMODEL_FORMATTEDFIELD, FRM_SUN_CONTROL_FORMATTEDFIELD, sal_True, sal_True ) | |
| // use the old control name for compytibility reasons | |
| ,OErrorBroadcaster( OComponentHelper::rBHelper ) | |
| { | |
| DBG_CTOR(OFormattedModel, NULL); | |
| implConstruct(); | |
| m_nClassId = FormComponentType::TEXTFIELD; | |
| initValueProperty( PROPERTY_EFFECTIVE_VALUE, PROPERTY_ID_EFFECTIVE_VALUE ); | |
| } | |
| //------------------------------------------------------------------ | |
| OFormattedModel::OFormattedModel( const OFormattedModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory ) | |
| :OEditBaseModel( _pOriginal, _rxFactory ) | |
| ,OErrorBroadcaster( OComponentHelper::rBHelper ) | |
| { | |
| DBG_CTOR(OFormattedModel, NULL); | |
| implConstruct(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| OFormattedModel::~OFormattedModel() | |
| { | |
| DBG_DTOR(OFormattedModel, NULL); | |
| } | |
| // XCloneable | |
| //------------------------------------------------------------------------------ | |
| IMPLEMENT_DEFAULT_CLONING( OFormattedModel ) | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OFormattedModel::disposing() | |
| { | |
| OErrorBroadcaster::disposing(); | |
| OEditBaseModel::disposing(); | |
| } | |
| // XServiceInfo | |
| //------------------------------------------------------------------------------ | |
| StringSequence OFormattedModel::getSupportedServiceNames() throw() | |
| { | |
| StringSequence aSupported = OEditBaseModel::getSupportedServiceNames(); | |
| sal_Int32 nOldLen = aSupported.getLength(); | |
| aSupported.realloc( nOldLen + 8 ); | |
| ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen; | |
| *pStoreTo++ = BINDABLE_CONTROL_MODEL; | |
| *pStoreTo++ = DATA_AWARE_CONTROL_MODEL; | |
| *pStoreTo++ = VALIDATABLE_CONTROL_MODEL; | |
| *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL; | |
| *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL; | |
| *pStoreTo++ = FRM_SUN_COMPONENT_FORMATTEDFIELD; | |
| *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_FORMATTEDFIELD; | |
| *pStoreTo++ = BINDABLE_DATABASE_FORMATTED_FIELD; | |
| return aSupported; | |
| } | |
| // XAggregation | |
| //------------------------------------------------------------------------------ | |
| Any SAL_CALL OFormattedModel::queryAggregation(const Type& _rType) throw(RuntimeException) | |
| { | |
| Any aReturn = OEditBaseModel::queryAggregation( _rType ); | |
| return aReturn.hasValue() ? aReturn : OErrorBroadcaster::queryInterface( _rType ); | |
| } | |
| // XTypeProvider | |
| //------------------------------------------------------------------------------ | |
| Sequence< Type > OFormattedModel::_getTypes() | |
| { | |
| return ::comphelper::concatSequences( | |
| OEditBaseModel::_getTypes(), | |
| OErrorBroadcaster::getTypes() | |
| ); | |
| } | |
| // XPersistObject | |
| //------------------------------------------------------------------------------ | |
| ::rtl::OUString SAL_CALL OFormattedModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException) | |
| { | |
| return ::rtl::OUString(FRM_COMPONENT_EDIT); | |
| } | |
| // XPropertySet | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::describeFixedProperties( Sequence< Property >& _rProps ) const | |
| { | |
| BEGIN_DESCRIBE_PROPERTIES( 3, OEditBaseModel ) | |
| DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND); | |
| DECL_PROP1(TABINDEX, sal_Int16, BOUND); | |
| DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT); | |
| END_DESCRIBE_PROPERTIES(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const | |
| { | |
| OEditBaseModel::describeAggregateProperties( _rAggregateProps ); | |
| // TreatAsNumeric nicht transient : wir wollen es an der UI anbinden (ist noetig, um dem EffectiveDefault | |
| // - der kann Text oder Zahl sein - einen Sinn zu geben) | |
| ModifyPropertyAttributes(_rAggregateProps, PROPERTY_TREATASNUMERIC, 0, PropertyAttribute::TRANSIENT); | |
| // same for FormatKey | |
| // (though the paragraph above for the TreatAsNumeric does not hold anymore - we do not have an UI for this. | |
| // But we have for the format key ...) | |
| // 25.06.2001 - 87862 - frank.schoenheit@sun.com | |
| ModifyPropertyAttributes(_rAggregateProps, PROPERTY_FORMATKEY, 0, PropertyAttribute::TRANSIENT); | |
| RemoveProperty(_rAggregateProps, PROPERTY_STRICTFORMAT); | |
| // no strict format property for formatted fields: it does not make sense, 'cause | |
| // there is no general way to decide which characters/sub strings are allowed during the input of an | |
| // arbitraryly formatted control | |
| // 81441 - 12/07/00 - FS | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const | |
| { | |
| OEditBaseModel::getFastPropertyValue(rValue, nHandle); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception) | |
| { | |
| OEditBaseModel::setFastPropertyValue_NoBroadcast(nHandle, rValue); | |
| } | |
| //------------------------------------------------------------------------------ | |
| sal_Bool OFormattedModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) | |
| throw( IllegalArgumentException ) | |
| { | |
| return OEditBaseModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::setPropertyToDefaultByHandle(sal_Int32 nHandle) | |
| { | |
| if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) | |
| { | |
| Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier(); | |
| DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::setPropertyToDefaultByHandle(FORMATSSUPPLIER) : have no aggregate !"); | |
| if (m_xAggregateSet.is()) | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier)); | |
| } | |
| else | |
| OEditBaseModel::setPropertyToDefaultByHandle(nHandle); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::setPropertyToDefault(const ::rtl::OUString& aPropertyName) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException ) | |
| { | |
| OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper(); | |
| sal_Int32 nHandle = rPH.getHandleByName( aPropertyName ); | |
| if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) | |
| setPropertyToDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER); | |
| else | |
| OEditBaseModel::setPropertyToDefault(aPropertyName); | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any OFormattedModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const | |
| { | |
| if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) | |
| { | |
| Reference<XNumberFormatsSupplier> xSupplier = calcDefaultFormatsSupplier(); | |
| return makeAny(xSupplier); | |
| } | |
| else | |
| return OEditBaseModel::getPropertyDefaultByHandle(nHandle); | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any SAL_CALL OFormattedModel::getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw( com::sun::star::beans::UnknownPropertyException, RuntimeException ) | |
| { | |
| OPropertyArrayAggregationHelper& rPH = m_aPropertyBagHelper.getInfoHelper(); | |
| sal_Int32 nHandle = rPH.getHandleByName( aPropertyName ); | |
| if (nHandle == PROPERTY_ID_FORMATSSUPPLIER) | |
| return getPropertyDefaultByHandle(PROPERTY_ID_FORMATSSUPPLIER); | |
| else | |
| return OEditBaseModel::getPropertyDefault(aPropertyName); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::_propertyChanged( const com::sun::star::beans::PropertyChangeEvent& evt ) throw(RuntimeException) | |
| { | |
| // TODO: check how this works with external bindings | |
| OSL_ENSURE( evt.Source == m_xAggregateSet, "OFormattedModel::_propertyChanged: where did this come from?" ); | |
| if ( evt.Source == m_xAggregateSet ) | |
| { | |
| Reference< XPropertySet > xSourceSet( evt.Source, UNO_QUERY ); | |
| if ( evt.PropertyName.equals( PROPERTY_FORMATKEY ) ) | |
| { | |
| if ( evt.NewValue.getValueType().getTypeClass() == TypeClass_LONG ) | |
| { | |
| try | |
| { | |
| ::osl::MutexGuard aGuard( m_aMutex ); | |
| Reference<XNumberFormatsSupplier> xSupplier( calcFormatsSupplier() ); | |
| m_nKeyType = getNumberFormatType(xSupplier->getNumberFormats(), getINT32( evt.NewValue ) ); | |
| // as m_aSaveValue (which is used by commitControlValueToDbColumn) is format dependent we have | |
| // to recalc it, which is done by translateDbColumnToControlValue | |
| if ( m_xColumn.is() && m_xAggregateFastSet.is() && !m_xCursor->isBeforeFirst() && !m_xCursor->isAfterLast()) | |
| { | |
| setControlValue( translateDbColumnToControlValue(), eOther ); | |
| } | |
| // if we're connected to an external value binding, then re-calculate the type | |
| // used to exchange the value - it depends on the format, too | |
| if ( hasExternalValueBinding() ) | |
| { | |
| calculateExternalValueType(); | |
| } | |
| } | |
| catch(Exception&) | |
| { | |
| } | |
| } | |
| return; | |
| } | |
| if ( evt.PropertyName.equals( PROPERTY_FORMATSSUPPLIER ) ) | |
| { | |
| updateFormatterNullDate(); | |
| return; | |
| } | |
| OBoundControlModel::_propertyChanged( evt ); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::updateFormatterNullDate() | |
| { | |
| // calc the current NULL date | |
| Reference< XNumberFormatsSupplier > xSupplier( calcFormatsSupplier() ); | |
| if ( xSupplier.is() ) | |
| xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ) ) ) >>= m_aNullDate; | |
| } | |
| //------------------------------------------------------------------------------ | |
| Reference< XNumberFormatsSupplier > OFormattedModel::calcFormatsSupplier() const | |
| { | |
| Reference<XNumberFormatsSupplier> xSupplier; | |
| DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::calcFormatsSupplier : have no aggregate !"); | |
| // hat mein aggregiertes Model einen FormatSupplier ? | |
| if( m_xAggregateSet.is() ) | |
| m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xSupplier; | |
| if (!xSupplier.is()) | |
| // check if my parent form has a supplier | |
| xSupplier = calcFormFormatsSupplier(); | |
| if (!xSupplier.is()) | |
| xSupplier = calcDefaultFormatsSupplier(); | |
| DBG_ASSERT(xSupplier.is(), "OFormattedModel::calcFormatsSupplier : no supplier !"); | |
| // jetzt sollte aber einer da sein | |
| return xSupplier; | |
| } | |
| //------------------------------------------------------------------------------ | |
| Reference<XNumberFormatsSupplier> OFormattedModel::calcFormFormatsSupplier() const | |
| { | |
| Reference<XChild> xMe; | |
| query_interface(static_cast<XWeak*>(const_cast<OFormattedModel*>(this)), xMe); | |
| // damit stellen wir sicher, dass wir auch fuer den Fall der Aggregation das richtige | |
| // Objekt bekommen | |
| DBG_ASSERT(xMe.is(), "OFormattedModel::calcFormFormatsSupplier : I should have a content interface !"); | |
| // jetzt durchhangeln nach oben, bis wir auf eine starform treffen (angefangen mit meinem eigenen Parent) | |
| Reference<XChild> xParent(xMe->getParent(), UNO_QUERY); | |
| Reference<XForm> xNextParentForm(xParent, UNO_QUERY); | |
| while (!xNextParentForm.is() && xParent.is()) | |
| { | |
| xParent = xParent.query( xParent->getParent() ); | |
| xNextParentForm = xNextParentForm.query( xParent ); | |
| } | |
| if (!xNextParentForm.is()) | |
| { | |
| DBG_ERROR("OFormattedModel::calcFormFormatsSupplier : have no ancestor which is a form !"); | |
| return NULL; | |
| } | |
| // den FormatSupplier von meinem Vorfahren (falls der einen hat) | |
| Reference< XRowSet > xRowSet( xNextParentForm, UNO_QUERY ); | |
| Reference< XNumberFormatsSupplier > xSupplier; | |
| if (xRowSet.is()) | |
| xSupplier = getNumberFormats( getConnection(xRowSet), sal_True, getContext().getLegacyServiceFactory() ); | |
| return xSupplier; | |
| } | |
| //------------------------------------------------------------------------------ | |
| Reference< XNumberFormatsSupplier > OFormattedModel::calcDefaultFormatsSupplier() const | |
| { | |
| return StandardFormatsSupplier::get( getContext().getLegacyServiceFactory() ); | |
| } | |
| // XBoundComponent | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::loaded(const EventObject& rEvent) throw ( ::com::sun::star::uno::RuntimeException) | |
| { | |
| // HACK : our onConnectedDbColumn accesses our NumberFormatter which locks the solar mutex (as it doesn't have | |
| // an own one). To prevent deadlocks with other threads which may request a property from us in an | |
| // UI-triggered action (e.g. an tooltip) we lock the solar mutex _here_ before our base class locks | |
| // it's own muext (which is used for property requests) | |
| // alternative a): we use two mutexes, one which is passed to the OPropertysetHelper and used for | |
| // property requests and one for our own code. This would need a lot of code rewriting | |
| // alternative b): The NumberFormatter has to be really threadsafe (with an own mutex), which is | |
| // the only "clean" solution for me. | |
| // FS - 69603 - 02.11.99 | |
| ::vos::OGuard aGuard(Application::GetSolarMutex()); | |
| OEditBaseModel::loaded(rEvent); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) | |
| { | |
| m_xOriginalFormatter = NULL; | |
| // get some properties of the field | |
| m_nFieldType = DataType::OTHER; | |
| Reference<XPropertySet> xField = getField(); | |
| if ( xField.is() ) | |
| xField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= m_nFieldType; | |
| sal_Int32 nFormatKey = 0; | |
| DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::onConnectedDbColumn : have no aggregate !"); | |
| if (m_xAggregateSet.is()) | |
| { // all the following doesn't make any sense if we have no aggregate ... | |
| Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER); | |
| DBG_ASSERT( aSupplier.hasValue(), "OFormattedModel::onConnectedDbColumn : invalid property value !" ); | |
| // das sollte im Constructor oder im read auf was richtiges gesetzt worden sein | |
| Any aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY); | |
| if ( !(aFmtKey >>= nFormatKey ) ) | |
| { // nobody gave us a format to use. So we examine the field we're bound to for a | |
| // format key, and use it ourself, too | |
| sal_Int32 nType = DataType::VARCHAR; | |
| if (xField.is()) | |
| { | |
| aFmtKey = xField->getPropertyValue(PROPERTY_FORMATKEY); | |
| xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType ; | |
| } | |
| Reference<XNumberFormatsSupplier> xSupplier = calcFormFormatsSupplier(); | |
| DBG_ASSERT(xSupplier.is(), "OFormattedModel::onConnectedDbColumn : bound to a field but no parent with a formatter ? how this ?"); | |
| if (xSupplier.is()) | |
| { | |
| m_bOriginalNumeric = getBOOL(getPropertyValue(PROPERTY_TREATASNUMERIC)); | |
| if (!aFmtKey.hasValue()) | |
| { // we aren't bound to a field (or this field's format is invalid) | |
| // -> determine the standard text (or numeric) format of the supplier | |
| Reference<XNumberFormatTypes> xTypes(xSupplier->getNumberFormats(), UNO_QUERY); | |
| if (xTypes.is()) | |
| { | |
| Locale aApplicationLocale = Application::GetSettings().GetUILocale(); | |
| if (m_bOriginalNumeric) | |
| aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::NUMBER, aApplicationLocale); | |
| else | |
| aFmtKey <<= (sal_Int32)xTypes->getStandardFormat(NumberFormat::TEXT, aApplicationLocale); | |
| } | |
| } | |
| aSupplier >>= m_xOriginalFormatter; | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier)); | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, aFmtKey); | |
| // das Numeric-Flag an mein gebundenes Feld anpassen | |
| if (xField.is()) | |
| { | |
| m_bNumeric = sal_False; | |
| switch (nType) | |
| { | |
| case DataType::BIT: | |
| case DataType::BOOLEAN: | |
| case DataType::TINYINT: | |
| case DataType::SMALLINT: | |
| case DataType::INTEGER: | |
| case DataType::BIGINT: | |
| case DataType::FLOAT: | |
| case DataType::REAL: | |
| case DataType::DOUBLE: | |
| case DataType::NUMERIC: | |
| case DataType::DECIMAL: | |
| case DataType::DATE: | |
| case DataType::TIME: | |
| case DataType::TIMESTAMP: | |
| m_bNumeric = sal_True; | |
| break; | |
| } | |
| } | |
| else | |
| m_bNumeric = m_bOriginalNumeric; | |
| setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bNumeric)); | |
| OSL_VERIFY( aFmtKey >>= nFormatKey ); | |
| } | |
| } | |
| } | |
| Reference<XNumberFormatsSupplier> xSupplier = calcFormatsSupplier(); | |
| m_bNumeric = getBOOL( getPropertyValue( PROPERTY_TREATASNUMERIC ) ); | |
| m_nKeyType = getNumberFormatType( xSupplier->getNumberFormats(), nFormatKey ); | |
| xSupplier->getNumberFormatSettings()->getPropertyValue( ::rtl::OUString::createFromAscii("NullDate") ) >>= m_aNullDate; | |
| OEditBaseModel::onConnectedDbColumn( _rxForm ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::onDisconnectedDbColumn() | |
| { | |
| OEditBaseModel::onDisconnectedDbColumn(); | |
| if (m_xOriginalFormatter.is()) | |
| { // unser aggregiertes Model hatte keinerlei Format-Informationen | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(m_xOriginalFormatter)); | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, Any()); | |
| setPropertyValue(PROPERTY_TREATASNUMERIC, makeAny((sal_Bool)m_bOriginalNumeric)); | |
| m_xOriginalFormatter = NULL; | |
| } | |
| m_nFieldType = DataType::OTHER; | |
| m_nKeyType = NumberFormat::UNDEFINED; | |
| m_aNullDate = DBTypeConversion::getStandardDate(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) | |
| { | |
| OEditBaseModel::write(_rxOutStream); | |
| _rxOutStream->writeShort(0x0003); | |
| DBG_ASSERT(m_xAggregateSet.is(), "OFormattedModel::write : have no aggregate !"); | |
| // mein Format (evtl. void) in ein persistentes Format bringen (der Supplier zusammen mit dem Key ist es zwar auch, | |
| // aber deswegen muessen wir ja nicht gleich den ganzen Supplier speichern, das waere ein klein wenig Overhead ;) | |
| Reference<XNumberFormatsSupplier> xSupplier; | |
| Any aFmtKey; | |
| sal_Bool bVoidKey = sal_True; | |
| if (m_xAggregateSet.is()) | |
| { | |
| Any aSupplier = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATSSUPPLIER); | |
| if (aSupplier.getValueType().getTypeClass() != TypeClass_VOID) | |
| { | |
| OSL_VERIFY( aSupplier >>= xSupplier ); | |
| } | |
| aFmtKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY); | |
| bVoidKey = (!xSupplier.is() || !aFmtKey.hasValue()) || (isLoaded() && m_xOriginalFormatter.is()); | |
| // (kein Fomatter und/oder Key) oder (loaded und faked Formatter) | |
| } | |
| _rxOutStream->writeBoolean(!bVoidKey); | |
| if (!bVoidKey) | |
| { | |
| // aus dem FormatKey und dem Formatter persistente Angaben basteln | |
| Any aKey = m_xAggregateSet->getPropertyValue(PROPERTY_FORMATKEY); | |
| sal_Int32 nKey = aKey.hasValue() ? getINT32(aKey) : 0; | |
| Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats(); | |
| ::rtl::OUString sFormatDescription; | |
| LanguageType eFormatLanguage = LANGUAGE_DONTKNOW; | |
| static const ::rtl::OUString s_aLocaleProp = ::rtl::OUString::createFromAscii("Locale"); | |
| Reference<com::sun::star::beans::XPropertySet> xFormat = xFormats->getByKey(nKey); | |
| if (hasProperty(s_aLocaleProp, xFormat)) | |
| { | |
| Any aLocale = xFormat->getPropertyValue(s_aLocaleProp); | |
| DBG_ASSERT(isA(aLocale, static_cast<Locale*>(NULL)), "OFormattedModel::write : invalid language property !"); | |
| if (isA(aLocale, static_cast<Locale*>(NULL))) | |
| { | |
| Locale* pLocale = (Locale*)aLocale.getValue(); | |
| eFormatLanguage = MsLangId::convertLocaleToLanguage( *pLocale ); | |
| } | |
| } | |
| static const ::rtl::OUString s_aFormatStringProp = ::rtl::OUString::createFromAscii("FormatString"); | |
| if (hasProperty(s_aFormatStringProp, xFormat)) | |
| xFormat->getPropertyValue(s_aFormatStringProp) >>= sFormatDescription; | |
| _rxOutStream->writeUTF(sFormatDescription); | |
| _rxOutStream->writeLong((sal_Int32)eFormatLanguage); | |
| } | |
| // version 2 : write the properties common to all OEditBaseModels | |
| writeCommonEditProperties(_rxOutStream); | |
| // version 3 : write the effective value property of the aggregate | |
| // Due to a bug within the UnoControlFormattedFieldModel implementation (our default aggregate) this props value isn't correctly read | |
| // and this can't be corrected without being incompatible. | |
| // so we have our own handling. | |
| // and to be a little bit more compatible we make the following section skippable | |
| { | |
| Reference< XDataOutputStream > xOut(_rxOutStream, UNO_QUERY); | |
| OStreamSection aDownCompat(xOut); | |
| // a sub version within the skippable block | |
| _rxOutStream->writeShort(0x0000); | |
| // version 0: the effective value of the aggregate | |
| Any aEffectiveValue; | |
| if (m_xAggregateSet.is()) | |
| { | |
| try { aEffectiveValue = m_xAggregateSet->getPropertyValue(PROPERTY_EFFECTIVE_VALUE); } catch(Exception&) { } | |
| } | |
| { | |
| OStreamSection aDownCompat2(xOut); | |
| switch (aEffectiveValue.getValueType().getTypeClass()) | |
| { | |
| case TypeClass_STRING: | |
| _rxOutStream->writeShort(0x0000); | |
| _rxOutStream->writeUTF(::comphelper::getString(aEffectiveValue)); | |
| break; | |
| case TypeClass_DOUBLE: | |
| _rxOutStream->writeShort(0x0001); | |
| _rxOutStream->writeDouble(::comphelper::getDouble(aEffectiveValue)); | |
| break; | |
| default: // void and all unknown states | |
| DBG_ASSERT(!aEffectiveValue.hasValue(), "FmXFormattedModel::write : unknown property value type !"); | |
| _rxOutStream->writeShort(0x0002); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) | |
| { | |
| OEditBaseModel::read(_rxInStream); | |
| sal_uInt16 nVersion = _rxInStream->readShort(); | |
| Reference<XNumberFormatsSupplier> xSupplier; | |
| sal_Int32 nKey = -1; | |
| switch (nVersion) | |
| { | |
| case 0x0001 : | |
| case 0x0002 : | |
| case 0x0003 : | |
| { | |
| sal_Bool bNonVoidKey = _rxInStream->readBoolean(); | |
| if (bNonVoidKey) | |
| { | |
| // den String und die Language lesen .... | |
| ::rtl::OUString sFormatDescription = _rxInStream->readUTF(); | |
| LanguageType eDescriptionLanguage = (LanguageType)_rxInStream->readLong(); | |
| // und daraus von einem Formatter zu einem Key zusammenwuerfeln lassen ... | |
| xSupplier = calcFormatsSupplier(); | |
| // calcFormatsSupplier nimmt erst den vom Model, dann einen von der starform, dann einen ganz neuen .... | |
| Reference<XNumberFormats> xFormats = xSupplier->getNumberFormats(); | |
| if (xFormats.is()) | |
| { | |
| Locale aDescriptionLanguage( MsLangId::convertLanguageToLocale(eDescriptionLanguage)); | |
| nKey = xFormats->queryKey(sFormatDescription, aDescriptionLanguage, sal_False); | |
| if (nKey == (sal_Int32)-1) | |
| { // noch nicht vorhanden in meinem Formatter ... | |
| nKey = xFormats->addNew(sFormatDescription, aDescriptionLanguage); | |
| } | |
| } | |
| } | |
| if ((nVersion == 0x0002) || (nVersion == 0x0003)) | |
| readCommonEditProperties(_rxInStream); | |
| if (nVersion == 0x0003) | |
| { // since version 3 there is a "skippable" block at this position | |
| Reference< XDataInputStream > xIn(_rxInStream, UNO_QUERY); | |
| OStreamSection aDownCompat(xIn); | |
| sal_Int16 nSubVersion = _rxInStream->readShort(); | |
| (void)nSubVersion; | |
| // version 0 and higher : the "effective value" property | |
| Any aEffectiveValue; | |
| { | |
| OStreamSection aDownCompat2(xIn); | |
| switch (_rxInStream->readShort()) | |
| { | |
| case 0: // String | |
| aEffectiveValue <<= _rxInStream->readUTF(); | |
| break; | |
| case 1: // double | |
| aEffectiveValue <<= (double)_rxInStream->readDouble(); | |
| break; | |
| case 2: | |
| break; | |
| case 3: | |
| DBG_ERROR("FmXFormattedModel::read : unknown effective value type !"); | |
| } | |
| } | |
| // this property is only to be set if we have no control source : in all other cases the base class did a | |
| // reset after it's read and this set the effective value to a default value | |
| if ( m_xAggregateSet.is() && ( getControlSource().getLength() == 0 ) ) | |
| { | |
| try | |
| { | |
| m_xAggregateSet->setPropertyValue(PROPERTY_EFFECTIVE_VALUE, aEffectiveValue); | |
| } | |
| catch(Exception&) | |
| { | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| default : | |
| DBG_ERROR("OFormattedModel::read : unknown version !"); | |
| // dann bleibt das Format des aggregierten Sets, wie es bei der Erzeugung ist : void | |
| defaultCommonEditProperties(); | |
| break; | |
| } | |
| if ((nKey != -1) && m_xAggregateSet.is()) | |
| { | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATSSUPPLIER, makeAny(xSupplier)); | |
| m_xAggregateSet->setPropertyValue(PROPERTY_FORMATKEY, makeAny((sal_Int32)nKey)); | |
| } | |
| else | |
| { | |
| setPropertyToDefault(PROPERTY_FORMATSSUPPLIER); | |
| setPropertyToDefault(PROPERTY_FORMATKEY); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| sal_uInt16 OFormattedModel::getPersistenceFlags() const | |
| { | |
| return (OEditBaseModel::getPersistenceFlags() & ~PF_HANDLE_COMMON_PROPS); | |
| // a) we do our own call to writeCommonEditProperties | |
| } | |
| //------------------------------------------------------------------------------ | |
| sal_Bool OFormattedModel::commitControlValueToDbColumn( bool /*_bPostReset*/ ) | |
| { | |
| Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) ); | |
| if ( aControlValue != m_aSaveValue ) | |
| { | |
| // Leerstring + EmptyIsNull = void | |
| if ( !aControlValue.hasValue() | |
| || ( ( aControlValue.getValueType().getTypeClass() == TypeClass_STRING ) | |
| && ( getString( aControlValue ).getLength() == 0 ) | |
| && m_bEmptyIsNull | |
| ) | |
| ) | |
| m_xColumnUpdate->updateNull(); | |
| else | |
| { | |
| try | |
| { | |
| double f = 0.0; | |
| if ( aControlValue.getValueType().getTypeClass() == TypeClass_DOUBLE || (aControlValue >>= f)) // #i110323 | |
| { | |
| DBTypeConversion::setValue( m_xColumnUpdate, m_aNullDate, getDouble( aControlValue ), m_nKeyType ); | |
| } | |
| else | |
| { | |
| DBG_ASSERT( aControlValue.getValueType().getTypeClass() == TypeClass_STRING, "OFormattedModel::commitControlValueToDbColumn: invalud value type !" ); | |
| m_xColumnUpdate->updateString( getString( aControlValue ) ); | |
| } | |
| } | |
| catch(Exception&) | |
| { | |
| return sal_False; | |
| } | |
| } | |
| m_aSaveValue = aControlValue; | |
| } | |
| return sal_True; | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::onConnectedExternalValue( ) | |
| { | |
| OEditBaseModel::onConnectedExternalValue(); | |
| updateFormatterNullDate(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any OFormattedModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const | |
| { | |
| Any aControlValue; | |
| switch( _rExternalValue.getValueTypeClass() ) | |
| { | |
| case TypeClass_VOID: | |
| break; | |
| case TypeClass_STRING: | |
| aControlValue = _rExternalValue; | |
| break; | |
| case TypeClass_BOOLEAN: | |
| { | |
| sal_Bool bExternalValue = sal_False; | |
| _rExternalValue >>= bExternalValue; | |
| aControlValue <<= (double)( bExternalValue ? 1 : 0 ); | |
| } | |
| break; | |
| default: | |
| { | |
| if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) ) | |
| { | |
| UNODate aDate; | |
| _rExternalValue >>= aDate; | |
| aControlValue <<= DBTypeConversion::toDouble( aDate, m_aNullDate ); | |
| } | |
| else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) ) | |
| { | |
| UNOTime aTime; | |
| _rExternalValue >>= aTime; | |
| aControlValue <<= DBTypeConversion::toDouble( aTime ); | |
| } | |
| else if ( _rExternalValue.getValueType().equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) ) | |
| { | |
| UNODateTime aDateTime; | |
| _rExternalValue >>= aDateTime; | |
| aControlValue <<= DBTypeConversion::toDouble( aDateTime, m_aNullDate ); | |
| } | |
| else | |
| { | |
| OSL_ENSURE( _rExternalValue.getValueTypeClass() == TypeClass_DOUBLE, | |
| "OFormattedModel::translateExternalValueToControlValue: don't know how to translate this type!" ); | |
| double fValue = 0; | |
| OSL_VERIFY( _rExternalValue >>= fValue ); | |
| aControlValue <<= fValue; | |
| } | |
| } | |
| } | |
| return aControlValue; | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any OFormattedModel::translateControlValueToExternalValue( ) const | |
| { | |
| OSL_PRECOND( hasExternalValueBinding(), | |
| "OFormattedModel::translateControlValueToExternalValue: precondition not met!" ); | |
| Any aControlValue( getControlValue() ); | |
| if ( !aControlValue.hasValue() ) | |
| return aControlValue; | |
| Any aExternalValue; | |
| // translate into the the external value type | |
| Type aExternalValueType( getExternalValueType() ); | |
| switch ( aExternalValueType.getTypeClass() ) | |
| { | |
| case TypeClass_STRING: | |
| { | |
| ::rtl::OUString sString; | |
| if ( aControlValue >>= sString ) | |
| { | |
| aExternalValue <<= sString; | |
| break; | |
| } | |
| } | |
| // NO break here! | |
| case TypeClass_BOOLEAN: | |
| { | |
| double fValue = 0; | |
| OSL_VERIFY( aControlValue >>= fValue ); | |
| // if this asserts ... well, the somebody set the TreatAsNumeric property to false, | |
| // and the control value is a string. This implies some weird misconfiguration | |
| // of the FormattedModel, so we won't care for it for the moment. | |
| aExternalValue <<= (sal_Bool)( fValue ? sal_True : sal_False ); | |
| } | |
| break; | |
| default: | |
| { | |
| double fValue = 0; | |
| OSL_VERIFY( aControlValue >>= fValue ); | |
| // if this asserts ... well, the somebody set the TreatAsNumeric property to false, | |
| // and the control value is a string. This implies some weird misconfiguration | |
| // of the FormattedModel, so we won't care for it for the moment. | |
| if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODate* >( NULL ) ) ) ) | |
| { | |
| aExternalValue <<= DBTypeConversion::toDate( fValue, m_aNullDate ); | |
| } | |
| else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNOTime* >( NULL ) ) ) ) | |
| { | |
| aExternalValue <<= DBTypeConversion::toTime( fValue ); | |
| } | |
| else if ( aExternalValueType.equals( ::getCppuType( static_cast< UNODateTime* >( NULL ) ) ) ) | |
| { | |
| aExternalValue <<= DBTypeConversion::toDateTime( fValue, m_aNullDate ); | |
| } | |
| else | |
| { | |
| OSL_ENSURE( aExternalValueType.equals( ::getCppuType( static_cast< double* >( NULL ) ) ), | |
| "OFormattedModel::translateControlValueToExternalValue: don't know how to translate this type!" ); | |
| aExternalValue <<= fValue; | |
| } | |
| } | |
| break; | |
| } | |
| return aExternalValue; | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any OFormattedModel::translateDbColumnToControlValue() | |
| { | |
| if ( m_bNumeric ) | |
| m_aSaveValue <<= DBTypeConversion::getValue( m_xColumn, m_aNullDate ); // #100056# OJ | |
| else | |
| m_aSaveValue <<= m_xColumn->getString(); | |
| if ( m_xColumn->wasNull() ) | |
| m_aSaveValue.clear(); | |
| return m_aSaveValue; | |
| } | |
| // ----------------------------------------------------------------------------- | |
| Sequence< Type > OFormattedModel::getSupportedBindingTypes() | |
| { | |
| ::std::list< Type > aTypes; | |
| aTypes.push_back( ::getCppuType( static_cast< double* >( NULL ) ) ); | |
| switch ( m_nKeyType & ~NumberFormat::DEFINED ) | |
| { | |
| case NumberFormat::DATE: | |
| aTypes.push_front(::getCppuType( static_cast< UNODate* >( NULL ) ) ); | |
| break; | |
| case NumberFormat::TIME: | |
| aTypes.push_front(::getCppuType( static_cast< UNOTime* >( NULL ) ) ); | |
| break; | |
| case NumberFormat::DATETIME: | |
| aTypes.push_front(::getCppuType( static_cast< UNODateTime* >( NULL ) ) ); | |
| break; | |
| case NumberFormat::TEXT: | |
| aTypes.push_front(::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ); | |
| break; | |
| case NumberFormat::LOGICAL: | |
| aTypes.push_front(::getCppuType( static_cast< sal_Bool* >( NULL ) ) ); | |
| break; | |
| } | |
| Sequence< Type > aTypesRet( aTypes.size() ); | |
| ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() ); | |
| return aTypesRet; | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any OFormattedModel::getDefaultForReset() const | |
| { | |
| return m_xAggregateSet->getPropertyValue( PROPERTY_EFFECTIVE_DEFAULT ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OFormattedModel::resetNoBroadcast() | |
| { | |
| OEditBaseModel::resetNoBroadcast(); | |
| m_aSaveValue.clear(); | |
| } | |
| //......................................................................... | |
| } | |
| //......................................................................... |