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 "Edit.hxx"
31 : :
32 : : #include <com/sun/star/uno/Type.hxx>
33 : : #include <com/sun/star/awt/XWindow.hpp>
34 : : #include <com/sun/star/container/XIndexAccess.hpp>
35 : : #include <com/sun/star/form/XSubmit.hpp>
36 : : #include <com/sun/star/util/NumberFormat.hpp>
37 : : #include <com/sun/star/sdbc/DataType.hpp>
38 : : #include <com/sun/star/awt/XVclWindowPeer.hpp>
39 : :
40 : : #include <vcl/svapp.hxx>
41 : : #include <tools/wintypes.hxx>
42 : :
43 : : #include <connectivity/dbtools.hxx>
44 : : #include <connectivity/formattedcolumnvalue.hxx>
45 : : #include <connectivity/dbconversion.hxx>
46 : :
47 : : #include <tools/diagnose_ex.h>
48 : : #include <tools/debug.hxx>
49 : :
50 : : #include <comphelper/container.hxx>
51 : : #include <comphelper/numbers.hxx>
52 : :
53 : : using namespace dbtools;
54 : :
55 : : //.........................................................................
56 : : namespace frm
57 : : {
58 : : using namespace ::com::sun::star::uno;
59 : : using namespace ::com::sun::star::sdb;
60 : : using namespace ::com::sun::star::sdbc;
61 : : using namespace ::com::sun::star::sdbcx;
62 : : using namespace ::com::sun::star::beans;
63 : : using namespace ::com::sun::star::container;
64 : : using namespace ::com::sun::star::form;
65 : : using namespace ::com::sun::star::awt;
66 : : using namespace ::com::sun::star::io;
67 : : using namespace ::com::sun::star::lang;
68 : : using namespace ::com::sun::star::util;
69 : : using namespace ::com::sun::star::form::binding;
70 : :
71 : : //------------------------------------------------------------------
72 : 80 : InterfaceRef SAL_CALL OEditControl_CreateInstance(const Reference< XMultiServiceFactory > & _rxFactory)
73 : : {
74 [ + - ]: 80 : return *(new OEditControl(_rxFactory));
75 : : }
76 : :
77 : : //------------------------------------------------------------------------------
78 : 0 : Sequence<Type> OEditControl::_getTypes()
79 : : {
80 [ # # ][ # # ]: 0 : static Sequence<Type> aTypes;
[ # # ][ # # ]
81 [ # # ]: 0 : if (!aTypes.getLength())
82 : : {
83 : : // my two base classes
84 [ # # ][ # # ]: 0 : aTypes = concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes());
[ # # ][ # # ]
[ # # ]
85 : : }
86 : 0 : return aTypes;
87 : : }
88 : :
89 : : //------------------------------------------------------------------------------
90 : 4145 : Any SAL_CALL OEditControl::queryAggregation(const Type& _rType) throw (RuntimeException)
91 : : {
92 : 4145 : Any aReturn = OBoundControl::queryAggregation(_rType);
93 [ + + ]: 4145 : if (!aReturn.hasValue())
94 [ + - ]: 201 : aReturn = OEditControl_BASE::queryInterface(_rType);
95 : :
96 : 4145 : return aReturn;
97 : : }
98 : :
99 : : DBG_NAME(OEditControl);
100 : : //------------------------------------------------------------------------------
101 : 80 : OEditControl::OEditControl(const Reference<XMultiServiceFactory>& _rxFactory)
102 : : :OBoundControl( _rxFactory, FRM_SUN_CONTROL_RICHTEXTCONTROL )
103 : : ,m_aChangeListeners(m_aMutex)
104 [ + - ][ + - ]: 80 : ,m_nKeyEvent( 0 )
105 : : {
106 : : DBG_CTOR(OEditControl,NULL);
107 : :
108 [ + - ]: 80 : increment(m_refCount);
109 : : {
110 : 80 : Reference<XWindow> xComp;
111 [ + - ][ + - ]: 80 : if (query_aggregation(m_xAggregate, xComp))
112 : : {
113 [ + - ][ + - ]: 80 : xComp->addFocusListener(this);
[ + - ]
114 [ + - ][ + - ]: 80 : xComp->addKeyListener(this);
[ + - ]
115 : 80 : }
116 : : }
117 [ + - ]: 80 : decrement(m_refCount);
118 : 80 : }
119 : :
120 : : //------------------------------------------------------------------------------
121 [ + - ]: 77 : OEditControl::~OEditControl()
122 : : {
123 [ - + ]: 77 : if( m_nKeyEvent )
124 [ # # ]: 0 : Application::RemoveUserEvent( m_nKeyEvent );
125 : :
126 [ - + ]: 77 : if (!OComponentHelper::rBHelper.bDisposed)
127 : : {
128 : 0 : acquire();
129 [ # # ]: 0 : dispose();
130 : : }
131 : :
132 : : DBG_DTOR(OEditControl,NULL);
133 [ - + ]: 154 : }
134 : :
135 : : // XChangeBroadcaster
136 : : //------------------------------------------------------------------------------
137 : 0 : void OEditControl::addChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
138 : : {
139 : 0 : m_aChangeListeners.addInterface( l );
140 : 0 : }
141 : :
142 : : //------------------------------------------------------------------------------
143 : 0 : void OEditControl::removeChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
144 : : {
145 : 0 : m_aChangeListeners.removeInterface( l );
146 : 0 : }
147 : :
148 : : // OComponentHelper
149 : : //------------------------------------------------------------------------------
150 : 77 : void OEditControl::disposing()
151 : : {
152 [ + - ]: 77 : OBoundControl::disposing();
153 : :
154 [ + - ][ + - ]: 77 : EventObject aEvt(static_cast<XWeak*>(this));
155 [ + - ][ + - ]: 77 : m_aChangeListeners.disposeAndClear(aEvt);
156 : 77 : }
157 : :
158 : : // XServiceInfo
159 : : //------------------------------------------------------------------------------
160 : 0 : StringSequence OEditControl::getSupportedServiceNames() throw()
161 : : {
162 : 0 : StringSequence aSupported = OBoundControl::getSupportedServiceNames();
163 [ # # ]: 0 : aSupported.realloc(aSupported.getLength() + 1);
164 : :
165 [ # # ]: 0 : ::rtl::OUString*pArray = aSupported.getArray();
166 [ # # ]: 0 : pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_TEXTFIELD;
167 : 0 : return aSupported;
168 : : }
169 : :
170 : : // XEventListener
171 : : //------------------------------------------------------------------------------
172 : 258 : void OEditControl::disposing(const EventObject& Source) throw( RuntimeException )
173 : : {
174 : 258 : OBoundControl::disposing(Source);
175 : 258 : }
176 : :
177 : : // XFocusListener
178 : : //------------------------------------------------------------------------------
179 : 0 : void OEditControl::focusGained( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
180 : : {
181 [ # # ][ # # ]: 0 : Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
182 [ # # ]: 0 : if (xSet.is())
183 [ # # ][ # # ]: 0 : xSet->getPropertyValue( PROPERTY_TEXT ) >>= m_aHtmlChangeValue;
[ # # ]
184 : 0 : }
185 : :
186 : : //------------------------------------------------------------------------------
187 : 0 : void OEditControl::focusLost( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
188 : : {
189 [ # # ][ # # ]: 0 : Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
190 [ # # ]: 0 : if (xSet.is())
191 : : {
192 : 0 : ::rtl::OUString sNewHtmlChangeValue;
193 [ # # ][ # # ]: 0 : xSet->getPropertyValue( PROPERTY_TEXT ) >>= sNewHtmlChangeValue;
[ # # ]
194 [ # # ]: 0 : if( sNewHtmlChangeValue != m_aHtmlChangeValue )
195 : : {
196 [ # # ][ # # ]: 0 : EventObject aEvt( *this );
197 [ # # ][ # # ]: 0 : m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvt );
198 : 0 : }
199 : 0 : }
200 : 0 : }
201 : :
202 : : // XKeyListener
203 : : //------------------------------------------------------------------------------
204 : 0 : void OEditControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
205 : : {
206 [ # # ][ # # ]: 0 : if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
207 : : return;
208 : :
209 : : // Is the Control in a form with a submit URL?
210 [ # # ][ # # ]: 0 : Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
211 [ # # ]: 0 : if( !xSet.is() )
212 : : return;
213 : :
214 : : // Not for multiline edits
215 [ # # ][ # # ]: 0 : Any aTmp( xSet->getPropertyValue(PROPERTY_MULTILINE));
[ # # ]
216 [ # # ][ # # ]: 0 : if ((aTmp.getValueType().equals(::getBooleanCppuType())) && getBOOL(aTmp))
[ # # ][ # # ]
[ # # ]
217 : : return;
218 : :
219 [ # # ]: 0 : Reference<XFormComponent> xFComp(xSet, UNO_QUERY);
220 [ # # ][ # # ]: 0 : InterfaceRef xParent = xFComp->getParent();
221 [ # # ]: 0 : if( !xParent.is() )
222 : : return;
223 : :
224 [ # # ]: 0 : Reference<XPropertySet> xFormSet(xParent, UNO_QUERY);
225 [ # # ]: 0 : if( !xFormSet.is() )
226 : : return;
227 : :
228 [ # # ][ # # ]: 0 : aTmp = xFormSet->getPropertyValue( PROPERTY_TARGET_URL );
[ # # ]
229 [ # # # # ]: 0 : if (!aTmp.getValueType().equals(::getCppuType((const ::rtl::OUString*)NULL)) ||
[ # # ][ # # ]
230 [ # # ][ # # ]: 0 : getString(aTmp).isEmpty() )
[ # # ]
231 : : return;
232 : :
233 [ # # ]: 0 : Reference<XIndexAccess> xElements(xParent, UNO_QUERY);
234 [ # # ][ # # ]: 0 : sal_Int32 nCount = xElements->getCount();
235 [ # # ]: 0 : if( nCount > 1 )
236 : : {
237 : 0 : Reference<XPropertySet> xFCSet;
238 [ # # ]: 0 : for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
239 : : {
240 : : // Any aElement(xElements->getByIndex(nIndex));
241 [ # # ][ # # ]: 0 : xElements->getByIndex(nIndex) >>= xFCSet;
[ # # ]
242 : : OSL_ENSURE(xFCSet.is(),"OEditControl::keyPressed: No XPropertySet!");
243 : :
244 [ # # ][ # # ]: 0 : if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
[ # # ][ # # ]
[ # # # # ]
[ # # ]
245 [ # # ][ # # ]: 0 : getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
246 : : {
247 : : // Found another Edit -> then do not submit!
248 [ # # ][ # # ]: 0 : if (xFCSet != xSet)
249 : : return;
250 : : }
251 [ # # ]: 0 : }
252 : : }
253 : :
254 : : // Because we're still in the header, trigger submit asynchronously
255 [ # # ]: 0 : if( m_nKeyEvent )
256 [ # # ]: 0 : Application::RemoveUserEvent( m_nKeyEvent );
257 [ # # ][ # # ]: 0 : m_nKeyEvent = Application::PostUserEvent( LINK(this, OEditControl,OnKeyPressed) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
258 : : }
259 : :
260 : : //------------------------------------------------------------------------------
261 : 0 : void OEditControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException)
262 : : {
263 : 0 : }
264 : :
265 : : //------------------------------------------------------------------------------
266 : 0 : IMPL_LINK(OEditControl, OnKeyPressed, void*, /*EMPTYARG*/)
267 : : {
268 : 0 : m_nKeyEvent = 0;
269 : :
270 [ # # ][ # # ]: 0 : Reference<XFormComponent> xFComp(getModel(), UNO_QUERY);
271 [ # # ][ # # ]: 0 : InterfaceRef xParent = xFComp->getParent();
272 [ # # ]: 0 : Reference<XSubmit> xSubmit(xParent, UNO_QUERY);
273 [ # # ]: 0 : if (xSubmit.is())
274 [ # # ][ # # ]: 0 : xSubmit->submit( Reference<XControl>(), ::com::sun::star::awt::MouseEvent() );
[ # # ][ # # ]
275 : 0 : return 0L;
276 : : }
277 : :
278 : : //------------------------------------------------------------------
279 : 167 : void SAL_CALL OEditControl::createPeer( const Reference< XToolkit>& _rxToolkit, const Reference< XWindowPeer>& _rxParent ) throw ( RuntimeException )
280 : : {
281 : 167 : OBoundControl::createPeer(_rxToolkit, _rxParent);
282 : 167 : }
283 : :
284 : : /*************************************************************************/
285 : : //------------------------------------------------------------------
286 : 168 : InterfaceRef SAL_CALL OEditModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
287 : : {
288 [ + - ]: 168 : return *(new OEditModel(_rxFactory));
289 : : }
290 : :
291 : : //------------------------------------------------------------------------------
292 : 4 : Sequence<Type> OEditModel::_getTypes()
293 : : {
294 : 4 : return OEditBaseModel::_getTypes();
295 : : }
296 : :
297 : :
298 : : DBG_NAME(OEditModel);
299 : : //------------------------------------------------------------------
300 : 200 : OEditModel::OEditModel(const Reference<XMultiServiceFactory>& _rxFactory)
301 : : :OEditBaseModel( _rxFactory, FRM_SUN_COMPONENT_RICHTEXTCONTROL, FRM_SUN_CONTROL_TEXTFIELD, sal_True, sal_True )
302 : : ,m_bMaxTextLenModified(sal_False)
303 [ + - ][ + - ]: 200 : ,m_bWritingFormattedFake(sal_False)
304 : : {
305 : : DBG_CTOR(OEditModel,NULL);
306 : :
307 : 200 : m_nClassId = FormComponentType::TEXTFIELD;
308 [ + - ][ + - ]: 200 : initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
309 : 200 : }
310 : :
311 : : //------------------------------------------------------------------
312 : 4 : OEditModel::OEditModel( const OEditModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
313 : : :OEditBaseModel( _pOriginal, _rxFactory )
314 : : ,m_bMaxTextLenModified(sal_False)
315 : 4 : ,m_bWritingFormattedFake(sal_False)
316 : : {
317 : : DBG_CTOR( OEditModel, NULL );
318 : :
319 : : // Note that most of the properties are not clone from the original object:
320 : : // Things as the format key, it's type, and such, depend on the field being part of a loaded form
321 : : // (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself
322 : : // certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded,
323 : : // they will be set to new values, anyway ....
324 : 4 : }
325 : :
326 : : //------------------------------------------------------------------
327 [ + - ]: 185 : OEditModel::~OEditModel()
328 : : {
329 [ - + ]: 185 : if (!OComponentHelper::rBHelper.bDisposed)
330 : : {
331 : 0 : acquire();
332 [ # # ]: 0 : dispose();
333 : : }
334 : :
335 : : DBG_DTOR(OEditModel,NULL);
336 [ - + ]: 370 : }
337 : :
338 : : //------------------------------------------------------------------------------
339 [ + - ][ + - ]: 4 : IMPLEMENT_DEFAULT_CLONING( OEditModel )
340 : :
341 : : //------------------------------------------------------------------------------
342 : 185 : void OEditModel::disposing()
343 : : {
344 : 185 : OEditBaseModel::disposing();
345 : 185 : m_pValueFormatter.reset();
346 : 185 : }
347 : :
348 : : // XPersistObject
349 : : //------------------------------------------------------------------------------
350 : 2 : ::rtl::OUString SAL_CALL OEditModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
351 : : {
352 : 2 : return FRM_COMPONENT_EDIT; // old (non-sun) name for compatibility !
353 : : }
354 : :
355 : : // XServiceInfo
356 : : //------------------------------------------------------------------------------
357 : 107 : StringSequence SAL_CALL OEditModel::getSupportedServiceNames() throw()
358 : : {
359 : 107 : StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
360 : :
361 : 107 : sal_Int32 nOldLen = aSupported.getLength();
362 [ + - ]: 107 : aSupported.realloc( nOldLen + 8 );
363 [ + - ]: 107 : ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
364 : :
365 [ + - ]: 107 : *pStoreTo++ = BINDABLE_CONTROL_MODEL;
366 [ + - ]: 107 : *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
367 [ + - ]: 107 : *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
368 : :
369 [ + - ]: 107 : *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
370 [ + - ]: 107 : *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
371 : :
372 [ + - ]: 107 : *pStoreTo++ = FRM_SUN_COMPONENT_TEXTFIELD;
373 [ + - ]: 107 : *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD;
374 [ + - ]: 107 : *pStoreTo++ = BINDABLE_DATABASE_TEXT_FIELD;
375 : :
376 : 107 : return aSupported;
377 : : }
378 : :
379 : : // XPropertySet
380 : 25780 : void SAL_CALL OEditModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
381 : : {
382 [ + + ]: 25780 : if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH == nHandle )
383 : : {
384 [ - + ]: 177 : if ( m_bMaxTextLenModified )
385 [ # # ]: 0 : rValue <<= sal_Int16(0);
386 [ + - ]: 177 : else if ( m_xAggregateSet.is() )
387 [ + - ]: 177 : rValue = m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN);
388 : : }
389 : : else
390 : : {
391 : 25603 : OEditBaseModel::getFastPropertyValue(rValue, nHandle );
392 : : }
393 : 25780 : }
394 : :
395 : : //------------------------------------------------------------------------------
396 : 206 : void OEditModel::describeFixedProperties( Sequence< Property >& _rProps ) const
397 : : {
398 : 206 : BEGIN_DESCRIBE_PROPERTIES( 5, OEditBaseModel )
399 [ + - ][ + - ]: 206 : DECL_PROP2(PERSISTENCE_MAXTEXTLENGTH,sal_Int16, READONLY, TRANSIENT);
400 [ + - ][ + - ]: 206 : DECL_PROP2(DEFAULT_TEXT, ::rtl::OUString, BOUND, MAYBEDEFAULT);
401 [ + - ]: 206 : DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND);
402 [ + - ]: 206 : DECL_PROP1(TABINDEX, sal_Int16, BOUND);
403 [ + - ][ + - ]: 206 : DECL_BOOL_PROP2(FILTERPROPOSAL, BOUND, MAYBEDEFAULT);
404 : : END_DESCRIBE_PROPERTIES();
405 : 206 : }
406 : :
407 : : //------------------------------------------------------------------------------
408 : 206 : void OEditModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
409 : : {
410 : 206 : OEditBaseModel::describeAggregateProperties( _rAggregateProps );
411 : :
412 : : // our aggregate is a rich text model, which also derives from OControlModel, as
413 : : // do we, so we need to remove some duplicate properties
414 [ + - ]: 206 : RemoveProperty( _rAggregateProps, PROPERTY_TABINDEX );
415 [ + - ]: 206 : RemoveProperty( _rAggregateProps, PROPERTY_CLASSID );
416 [ + - ]: 206 : RemoveProperty( _rAggregateProps, PROPERTY_NAME );
417 [ + - ]: 206 : RemoveProperty( _rAggregateProps, PROPERTY_TAG );
418 [ + - ]: 206 : RemoveProperty( _rAggregateProps, PROPERTY_NATIVE_LOOK );
419 : :
420 : 206 : }
421 : :
422 : : //------------------------------------------------------------------------------
423 : 44 : bool OEditModel::implActsAsRichText( ) const
424 : : {
425 : 44 : sal_Bool bActAsRichText = sal_False;
426 [ + - ]: 44 : if ( m_xAggregateSet.is() )
427 : : {
428 [ + - ][ + - ]: 44 : OSL_VERIFY( m_xAggregateSet->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActAsRichText );
[ + - ]
429 : : }
430 : 44 : return bActAsRichText;
431 : : }
432 : :
433 : : //------------------------------------------------------------------------------
434 : 10 : void SAL_CALL OEditModel::reset( ) throw(RuntimeException)
435 : : {
436 : : // no reset if we currently act as rich text control
437 [ - + ]: 10 : if ( implActsAsRichText() )
438 : 10 : return;
439 : :
440 : 10 : OEditBaseModel::reset();
441 : : }
442 : :
443 : : //------------------------------------------------------------------------------
444 : : namespace
445 : : {
446 : 8 : void lcl_transferProperties( const Reference< XPropertySet >& _rxSource, const Reference< XPropertySet >& _rxDest )
447 : : {
448 : : try
449 : : {
450 : 8 : Reference< XPropertySetInfo > xSourceInfo;
451 [ + - ]: 8 : if ( _rxSource.is() )
452 [ + - ][ + - ]: 8 : xSourceInfo = _rxSource->getPropertySetInfo();
[ + - ]
453 : :
454 : 8 : Reference< XPropertySetInfo > xDestInfo;
455 [ + - ]: 8 : if ( _rxDest.is() )
456 [ + - ][ + - ]: 8 : xDestInfo = _rxDest->getPropertySetInfo();
[ + - ]
457 : :
458 [ + - ][ - + ]: 8 : if ( !xSourceInfo.is() || !xDestInfo.is() )
[ - + ]
459 : : {
460 : : OSL_FAIL( "lcl_transferProperties: invalid property set(s)!" );
461 : 8 : return;
462 : : }
463 : :
464 [ + - ][ + - ]: 8 : Sequence< Property > aSourceProps( xSourceInfo->getProperties() );
465 : 8 : const Property* pSourceProps = aSourceProps.getConstArray();
466 : 8 : const Property* pSourcePropsEnd = aSourceProps.getConstArray() + aSourceProps.getLength();
467 [ + + ]: 656 : while ( pSourceProps != pSourcePropsEnd )
468 : : {
469 [ + - ][ + - ]: 648 : if ( !xDestInfo->hasPropertyByName( pSourceProps->Name ) )
[ + + ]
470 : : {
471 : 288 : ++pSourceProps;
472 : 288 : continue;
473 : : }
474 : :
475 [ + - ][ + - ]: 360 : Property aDestProp( xDestInfo->getPropertyByName( pSourceProps->Name ) );
476 [ - + ]: 360 : if ( 0 != ( aDestProp.Attributes & PropertyAttribute::READONLY ) )
477 : : {
478 : 0 : ++pSourceProps;
479 : 0 : continue;
480 : : }
481 : :
482 : : try
483 : : {
484 [ + - ][ + - ]: 360 : _rxDest->setPropertyValue( pSourceProps->Name, _rxSource->getPropertyValue( pSourceProps->Name ) );
[ + - ][ + - ]
[ # # ]
485 : : }
486 [ # # ]: 0 : catch(const IllegalArgumentException& e)
487 : : {
488 : : #if OSL_DEBUG_LEVEL > 0
489 : : ::rtl::OString sMessage( "could not transfer the property named '" );
490 : : sMessage += ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US );
491 : : sMessage += ::rtl::OString( "'." );
492 : : if ( !e.Message.isEmpty() )
493 : : {
494 : : sMessage += ::rtl::OString( "\n\nMessage:\n" );
495 : : sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US );
496 : : }
497 : : OSL_FAIL( sMessage.getStr() );
498 : : #else
499 : : (void)e;
500 : : #endif
501 : : }
502 : :
503 [ + - ]: 1008 : ++pSourceProps;
504 [ + - ][ - + ]: 368 : }
[ + - ][ # # ]
505 : : }
506 : 0 : catch( const Exception& )
507 : : {
508 : : DBG_UNHANDLED_EXCEPTION();
509 : : }
510 : : }
511 : : }
512 : :
513 : : //------------------------------------------------------------------------------
514 : 4 : void OEditModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
515 : : {
516 : : // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate,
517 : : // but for compatibility, we need to use an "old" aggregate for writing and reading
518 : :
519 : : Reference< XPropertySet > xFakedAggregate(
520 : 4 : getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
521 : : UNO_QUERY
522 [ + - + - ]: 8 : );
[ + - ]
523 : : OSL_ENSURE( xFakedAggregate.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" );
524 [ - + ]: 4 : if ( !xFakedAggregate.is() )
525 : 4 : return;
526 : :
527 [ + - ]: 4 : lcl_transferProperties( m_xAggregateSet, xFakedAggregate );
528 : :
529 [ + - ]: 4 : Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
530 : : OSL_ENSURE( xFakedPersist.is(), "OEditModel::writeAggregate: no XPersistObject!" );
531 [ + - ]: 4 : if ( xFakedPersist.is() )
532 [ + - ][ + - ]: 4 : xFakedPersist->write( _rxOutStream );
[ + - ]
533 : : }
534 : :
535 : : //------------------------------------------------------------------------------
536 : 4 : void OEditModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
537 : : {
538 : : // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate,
539 : : // but for compatibility, we need to use an "old" aggregate for writing and reading
540 : :
541 : : Reference< XPropertySet > xFakedAggregate(
542 : 4 : getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
543 : : UNO_QUERY
544 [ + - + - ]: 8 : );
[ + - ]
545 [ + - ]: 4 : Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
546 : : OSL_ENSURE( xFakedPersist.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" );
547 [ + - ]: 4 : if ( xFakedPersist.is() )
548 : : {
549 [ + - ][ + - ]: 4 : xFakedPersist->read( _rxInStream );
550 [ + - ]: 4 : lcl_transferProperties( xFakedAggregate, m_xAggregateSet );
551 : 4 : }
552 : 4 : }
553 : :
554 : : //------------------------------------------------------------------------------
555 : 4 : void OEditModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
556 : : {
557 : 4 : Any aCurrentText;
558 : 4 : sal_Int16 nOldTextLen = 0;
559 : : // Am I loaded at the moment and did I switch MaxTextLen temporarily?
560 [ - + ]: 4 : if ( m_bMaxTextLenModified )
561 : : { // -> for the duration of saving, make my aggregated model believe the old TextLen
562 : :
563 : : // before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len
564 [ # # ][ # # ]: 0 : aCurrentText = m_xAggregateSet->getPropertyValue(PROPERTY_TEXT);
[ # # ]
565 : :
566 [ # # ][ # # ]: 0 : m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN) >>= nOldTextLen;
[ # # ]
567 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny((sal_Int16)0));
[ # # ][ # # ]
568 : : }
569 : :
570 [ + - ]: 4 : OEditBaseModel::write(_rxOutStream);
571 : :
572 [ - + ]: 4 : if ( m_bMaxTextLenModified )
573 : : { // Reset again
574 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny(nOldTextLen));
[ # # ][ # # ]
575 : : // and reset the text
576 : : // First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks
577 : : // we aren't changing the prop (it didn't notify the - implicite - change of the text prop while setting the max text len)
578 : : // This seems to be a bug with in toolkit's EditControl-implementation.
579 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, makeAny(::rtl::OUString()));
[ # # ][ # # ]
580 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, aCurrentText);
[ # # ]
581 : 4 : }
582 : 4 : }
583 : :
584 : : //------------------------------------------------------------------------------
585 : 4 : void OEditModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
586 : : {
587 : 4 : OEditBaseModel::read(_rxInStream);
588 : :
589 : : // Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown
590 : : // to older versions (5.0).
591 : : // correct this ...
592 [ + - ]: 4 : if (m_xAggregateSet.is())
593 : : {
594 [ + - ][ + - ]: 4 : Any aDefaultControl = m_xAggregateSet->getPropertyValue(PROPERTY_DEFAULTCONTROL);
[ + - ]
595 [ - + ]: 12 : if ( (aDefaultControl.getValueType().getTypeClass() == TypeClass_STRING)
[ + - - + ]
596 [ + - ][ + - ]: 8 : && (getString(aDefaultControl).compareTo(STARDIV_ONE_FORM_CONTROL_TEXTFIELD) == COMPARE_EQUAL)
[ + - ][ + - ]
[ # # # # ]
597 : : )
598 : : {
599 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( (::rtl::OUString)STARDIV_ONE_FORM_CONTROL_EDIT ) );
[ # # ][ # # ]
[ # # ]
600 : : // Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT,
601 : : // the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD.
602 : 4 : }
603 : : }
604 : 4 : }
605 : :
606 : : //------------------------------------------------------------------------------
607 : 4 : sal_uInt16 OEditModel::getPersistenceFlags() const
608 : : {
609 : 4 : sal_uInt16 nFlags = OEditBaseModel::getPersistenceFlags();
610 : :
611 [ - + ]: 4 : if (m_bWritingFormattedFake)
612 : 0 : nFlags |= PF_FAKE_FORMATTED_FIELD;
613 : :
614 : 4 : return nFlags;
615 : : }
616 : :
617 : : //------------------------------------------------------------------------------
618 : 34 : void OEditModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
619 : : {
620 : 34 : Reference< XPropertySet > xField = getField();
621 [ + - ]: 34 : if ( xField.is() )
622 : : {
623 [ + - ][ + - ]: 34 : m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
[ + - ]
624 : :
625 [ + - ][ + - ]: 34 : if ( m_pValueFormatter->getKeyType() != NumberFormat::SCIENTIFIC )
626 : : {
627 [ + - ][ + - ]: 34 : m_bMaxTextLenModified = getINT16(m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN)) != 0;
[ + - ][ + - ]
628 [ + - ]: 34 : if ( !m_bMaxTextLenModified )
629 : : {
630 : 34 : sal_Int32 nFieldLen = 0;
631 [ + - ][ + - ]: 34 : xField->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Precision") ) ) >>= nFieldLen;
[ + - ]
632 : :
633 [ - + ][ + - ]: 34 : if (nFieldLen && nFieldLen <= USHRT_MAX)
634 : : {
635 : 0 : Any aVal;
636 [ # # ]: 0 : aVal <<= (sal_Int16)nFieldLen;
637 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
[ # # ]
638 : :
639 : 34 : m_bMaxTextLenModified = sal_True;
640 : : }
641 : : }
642 : : else
643 : 0 : m_bMaxTextLenModified = sal_False; // to get sure that the text len won't be set in unloaded
644 : : }
645 : 34 : }
646 : 34 : }
647 : :
648 : : //------------------------------------------------------------------------------
649 : 34 : void OEditModel::onDisconnectedDbColumn()
650 : : {
651 : 34 : OEditBaseModel::onDisconnectedDbColumn();
652 : :
653 : 34 : m_pValueFormatter.reset();
654 : :
655 [ # # ][ - + ]: 34 : if ( hasField() && m_bMaxTextLenModified )
[ - + ]
656 : : {
657 : 0 : Any aVal;
658 [ # # ]: 0 : aVal <<= (sal_Int16)0; // Only if it was 0, I switched it in onConnectedDbColumn
659 [ # # ][ # # ]: 0 : m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
[ # # ]
660 : 0 : m_bMaxTextLenModified = sal_False;
661 : : }
662 : 34 : }
663 : :
664 : : //------------------------------------------------------------------------------
665 : 34 : sal_Bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType )
666 : : {
667 : : // if we act as rich text currently, we do not allow binding to a database column
668 [ - + ]: 34 : if ( implActsAsRichText() )
669 : 0 : return sal_False;
670 : :
671 : 34 : return OEditBaseModel::approveDbColumnType( _nColumnType );
672 : : }
673 : :
674 : : //------------------------------------------------------------------------------
675 : 31 : void OEditModel::resetNoBroadcast()
676 : : {
677 : 31 : OEditBaseModel::resetNoBroadcast();
678 : 31 : }
679 : :
680 : : //------------------------------------------------------------------------------
681 : 0 : sal_Bool OEditModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
682 : : {
683 [ # # ][ # # ]: 0 : Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
684 : :
685 : 0 : ::rtl::OUString sNewValue;
686 : 0 : aNewValue >>= sNewValue;
687 : :
688 [ # # ][ # # ]: 0 : if ( !aNewValue.hasValue()
[ # # # # ]
689 : 0 : || ( sNewValue.isEmpty() // an empty string
690 : : && m_bEmptyIsNull // which should be interpreted as NULL
691 : : )
692 : : )
693 : : {
694 [ # # ][ # # ]: 0 : m_xColumnUpdate->updateNull();
695 : : }
696 : : else
697 : : {
698 : : OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::commitControlValueToDbColumn: no value formatter!" );
699 : : try
700 : : {
701 [ # # ]: 0 : if ( m_pValueFormatter.get() )
702 : : {
703 [ # # ][ # # ]: 0 : if ( !m_pValueFormatter->setFormattedValue( sNewValue ) )
704 : 0 : return sal_False;
705 : : }
706 : : else
707 [ # # ][ # # ]: 0 : m_xColumnUpdate->updateString( sNewValue );
708 : : }
709 [ # # ]: 0 : catch ( const Exception& )
710 : : {
711 : 0 : return sal_False;
712 : : }
713 : : }
714 : :
715 [ # # ]: 0 : return sal_True;
716 : : }
717 : :
718 : : //------------------------------------------------------------------------------
719 : 68 : Any OEditModel::translateDbColumnToControlValue()
720 : : {
721 : : OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::translateDbColumnToControlValue: no value formatter!" );
722 : 68 : Any aRet;
723 [ + - ]: 68 : if ( m_pValueFormatter.get() )
724 : : {
725 [ + - ]: 68 : ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
726 [ + + + - ]: 172 : if ( sValue.isEmpty()
[ - + ][ + - ]
727 [ + - ]: 52 : && m_pValueFormatter->getColumn().is()
728 [ + - ][ + - ]: 52 : && m_pValueFormatter->getColumn()->wasNull()
[ + - ]
729 : : )
730 : : {
731 : : }
732 : : else
733 : : {
734 : : // #i2817# OJ
735 [ + - ][ + - ]: 68 : sal_uInt16 nMaxTextLen = getINT16( m_xAggregateSet->getPropertyValue( PROPERTY_MAXTEXTLEN ) );
[ + - ][ + - ]
736 [ # # ][ - + ]: 68 : if ( nMaxTextLen && sValue.getLength() > nMaxTextLen )
[ - + ]
737 : : {
738 : 0 : sal_Int32 nDiff = sValue.getLength() - nMaxTextLen;
739 : 0 : sValue = sValue.replaceAt( nMaxTextLen, nDiff, ::rtl::OUString() );
740 : : }
741 : :
742 [ + - ]: 68 : aRet <<= sValue;
743 : 68 : }
744 : : }
745 : :
746 [ + - ][ # # ]: 68 : return aRet.hasValue() ? aRet : makeAny( ::rtl::OUString() );
[ - + ][ # # ]
747 : : }
748 : :
749 : : //------------------------------------------------------------------------------
750 : 31 : Any OEditModel::getDefaultForReset() const
751 : : {
752 : 31 : return makeAny( m_aDefaultText );
753 : : }
754 : :
755 : : //.........................................................................
756 : : }
757 : : //.........................................................................
758 : :
759 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|