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