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