1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DatabaseForm.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
34 #include "componenttools.hxx"
35 #include "DatabaseForm.hxx"
36 #include "EventThread.hxx"
37 #include "frm_module.hxx"
38 #include "frm_resource.hrc"
39 #include "frm_resource.hxx"
40 #include "GroupManager.hxx"
41 #include "property.hrc"
42 #include "property.hxx"
43 #include "services.hxx"
45 #include <com/sun/star/awt/XControlContainer.hpp>
46 #include <com/sun/star/awt/XTextComponent.hpp>
47 #include <com/sun/star/form/DataSelectionType.hpp>
48 #include <com/sun/star/form/FormComponentType.hpp>
49 #include <com/sun/star/form/TabulatorCycle.hpp>
50 #include <com/sun/star/frame/FrameSearchFlag.hpp>
51 #include <com/sun/star/frame/XDispatch.hpp>
52 #include <com/sun/star/frame/XDispatchProvider.hpp>
53 #include <com/sun/star/frame/XModel.hpp>
54 #include <com/sun/star/io/XObjectInputStream.hpp>
55 #include <com/sun/star/io/XObjectOutputStream.hpp>
56 #include <com/sun/star/sdb/CommandType.hpp>
57 #include <com/sun/star/sdb/RowSetVetoException.hpp>
58 #include <com/sun/star/sdb/SQLContext.hpp>
59 #include <com/sun/star/sdb/XColumnUpdate.hpp>
60 #include <com/sun/star/sdbc/DataType.hpp>
61 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
62 #include <com/sun/star/sdbc/ResultSetType.hpp>
63 #include <com/sun/star/sdbc/XRowSet.hpp>
64 #include <com/sun/star/sdbcx/Privilege.hpp>
65 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
66 #include <com/sun/star/util/XCancellable.hpp>
67 #include <com/sun/star/util/XURLTransformer.hpp>
68 #include <com/sun/star/util/XModifiable2.hpp>
70 #include <comphelper/basicio.hxx>
71 #include <comphelper/container.hxx>
72 #include <comphelper/enumhelper.hxx>
73 #include <comphelper/extract.hxx>
74 #include <comphelper/seqstream.hxx>
75 #include <comphelper/sequence.hxx>
76 #include <comphelper/stl_types.hxx>
77 #include <comphelper/uno3.hxx>
78 #include <connectivity/dbtools.hxx>
79 #include <cppuhelper/exc_hlp.hxx>
80 #include <cppuhelper/implbase2.hxx>
81 #include <osl/mutex.hxx>
82 #include <rtl/math.hxx>
83 #include <rtl/tencinfo.h>
84 #include <svtools/inetstrm.hxx>
85 #include <svtools/inettype.hxx>
86 #include <tools/debug.hxx>
87 #include <tools/diagnose_ex.h>
88 #include <tools/fsys.hxx>
89 #include <tools/inetmsg.hxx>
90 #include <tools/urlobj.hxx>
91 #include <unotools/ucblockbytes.hxx>
92 #include <unotools/ucbstreamhelper.hxx>
93 #include <vcl/svapp.hxx>
94 #include <vcl/timer.hxx>
95 #include <vos/mutex.hxx>
101 // compatiblity: DatabaseCursorType is dead, but for compatiblity reasons we still have to write it ...
107 enum DatabaseCursorType
109 DatabaseCursorType_FORWARD
= 0,
110 DatabaseCursorType_SNAPSHOT
= 1,
111 DatabaseCursorType_KEYSET
= 2,
112 DatabaseCursorType_DYNAMIC
= 3,
113 DatabaseCursorType_MAKE_FIXED_SIZE
= SAL_MAX_ENUM
118 using namespace ::dbtools
;
119 using namespace ::comphelper
;
120 using namespace ::com::sun::star::uno
;
121 using namespace ::com::sun::star::sdb
;
122 using namespace ::com::sun::star::sdbc
;
123 using namespace ::com::sun::star::sdbcx
;
124 using namespace ::com::sun::star::beans
;
125 using namespace ::com::sun::star::container
;
126 using namespace ::com::sun::star::task
;
127 using namespace ::com::sun::star::frame
;
128 using namespace ::com::sun::star::form
;
129 using namespace ::com::sun::star::awt
;
130 using namespace ::com::sun::star::io
;
131 using namespace ::com::sun::star::lang
;
132 using namespace ::com::sun::star::data
;
133 using namespace ::com::sun::star::util
;
135 //--------------------------------------------------------------------------
136 extern "C" void SAL_CALL
createRegistryInfo_ODatabaseForm()
138 static ::frm::OMultiInstanceAutoRegistration
< ::frm::ODatabaseForm
> aAutoRegistration
;
141 //.........................................................................
144 //.........................................................................
146 //==================================================================
147 //= DocumentModifyGuard
148 //==================================================================
149 class DocumentModifyGuard
152 DocumentModifyGuard( const Reference
< XInterface
>& _rxFormComponent
)
153 :m_xDocumentModify( getXModel( _rxFormComponent
), UNO_QUERY
)
155 OSL_ENSURE( m_xDocumentModify
.is(), "DocumentModifyGuard::DocumentModifyGuard: no document, or no XModifiable2!" );
156 impl_changeModifiableFlag_nothrow( false );
158 ~DocumentModifyGuard()
160 impl_changeModifiableFlag_nothrow( true );
164 void impl_changeModifiableFlag_nothrow( const bool _enable
)
168 if ( m_xDocumentModify
.is() )
169 _enable
? m_xDocumentModify
->enableSetModified() : m_xDocumentModify
->disableSetModified();
171 catch( const Exception
& )
173 DBG_UNHANDLED_EXCEPTION();
178 Reference
< XModifiable2
> m_xDocumentModify
;
181 //==================================================================
182 //= OFormSubmitResetThread
183 //=-----------------------------------------------------------------
184 //= submitting and resetting html-forms asynchronously
185 //==================================================================
187 //------------------------------------------------------------------
188 class OFormSubmitResetThread
: public OComponentEventThread
192 // duplicate an event with respect to it's type
193 virtual EventObject
*cloneEvent( const EventObject
*pEvt
) const;
195 // process an event. while processing the mutex isn't locked, and pCompImpl
196 // is made sure to remain valid
197 virtual void processEvent( ::cppu::OComponentHelper
* _pCompImpl
,
198 const EventObject
* _pEvt
,
199 const Reference
<XControl
>& _rControl
,
204 OFormSubmitResetThread(ODatabaseForm
* pControl
) : OComponentEventThread(pControl
) { }
207 //------------------------------------------------------------------
208 EventObject
* OFormSubmitResetThread::cloneEvent(
209 const EventObject
*pEvt
) const
211 return new ::com::sun::star::awt::MouseEvent( *(::com::sun::star::awt::MouseEvent
*)pEvt
);
214 //------------------------------------------------------------------
215 void OFormSubmitResetThread::processEvent(
216 ::cppu::OComponentHelper
* pCompImpl
,
217 const EventObject
*_pEvt
,
218 const Reference
<XControl
>& _rControl
,
222 ((ODatabaseForm
*)pCompImpl
)->submit_impl(_rControl
, *static_cast<const ::com::sun::star::awt::MouseEvent
*>(_pEvt
), true);
224 ((ODatabaseForm
*)pCompImpl
)->reset_impl(true);
227 //==================================================================
229 //==================================================================
231 //------------------------------------------------------------------
232 Reference
< XInterface
> SAL_CALL
ODatabaseForm::Create( const Reference
< XMultiServiceFactory
>& _rxFactory
)
234 return *( new ODatabaseForm( _rxFactory
) );
237 //------------------------------------------------------------------------------
238 Sequence
<sal_Int8
> SAL_CALL
ODatabaseForm::getImplementationId() throw(RuntimeException
)
240 return OImplementationIds::getImplementationId(getTypes());
243 //------------------------------------------------------------------
244 Sequence
<Type
> SAL_CALL
ODatabaseForm::getTypes() throw(RuntimeException
)
247 Sequence
<Type
> aAggregateTypes
;
248 Reference
<XTypeProvider
> xAggregateTypes
;
249 if (query_aggregation(m_xAggregate
, xAggregateTypes
))
250 aAggregateTypes
= xAggregateTypes
->getTypes();
252 Sequence
< Type
> aRet
= concatSequences(
253 aAggregateTypes
, ODatabaseForm_BASE1::getTypes(), OFormComponents::getTypes()
255 aRet
= concatSequences( aRet
, ODatabaseForm_BASE2::getTypes(), ODatabaseForm_BASE3::getTypes() );
256 return concatSequences( aRet
, OPropertySetAggregationHelper::getTypes() );
259 //------------------------------------------------------------------
260 Any SAL_CALL
ODatabaseForm::queryAggregation(const Type
& _rType
) throw(RuntimeException
)
262 Any aReturn
= ODatabaseForm_BASE1::queryInterface(_rType
);
263 // our own interfaces
264 if (!aReturn
.hasValue())
266 aReturn
= ODatabaseForm_BASE2::queryInterface(_rType
);
267 // property set related interfaces
268 if (!aReturn
.hasValue())
270 aReturn
= OPropertySetAggregationHelper::queryInterface(_rType
);
272 // form component collection related interfaces
273 if (!aReturn
.hasValue())
275 aReturn
= OFormComponents::queryAggregation(_rType
);
277 // interfaces already present in the aggregate which we want to reroute
278 // only available if we could create the aggregate
279 if (!aReturn
.hasValue() && m_xAggregateAsRowSet
.is())
280 aReturn
= ODatabaseForm_BASE3::queryInterface(_rType
);
282 // aggregate interfaces
283 // (ask the aggregated object _after_ the OComponentHelper (base of OFormComponents),
284 // so calls to the XComponent interface reach us and not the aggreagtion)
285 if (!aReturn
.hasValue() && m_xAggregate
.is())
286 aReturn
= m_xAggregate
->queryAggregation(_rType
);
294 DBG_NAME(ODatabaseForm
);
295 //------------------------------------------------------------------
296 ODatabaseForm::ODatabaseForm(const Reference
<XMultiServiceFactory
>& _rxFactory
)
297 :OFormComponents(_rxFactory
)
298 ,OPropertySetAggregationHelper(OComponentHelper::rBHelper
)
299 ,OPropertyChangeListener(m_aMutex
)
300 ,m_aLoadListeners(m_aMutex
)
301 ,m_aRowSetApproveListeners(m_aMutex
)
302 ,m_aRowSetListeners(m_aMutex
)
303 ,m_aSubmitListeners(m_aMutex
)
304 ,m_aErrorListeners(m_aMutex
)
305 ,m_aResetListeners( *this, m_aMutex
)
306 ,m_aPropertyBagHelper( *this )
307 ,m_pAggregatePropertyMultiplexer(NULL
)
308 ,m_pGroupManager( NULL
)
309 ,m_aParameterManager( m_aMutex
, _rxFactory
)
310 ,m_aFilterManager( _rxFactory
)
315 ,m_bInsertOnly( sal_False
)
316 ,m_eSubmitMethod(FormSubmitMethod_GET
)
317 ,m_eSubmitEncoding(FormSubmitEncoding_URL
)
318 ,m_eNavigation(NavigationBarMode_CURRENT
)
319 ,m_bAllowInsert(sal_True
)
320 ,m_bAllowUpdate(sal_True
)
321 ,m_bAllowDelete(sal_True
)
322 ,m_bLoaded(sal_False
)
323 ,m_bSubForm(sal_False
)
324 ,m_bForwardingConnection(sal_False
)
325 ,m_bSharingConnection( sal_False
)
327 DBG_CTOR( ODatabaseForm
, NULL
);
331 //------------------------------------------------------------------
332 ODatabaseForm::ODatabaseForm( const ODatabaseForm
& _cloneSource
)
333 :OFormComponents( _cloneSource
)
334 ,OPropertySetAggregationHelper( OComponentHelper::rBHelper
)
335 ,OPropertyChangeListener( m_aMutex
)
336 ,ODatabaseForm_BASE1()
337 ,ODatabaseForm_BASE2()
338 ,ODatabaseForm_BASE3()
339 ,IPropertyBagHelperContext()
340 ,m_aLoadListeners( m_aMutex
)
341 ,m_aRowSetApproveListeners( m_aMutex
)
342 ,m_aRowSetListeners( m_aMutex
)
343 ,m_aSubmitListeners( m_aMutex
)
344 ,m_aErrorListeners( m_aMutex
)
345 ,m_aResetListeners( *this, m_aMutex
)
346 ,m_aPropertyBagHelper( *this )
347 ,m_pAggregatePropertyMultiplexer( NULL
)
348 ,m_pGroupManager( NULL
)
349 ,m_aParameterManager( m_aMutex
, _cloneSource
.m_xServiceFactory
)
350 ,m_aFilterManager( _cloneSource
.m_xServiceFactory
)
351 ,m_pLoadTimer( NULL
)
353 ,m_nResetsPending( 0 )
355 ,m_bInsertOnly( _cloneSource
.m_bInsertOnly
)
356 ,m_aControlBorderColorFocus( _cloneSource
.m_aControlBorderColorFocus
)
357 ,m_aControlBorderColorMouse( _cloneSource
.m_aControlBorderColorMouse
)
358 ,m_aControlBorderColorInvalid( _cloneSource
.m_aControlBorderColorInvalid
)
359 ,m_aDynamicControlBorder( _cloneSource
.m_aDynamicControlBorder
)
360 ,m_sName( _cloneSource
.m_sName
)
361 ,m_aTargetURL( _cloneSource
.m_aTargetURL
)
362 ,m_aTargetFrame( _cloneSource
.m_aTargetFrame
)
363 ,m_eSubmitMethod( _cloneSource
.m_eSubmitMethod
)
364 ,m_eSubmitEncoding( _cloneSource
.m_eSubmitEncoding
)
365 ,m_eNavigation( _cloneSource
.m_eNavigation
)
366 ,m_bAllowInsert( _cloneSource
.m_bAllowInsert
)
367 ,m_bAllowUpdate( _cloneSource
.m_bAllowUpdate
)
368 ,m_bAllowDelete( _cloneSource
.m_bAllowDelete
)
369 ,m_bLoaded( sal_False
)
370 ,m_bSubForm( sal_False
)
371 ,m_bForwardingConnection( sal_False
)
372 ,m_bSharingConnection( sal_False
)
374 DBG_CTOR( ODatabaseForm
, NULL
);
378 osl_incrementInterlockedCount( &m_refCount
);
380 // our aggregated rowset itself is not cloneable, so simply copy the properties
381 ::comphelper::copyProperties( _cloneSource
.m_xAggregateSet
, m_xAggregateSet
);
383 // also care for the dynamic properties: If the clone source has properties which we do not have,
387 Reference
< XPropertySet
> xSourceProps( const_cast< ODatabaseForm
& >( _cloneSource
).queryAggregation(
388 XPropertySet::static_type() ), UNO_QUERY_THROW
);
389 Reference
< XPropertySetInfo
> xSourcePSI( xSourceProps
->getPropertySetInfo(), UNO_SET_THROW
);
390 Reference
< XPropertyState
> xSourcePropState( xSourceProps
, UNO_QUERY
);
392 Reference
< XPropertySetInfo
> xDestPSI( getPropertySetInfo(), UNO_QUERY_THROW
);
394 Sequence
< Property
> aSourceProperties( xSourcePSI
->getProperties() );
395 for ( const Property
* pSourceProperty
= aSourceProperties
.getConstArray();
396 pSourceProperty
!= aSourceProperties
.getConstArray() + aSourceProperties
.getLength();
400 if ( xDestPSI
->hasPropertyByName( pSourceProperty
->Name
) )
403 // the initial value passed to XPropertyContainer is also used as default, usually. So, try
404 // to retrieve the default of the source property
406 if ( xSourcePropState
.is() )
408 aInitialValue
= xSourcePropState
->getPropertyDefault( pSourceProperty
->Name
);
412 aInitialValue
= xSourceProps
->getPropertyValue( pSourceProperty
->Name
);
414 addProperty( pSourceProperty
->Name
, pSourceProperty
->Attributes
, aInitialValue
);
415 setPropertyValue( pSourceProperty
->Name
, xSourceProps
->getPropertyValue( pSourceProperty
->Name
) );
418 catch( const Exception
& )
420 throw WrappedTargetException(
421 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given database form." ) ),
422 *const_cast< ODatabaseForm
* >( &_cloneSource
),
423 ::cppu::getCaughtException()
427 osl_decrementInterlockedCount( &m_refCount
);
430 //------------------------------------------------------------------
431 void ODatabaseForm::impl_construct()
433 // aggregate a row set
434 increment(m_refCount
);
436 m_xAggregate
= Reference
< XAggregation
>( m_xServiceFactory
->createInstance( SRV_SDB_ROWSET
), UNO_QUERY_THROW
);
437 m_xAggregateAsRowSet
.set( m_xAggregate
, UNO_QUERY_THROW
);
438 setAggregation( m_xAggregate
);
441 // listen for the properties, important for Parameters
442 if ( m_xAggregateSet
.is() )
444 m_pAggregatePropertyMultiplexer
= new OPropertyChangeMultiplexer(this, m_xAggregateSet
, sal_False
);
445 m_pAggregatePropertyMultiplexer
->acquire();
446 m_pAggregatePropertyMultiplexer
->addProperty(PROPERTY_COMMAND
);
447 m_pAggregatePropertyMultiplexer
->addProperty(PROPERTY_ACTIVE_CONNECTION
);
451 Reference
< XWarningsSupplier
> xRowSetWarnings( m_xAggregate
, UNO_QUERY
);
452 m_aWarnings
.setExternalWarnings( xRowSetWarnings
);
455 if ( m_xAggregate
.is() )
457 m_xAggregate
->setDelegator( static_cast< XWeak
* >( this ) );
461 m_aFilterManager
.initialize( m_xAggregateSet
);
462 m_aParameterManager
.initialize( this, m_xAggregate
);
464 declareForwardedProperty( PROPERTY_ID_ACTIVE_CONNECTION
);
466 decrement( m_refCount
);
468 m_pGroupManager
= new OGroupManager( this );
469 m_pGroupManager
->acquire();
472 //------------------------------------------------------------------
473 ODatabaseForm::~ODatabaseForm()
475 DBG_DTOR(ODatabaseForm
,NULL
);
477 m_pGroupManager
->release();
478 m_pGroupManager
= NULL
;
480 if (m_xAggregate
.is())
481 m_xAggregate
->setDelegator( NULL
);
483 m_aWarnings
.setExternalWarnings( NULL
);
485 if (m_pAggregatePropertyMultiplexer
)
487 m_pAggregatePropertyMultiplexer
->dispose();
488 m_pAggregatePropertyMultiplexer
->release();
489 m_pAggregatePropertyMultiplexer
= NULL
;
493 //==============================================================================
495 //------------------------------------------------------------------------
496 ::rtl::OUString
ODatabaseForm::GetDataURLEncoded(const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
498 return GetDataEncoded(true,SubmitButton
,MouseEvt
);
500 // -----------------------------------------------------------------------------
501 ::rtl::OUString
ODatabaseForm::GetDataEncoded(bool _bURLEncoded
,const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
503 // Liste von successful Controls fuellen
504 HtmlSuccessfulObjList aSuccObjList
;
505 FillSuccessfulList( aSuccObjList
, SubmitButton
, MouseEvt
);
508 // Liste zu ::rtl::OUString zusammensetzen
509 ::rtl::OUStringBuffer aResult
;
510 ::rtl::OUString aName
;
511 ::rtl::OUString aValue
;
513 for ( HtmlSuccessfulObjListIterator pSuccObj
= aSuccObjList
.begin();
514 pSuccObj
< aSuccObjList
.end();
518 aName
= pSuccObj
->aName
;
519 aValue
= pSuccObj
->aValue
;
520 if( pSuccObj
->nRepresentation
== SUCCESSFUL_REPRESENT_FILE
&& aValue
.getLength() )
522 // Bei File-URLs wird der Dateiname und keine URL uebertragen,
523 // weil Netscape dies so macht.
525 aURL
.SetSmartProtocol(INET_PROT_FILE
);
526 aURL
.SetSmartURL(aValue
);
527 if( INET_PROT_FILE
== aURL
.GetProtocol() )
528 aValue
= INetURLObject::decode(aURL
.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS
);
533 aResult
.append(aName
);
534 aResult
.append(sal_Unicode('='));
535 aResult
.append(aValue
);
537 if (pSuccObj
< aSuccObjList
.end() - 1)
540 aResult
.append(sal_Unicode('&'));
542 aResult
.appendAscii("\r\n");
547 aSuccObjList
.clear();
549 return aResult
.makeStringAndClear();
552 //==============================================================================
554 //------------------------------------------------------------------------
555 ::rtl::OUString
ODatabaseForm::GetDataTextEncoded(const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
557 return GetDataEncoded(false,SubmitButton
,MouseEvt
);
560 //------------------------------------------------------------------------
561 Sequence
<sal_Int8
> ODatabaseForm::GetDataMultiPartEncoded(const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
, ::rtl::OUString
& rContentType
)
565 INetMIMEMessage aParent
;
566 aParent
.EnableAttachChild( INETMSG_MULTIPART_FORM_DATA
);
569 // Liste von successful Controls fuellen
570 HtmlSuccessfulObjList aSuccObjList
;
571 FillSuccessfulList( aSuccObjList
, SubmitButton
, MouseEvt
);
574 // Liste zu ::rtl::OUString zusammensetzen
575 ::rtl::OUString aResult
;
576 for ( HtmlSuccessfulObjListIterator pSuccObj
= aSuccObjList
.begin();
577 pSuccObj
< aSuccObjList
.end();
581 if( pSuccObj
->nRepresentation
== SUCCESSFUL_REPRESENT_TEXT
)
582 InsertTextPart( aParent
, pSuccObj
->aName
, pSuccObj
->aValue
);
583 else if( pSuccObj
->nRepresentation
== SUCCESSFUL_REPRESENT_FILE
)
584 InsertFilePart( aParent
, pSuccObj
->aName
, pSuccObj
->aValue
);
589 aSuccObjList
.clear();
591 // Fuer Parent MessageStream erzeugen
592 INetMIMEMessageStream aMessStream
;
593 aMessStream
.SetSourceMessage( &aParent
);
594 aMessStream
.GenerateHeader( sal_False
);
596 // MessageStream in SvStream kopieren
597 SvMemoryStream aMemStream
;
598 char* pBuf
= new char[1025];
600 while( (nRead
= aMessStream
.Read(pBuf
, 1024)) > 0 )
601 aMemStream
.Write( pBuf
, nRead
);
605 aMemStream
.Seek( 0 );
606 void* pData
= (void*)aMemStream
.GetData();
607 sal_Int32 nLen
= aMemStream
.Seek(STREAM_SEEK_TO_END
);
609 rContentType
= UniString(aParent
.GetContentType());
610 return Sequence
<sal_Int8
>((sal_Int8
*)pData
, nLen
);
613 //------------------------------------------------------------------------
616 static void appendDigits( sal_Int32 _nNumber
, sal_Int8 nDigits
, ::rtl::OUStringBuffer
& _rOut
)
618 sal_Int32 nCurLen
= _rOut
.getLength();
619 _rOut
.append( _nNumber
);
620 while ( _rOut
.getLength() - nCurLen
< nDigits
)
621 _rOut
.insert( nCurLen
, (sal_Unicode
)'0' );
625 //------------------------------------------------------------------------
626 void ODatabaseForm::AppendComponent(HtmlSuccessfulObjList
& rList
, const Reference
<XPropertySet
>& xComponentSet
, const ::rtl::OUString
& rNamePrefix
,
627 const Reference
<XControl
>& rxSubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
629 if (!xComponentSet
.is())
632 // MIB 25.6.98: Geschachtelte Formulare abfangen ... oder muesste
633 // man sie submitten?
634 if (!hasProperty(PROPERTY_CLASSID
, xComponentSet
))
638 if (!hasProperty(PROPERTY_NAME
, xComponentSet
))
641 sal_Int16 nClassId
= 0;
642 xComponentSet
->getPropertyValue(PROPERTY_CLASSID
) >>= nClassId
;
643 ::rtl::OUString aName
;
644 xComponentSet
->getPropertyValue( PROPERTY_NAME
) >>= aName
;
645 if( !aName
.getLength() && nClassId
!= FormComponentType::IMAGEBUTTON
)
647 else // Name um den Prefix erweitern
648 aName
= rNamePrefix
+ aName
;
653 case FormComponentType::COMMANDBUTTON
:
655 // Es wird nur der gedrueckte Submit-Button ausgewertet
656 // MIB: Sofern ueberhaupt einer uebergeben wurde
657 if( rxSubmitButton
.is() )
659 Reference
<XPropertySet
> xSubmitButtonComponent(rxSubmitButton
->getModel(), UNO_QUERY
);
660 if (xSubmitButtonComponent
== xComponentSet
&& hasProperty(PROPERTY_LABEL
, xComponentSet
))
663 ::rtl::OUString aLabel
;
664 xComponentSet
->getPropertyValue( PROPERTY_LABEL
) >>= aLabel
;
665 rList
.push_back( HtmlSuccessfulObj(aName
, aLabel
) );
671 case FormComponentType::IMAGEBUTTON
:
673 // Es wird nur der gedrueckte Submit-Button ausgewertet
674 // MIB: Sofern ueberhaupt einer uebergeben wurde
675 if( rxSubmitButton
.is() )
677 Reference
<XPropertySet
> xSubmitButtonComponent(rxSubmitButton
->getModel(), UNO_QUERY
);
678 if (xSubmitButtonComponent
== xComponentSet
)
680 // <name>.x=<pos.X>&<name>.y=<pos.Y>
681 ::rtl::OUString aLhs
= aName
;
682 ::rtl::OUString aRhs
= ::rtl::OUString::valueOf( MouseEvt
.X
);
684 // nur wenn ein Name vorhanden ist, kann ein name.x
685 aLhs
+= aName
.getLength() ? UniString::CreateFromAscii(".x") : UniString::CreateFromAscii("x");
686 rList
.push_back( HtmlSuccessfulObj(aLhs
, aRhs
) );
689 aRhs
= ::rtl::OUString::valueOf( MouseEvt
.Y
);
690 aLhs
+= aName
.getLength() ? UniString::CreateFromAscii(".y") : UniString::CreateFromAscii("y");
691 rList
.push_back( HtmlSuccessfulObj(aLhs
, aRhs
) );
697 // CheckBoxen / RadioButtons
698 case FormComponentType::CHECKBOX
:
699 case FormComponentType::RADIOBUTTON
:
702 if( !hasProperty(PROPERTY_STATE
, xComponentSet
) )
704 sal_Int16 nChecked
= 0;
705 xComponentSet
->getPropertyValue( PROPERTY_STATE
) >>= nChecked
;
709 ::rtl::OUString aStrValue
;
710 if( hasProperty(PROPERTY_REFVALUE
, xComponentSet
) )
711 xComponentSet
->getPropertyValue( PROPERTY_REFVALUE
) >>= aStrValue
;
713 rList
.push_back( HtmlSuccessfulObj(aName
, aStrValue
) );
717 case FormComponentType::TEXTFIELD
:
720 if( !hasProperty(PROPERTY_TEXT
, xComponentSet
) )
723 // MIB: Spezial-Behandlung fuer Multiline-Edit nur dann, wenn
724 // es auch ein Control dazu gibt.
725 Any aTmp
= xComponentSet
->getPropertyValue( PROPERTY_MULTILINE
);
726 sal_Bool bMulti
= rxSubmitButton
.is()
727 && (aTmp
.getValueType().getTypeClass() == TypeClass_BOOLEAN
)
729 ::rtl::OUString sText
;
730 if ( bMulti
) // Bei MultiLineEdit Text am Control abholen
733 Reference
<XControlContainer
> xControlContainer(rxSubmitButton
->getContext(), UNO_QUERY
);
734 if( !xControlContainer
.is() ) break;
736 Sequence
<Reference
<XControl
> > aControlSeq
= xControlContainer
->getControls();
737 Reference
<XControl
> xControl
;
738 Reference
<XFormComponent
> xControlComponent
;
740 // Richtiges Control suchen
742 for( i
=0; i
<aControlSeq
.getLength(); i
++ )
744 xControl
= aControlSeq
.getConstArray()[i
];
745 Reference
<XPropertySet
> xModel(xControl
->getModel(), UNO_QUERY
);
746 if (xModel
== xComponentSet
)
748 Reference
<XTextComponent
> xTextComponent(xControl
, UNO_QUERY
);
749 if( xTextComponent
.is() )
750 sText
= xTextComponent
->getText();
754 // Control nicht gefunden oder nicht existent, (Edit im Grid)
755 if (i
== aControlSeq
.getLength())
756 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= sText
;
759 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= sText
;
761 rList
.push_back( HtmlSuccessfulObj(aName
, sText
) );
764 // ComboBox, Patternfield
765 case FormComponentType::COMBOBOX
:
766 case FormComponentType::PATTERNFIELD
:
769 if( hasProperty(PROPERTY_TEXT
, xComponentSet
) )
771 ::rtl::OUString aText
;
772 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= aText
;
773 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
776 case FormComponentType::CURRENCYFIELD
:
777 case FormComponentType::NUMERICFIELD
:
779 // <name>=<wert> // wert wird als double mit Punkt als Decimaltrenner
780 // kein Wert angegeben (NULL) -> wert leer
781 if( hasProperty(PROPERTY_VALUE
, xComponentSet
) )
783 ::rtl::OUString aText
;
784 Any aVal
= xComponentSet
->getPropertyValue( PROPERTY_VALUE
);
786 double aDoubleVal
= 0;
787 if (aVal
>>= aDoubleVal
)
789 sal_Int16 nScale
= 0;
790 xComponentSet
->getPropertyValue( PROPERTY_DECIMAL_ACCURACY
) >>= nScale
;
791 aText
= ::rtl::math::doubleToUString(aDoubleVal
, rtl_math_StringFormat_F
, nScale
, '.', sal_True
);
793 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
796 case FormComponentType::DATEFIELD
:
798 // <name>=<wert> // Wert wird als Datum im Format (MM-DD-YYYY)
799 // kein Wert angegeben (NULL) -> wert leer
800 if( hasProperty(PROPERTY_DATE
, xComponentSet
) )
802 ::rtl::OUString aText
;
803 Any aVal
= xComponentSet
->getPropertyValue( PROPERTY_DATE
);
804 sal_Int32 nInt32Val
= 0;
805 if (aVal
>>= nInt32Val
)
807 ::Date
aDate( nInt32Val
);
808 ::rtl::OUStringBuffer aBuffer
;
809 appendDigits( aDate
.GetMonth(), 2, aBuffer
);
810 aBuffer
.append( (sal_Unicode
)'-' );
811 appendDigits( aDate
.GetDay(), 2, aBuffer
);
812 aBuffer
.append( (sal_Unicode
)'-' );
813 appendDigits( aDate
.GetYear(), 4, aBuffer
);
814 aText
= aBuffer
.makeStringAndClear();
816 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
819 case FormComponentType::TIMEFIELD
:
821 // <name>=<wert> // Wert wird als Zeit im Format (HH:MM:SS) angegeben
822 // kein Wert angegeben (NULL) -> wert leer
823 if( hasProperty(PROPERTY_TIME
, xComponentSet
) )
825 ::rtl::OUString aText
;
826 Any aVal
= xComponentSet
->getPropertyValue( PROPERTY_TIME
);
827 sal_Int32 nInt32Val
= 0;
828 if (aVal
>>= nInt32Val
)
830 ::Time
aTime(nInt32Val
);
831 ::rtl::OUStringBuffer aBuffer
;
832 appendDigits( aTime
.GetHour(), 2, aBuffer
);
833 aBuffer
.append( (sal_Unicode
)'-' );
834 appendDigits( aTime
.GetMin(), 2, aBuffer
);
835 aBuffer
.append( (sal_Unicode
)'-' );
836 appendDigits( aTime
.GetSec(), 2, aBuffer
);
837 aText
= aBuffer
.makeStringAndClear();
839 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
844 case FormComponentType::HIDDENCONTROL
:
848 if( hasProperty(PROPERTY_HIDDEN_VALUE
, xComponentSet
) )
850 ::rtl::OUString aText
;
851 xComponentSet
->getPropertyValue( PROPERTY_HIDDEN_VALUE
) >>= aText
;
852 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
857 case FormComponentType::FILECONTROL
:
860 if( hasProperty(PROPERTY_TEXT
, xComponentSet
) )
863 ::rtl::OUString aText
;
864 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= aText
;
865 rList
.push_back( HtmlSuccessfulObj(aName
, aText
, SUCCESSFUL_REPRESENT_FILE
) );
870 case FormComponentType::LISTBOX
:
873 // <name>=<Token0>&<name>=<Token1>&...&<name>=<TokenN> (Mehrfachselektion)
874 if (!hasProperty(PROPERTY_SELECT_SEQ
, xComponentSet
) ||
875 !hasProperty(PROPERTY_STRINGITEMLIST
, xComponentSet
))
879 Sequence
< ::rtl::OUString
> aVisibleList
;
880 xComponentSet
->getPropertyValue( PROPERTY_STRINGITEMLIST
) >>= aVisibleList
;
881 sal_Int32 nStringCnt
= aVisibleList
.getLength();
882 const ::rtl::OUString
* pStrings
= aVisibleList
.getConstArray();
885 Sequence
< ::rtl::OUString
> aValueList
;
886 xComponentSet
->getPropertyValue( PROPERTY_VALUE_SEQ
) >>= aValueList
;
887 sal_Int32 nValCnt
= aValueList
.getLength();
888 const ::rtl::OUString
* pVals
= aValueList
.getConstArray();
891 Sequence
<sal_Int16
> aSelectList
;
892 xComponentSet
->getPropertyValue( PROPERTY_SELECT_SEQ
) >>= aSelectList
;
893 sal_Int32 nSelCount
= aSelectList
.getLength();
894 const sal_Int16
* pSels
= aSelectList
.getConstArray();
896 // Einfach- oder Mehrfach-Selektion
897 // Bei Einfach-Selektionen beruecksichtigt MT nur den ersten Eintrag
899 if (nSelCount
> 1 && !getBOOL(xComponentSet
->getPropertyValue(PROPERTY_MULTISELECTION
)))
902 // Die Indizes in der Selektions-Liste koennen auch ungueltig sein,
903 // also muss man die gueltigen erstmal raussuchen um die Laenge
904 // der neuen Liste zu bestimmen.
905 sal_Int32 nCurCnt
= 0;
907 for( i
=0; i
<nSelCount
; ++i
)
909 if( pSels
[i
] < nStringCnt
)
913 ::rtl::OUString aSubValue
;
914 for(i
=0; i
<nCurCnt
; ++i
)
916 sal_Int16 nSelPos
= pSels
[i
];
917 if (nSelPos
< nValCnt
&& pVals
[nSelPos
].getLength())
919 aSubValue
= pVals
[nSelPos
];
923 aSubValue
= pStrings
[nSelPos
];
925 rList
.push_back( HtmlSuccessfulObj(aName
, aSubValue
) );
928 case FormComponentType::GRIDCONTROL
:
930 // Die einzelnen Spaltenwerte werden verschickt,
931 // der Name wird mit dem Prefix des Names des Grids erweitert
932 Reference
<XIndexAccess
> xContainer(xComponentSet
, UNO_QUERY
);
933 if (!xContainer
.is())
936 aName
+= UniString('.');
938 Reference
<XPropertySet
> xSet
;
939 sal_Int32 nCount
= xContainer
->getCount();
940 // we know already how many objects should be appended,
941 // so why not allocate the space for them
942 rList
.reserve( nCount
+ rList
.capacity() ); // not size()
943 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
945 xContainer
->getByIndex(i
) >>= xSet
;
947 AppendComponent(rList
, xSet
, aName
, rxSubmitButton
, MouseEvt
);
953 //------------------------------------------------------------------------
954 void ODatabaseForm::FillSuccessfulList( HtmlSuccessfulObjList
& rList
,
955 const Reference
<XControl
>& rxSubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
959 // Ueber Components iterieren
960 Reference
<XPropertySet
> xComponentSet
;
961 ::rtl::OUString aPrefix
;
963 // we know already how many objects should be appended,
964 // so why not allocate the space for them
965 rList
.reserve( getCount() );
966 for( sal_Int32 nIndex
=0; nIndex
< getCount(); nIndex
++ )
968 getByIndex( nIndex
) >>= xComponentSet
;
969 AppendComponent(rList
, xComponentSet
, aPrefix
, rxSubmitButton
, MouseEvt
);
973 //------------------------------------------------------------------------
974 void ODatabaseForm::Encode( ::rtl::OUString
& rString
) const
976 ::rtl::OUString aResult
;
979 // rString.Convert(CHARSET_SYSTEM, CHARSET_ANSI);
982 // Zeilenendezeichen werden als CR dargestellt
983 UniString sConverter
= rString
;
984 sConverter
.ConvertLineEnd( LINEEND_CR
);
985 rString
= sConverter
;
988 // Jeden einzelnen Character ueberpruefen
989 sal_Int32 nStrLen
= rString
.getLength();
990 sal_Unicode nCharCode
;
991 for( sal_Int32 nCurPos
=0; nCurPos
< nStrLen
; ++nCurPos
)
993 nCharCode
= rString
[nCurPos
];
995 // Behandlung fuer chars, die kein alphanumerisches Zeichen sind
996 // und CharacterCodes > 127
997 if( (!isalnum(nCharCode
) && nCharCode
!= (sal_Unicode
)' ') || nCharCode
> 127 )
1002 aResult
+= ::rtl::OUString::createFromAscii("%0D%0A"); // Hex-Darstellung CR LF
1006 // Netscape Sonderbehandlung
1012 aResult
+= UniString(nCharCode
);
1018 short nHi
= ((sal_Int16
)nCharCode
) / 16;
1019 short nLo
= ((sal_Int16
)nCharCode
) - (nHi
*16);
1020 if( nHi
> 9 ) nHi
+= (int)'A'-10; else nHi
+= (int)'0';
1021 if( nLo
> 9 ) nLo
+= (int)'A'-10; else nLo
+= (int)'0';
1022 aResult
+= UniString('%');
1023 aResult
+= UniString((sal_Unicode
)nHi
);
1024 aResult
+= UniString((sal_Unicode
)nLo
);
1029 aResult
+= UniString(nCharCode
);
1033 // Spaces durch '+' ersetzen
1034 aResult
= aResult
.replace(' ', '+');
1039 //------------------------------------------------------------------------
1040 void ODatabaseForm::InsertTextPart( INetMIMEMessage
& rParent
, const ::rtl::OUString
& rName
,
1041 const ::rtl::OUString
& rData
)
1044 // Part als Message-Child erzeugen
1045 INetMIMEMessage
* pChild
= new INetMIMEMessage();
1049 ::rtl::OUString aContentDisp
= ::rtl::OUString::createFromAscii("form-data; name=\"");
1050 aContentDisp
+= rName
;
1051 aContentDisp
+= UniString('\"');
1052 pChild
->SetContentDisposition( aContentDisp
);
1053 pChild
->SetContentType( UniString::CreateFromAscii("text/plain") );
1055 rtl_TextEncoding eSystemEncoding
= gsl_getSystemTextEncoding();
1056 const sal_Char
* pBestMatchingEncoding
= rtl_getBestMimeCharsetFromTextEncoding( eSystemEncoding
);
1057 UniString aBestMatchingEncoding
= UniString::CreateFromAscii( pBestMatchingEncoding
);
1058 pChild
->SetContentTransferEncoding(aBestMatchingEncoding
);
1061 SvMemoryStream
* pStream
= new SvMemoryStream
;
1062 pStream
->WriteLine( ByteString( UniString(rData
), rtl_getTextEncodingFromMimeCharset(pBestMatchingEncoding
) ) );
1065 pChild
->SetDocumentLB( new SvLockBytes(pStream
, sal_True
) );
1066 rParent
.AttachChild( *pChild
);
1069 //------------------------------------------------------------------------
1070 sal_Bool
ODatabaseForm::InsertFilePart( INetMIMEMessage
& rParent
, const ::rtl::OUString
& rName
,
1071 const ::rtl::OUString
& rFileName
)
1073 UniString
aFileName( rFileName
);
1074 UniString
aContentType(UniString::CreateFromAscii(CONTENT_TYPE_STR_TEXT_PLAIN
));
1075 SvStream
*pStream
= 0;
1077 if( aFileName
.Len() )
1079 // Bisher koennen wir nur File-URLs verarbeiten
1081 aURL
.SetSmartProtocol(INET_PROT_FILE
);
1082 aURL
.SetSmartURL(rFileName
);
1083 if( INET_PROT_FILE
== aURL
.GetProtocol() )
1085 aFileName
= INetURLObject::decode(aURL
.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS
);
1086 DirEntry
aDirEntry( aFileName
);
1087 if( aDirEntry
.Exists() )
1089 pStream
= ::utl::UcbStreamHelper::CreateStream(aFileName
, STREAM_READ
);
1090 if (!pStream
|| (pStream
->GetError() != ERRCODE_NONE
))
1096 INetContentType eContentType
= INetContentTypes::GetContentType4Extension(
1097 aDirEntry
.GetExtension() );
1098 if (eContentType
!= CONTENT_TYPE_UNKNOWN
)
1099 aContentType
= INetContentTypes::GetContentType(eContentType
);
1103 // Wenn irgendetwas nicht geklappt hat, legen wir einen leeren
1106 pStream
= new SvMemoryStream
;
1109 // Part als Message-Child erzeugen
1110 INetMIMEMessage
* pChild
= new INetMIMEMessage
;
1114 ::rtl::OUString aContentDisp
= ::rtl::OUString::createFromAscii( "form-data; name=\"" );
1115 aContentDisp
+= rName
;
1116 aContentDisp
+= UniString('\"');
1117 aContentDisp
+= ::rtl::OUString::createFromAscii("; filename=\"");
1118 aContentDisp
+= aFileName
;
1119 aContentDisp
+= UniString('\"');
1120 pChild
->SetContentDisposition( aContentDisp
);
1121 pChild
->SetContentType( aContentType
);
1122 pChild
->SetContentTransferEncoding( UniString(::rtl::OUString::createFromAscii("8bit")) );
1126 pChild
->SetDocumentLB( new SvLockBytes(pStream
, sal_True
) );
1127 rParent
.AttachChild( *pChild
);
1132 //==============================================================================
1134 //------------------------------------------------------------------------------
1135 void ODatabaseForm::onError( const SQLErrorEvent
& _rEvent
)
1137 m_aErrorListeners
.notifyEach( &XSQLErrorListener::errorOccured
, _rEvent
);
1140 //------------------------------------------------------------------------------
1141 void ODatabaseForm::onError( const SQLException
& _rException
, const ::rtl::OUString
& _rContextDescription
)
1143 if ( !m_aErrorListeners
.getLength() )
1146 SQLErrorEvent
aEvent( *this, makeAny( prependErrorInfo( _rException
, *this, _rContextDescription
) ) );
1150 //------------------------------------------------------------------------------
1151 void ODatabaseForm::updateParameterInfo()
1153 m_aParameterManager
.updateParameterInfo( m_aFilterManager
);
1156 //------------------------------------------------------------------------------
1157 bool ODatabaseForm::hasValidParent() const
1159 // do we have to fill the parameters again?
1162 Reference
<XResultSet
> xResultSet(m_xParent
, UNO_QUERY
);
1163 if (!xResultSet
.is())
1165 DBG_ERROR("ODatabaseForm::hasValidParent() : no parent resultset !");
1170 Reference
< XPropertySet
> xSet( m_xParent
, UNO_QUERY
);
1171 Reference
< XLoadable
> xLoad( m_xParent
, UNO_QUERY
);
1172 if ( xLoad
->isLoaded()
1173 && ( xResultSet
->isBeforeFirst()
1174 || xResultSet
->isAfterLast()
1175 || getBOOL( xSet
->getPropertyValue( PROPERTY_ISNEW
) )
1178 // the parent form is loaded and on a "virtual" row -> not valid
1183 // parent could be forwardonly?
1190 //------------------------------------------------------------------------------
1191 bool ODatabaseForm::fillParameters( ::osl::ResettableMutexGuard
& _rClearForNotifies
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
)
1193 // do we have to fill the parameters again?
1194 if ( !m_aParameterManager
.isUpToDate() )
1195 updateParameterInfo();
1197 // is there a valid parent?
1198 if ( m_bSubForm
&& !hasValidParent() )
1201 // ensure we're connected
1202 if ( !implEnsureConnection() )
1205 if ( m_aParameterManager
.isUpToDate() )
1206 return m_aParameterManager
.fillParameterValues( _rxCompletionHandler
, _rClearForNotifies
);
1211 //------------------------------------------------------------------------------
1212 void ODatabaseForm::saveInsertOnlyState( )
1214 OSL_ENSURE( !m_aIgnoreResult
.hasValue(), "ODatabaseForm::saveInsertOnlyState: overriding old value!" );
1215 m_aIgnoreResult
= m_xAggregateSet
->getPropertyValue( PROPERTY_INSERTONLY
);
1218 //------------------------------------------------------------------------------
1219 void ODatabaseForm::restoreInsertOnlyState( )
1221 if ( m_aIgnoreResult
.hasValue() )
1223 m_xAggregateSet
->setPropertyValue( PROPERTY_INSERTONLY
, m_aIgnoreResult
);
1224 m_aIgnoreResult
= Any();
1228 //------------------------------------------------------------------------------
1229 sal_Bool
ODatabaseForm::executeRowSet(::osl::ResettableMutexGuard
& _rClearForNotifies
, sal_Bool bMoveToFirst
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
)
1231 if (!m_xAggregateAsRowSet
.is())
1234 if (!fillParameters(_rClearForNotifies
, _rxCompletionHandler
))
1237 restoreInsertOnlyState( );
1239 // ensure the aggregated row set has the correct properties
1240 sal_Int32 nConcurrency
= ResultSetConcurrency::READ_ONLY
;
1242 // if we have a parent, who is not positioned on a valid row
1243 // we can't be updatable!
1244 if (m_bSubForm
&& !hasValidParent())
1246 nConcurrency
= ResultSetConcurrency::READ_ONLY
;
1248 // don't use any parameters if we don't have a valid parent
1249 m_aParameterManager
.setAllParametersNull();
1251 // switch to "insert only" mode
1252 saveInsertOnlyState( );
1253 m_xAggregateSet
->setPropertyValue( PROPERTY_INSERTONLY
, makeAny( sal_True
) );
1255 else if (m_bAllowInsert
|| m_bAllowUpdate
|| m_bAllowDelete
)
1256 nConcurrency
= ResultSetConcurrency::UPDATABLE
;
1258 nConcurrency
= ResultSetConcurrency::READ_ONLY
;
1260 m_xAggregateSet
->setPropertyValue( PROPERTY_RESULTSET_CONCURRENCY
, makeAny( (sal_Int32
)nConcurrency
) );
1261 m_xAggregateSet
->setPropertyValue( PROPERTY_RESULTSET_TYPE
, makeAny( (sal_Int32
)ResultSetType::SCROLL_SENSITIVE
) );
1263 sal_Bool bSuccess
= sal_False
;
1266 m_xAggregateAsRowSet
->execute();
1267 bSuccess
= sal_True
;
1269 catch( const RowSetVetoException
& eVeto
)
1273 catch(SQLException
& eDb
)
1275 _rClearForNotifies
.clear();
1276 if (m_sCurrentErrorContext
.getLength())
1277 onError(eDb
, m_sCurrentErrorContext
);
1279 onError(eDb
, FRM_RES_STRING(RID_STR_READERROR
));
1280 _rClearForNotifies
.reset();
1282 restoreInsertOnlyState( );
1287 // adjust the privilege property
1289 m_xAggregateSet
->getPropertyValue(PROPERTY_PRIVILEGES
) >>= m_nPrivileges
;
1290 if (!m_bAllowInsert
)
1291 m_nPrivileges
&= ~Privilege::INSERT
;
1292 if (!m_bAllowUpdate
)
1293 m_nPrivileges
&= ~Privilege::UPDATE
;
1294 if (!m_bAllowDelete
)
1295 m_nPrivileges
&= ~Privilege::DELETE
;
1299 // the row set is positioned _before_ the first row (per definitionem), so move the set ...
1302 // if we have an insert only rowset we move to the insert row
1304 if (((m_nPrivileges
& Privilege::INSERT
) == Privilege::INSERT
)
1307 // move on the insert row of set
1308 // resetting must be done later, after the load events have been posted
1309 // see :moveToInsertRow and load , reload
1310 Reference
<XResultSetUpdate
> xUpdate
;
1311 if (query_aggregation( m_xAggregate
, xUpdate
))
1312 xUpdate
->moveToInsertRow();
1315 catch(SQLException
& eDB
)
1317 _rClearForNotifies
.clear();
1318 if (m_sCurrentErrorContext
.getLength())
1319 onError(eDB
, m_sCurrentErrorContext
);
1321 onError(eDB
, FRM_RES_STRING(RID_STR_READERROR
));
1322 _rClearForNotifies
.reset();
1323 bSuccess
= sal_False
;
1330 //------------------------------------------------------------------
1331 void ODatabaseForm::disposing()
1333 if (m_pAggregatePropertyMultiplexer
)
1334 m_pAggregatePropertyMultiplexer
->dispose();
1339 // cancel the submit/reset-thread
1341 ::osl::MutexGuard
aGuard( m_aMutex
);
1344 m_pThread
->release();
1349 EventObject
aEvt(static_cast<XWeak
*>(this));
1350 m_aLoadListeners
.disposeAndClear(aEvt
);
1351 m_aRowSetApproveListeners
.disposeAndClear(aEvt
);
1352 m_aParameterManager
.disposing( aEvt
);
1353 m_aResetListeners
.disposing();
1354 m_aSubmitListeners
.disposeAndClear(aEvt
);
1355 m_aErrorListeners
.disposeAndClear(aEvt
);
1357 m_aParameterManager
.dispose(); // (to free any references it may have to me)
1358 m_aFilterManager
.dispose(); // (dito)
1360 OFormComponents::disposing();
1361 OPropertySetAggregationHelper::disposing();
1363 // stop listening on the aggregate
1364 if (m_xAggregateAsRowSet
.is())
1365 m_xAggregateAsRowSet
->removeRowSetListener(this);
1367 // dispose the active connection
1368 Reference
<XComponent
> xAggregationComponent
;
1369 if (query_aggregation(m_xAggregate
, xAggregationComponent
))
1370 xAggregationComponent
->dispose();
1372 m_aPropertyBagHelper
.dispose();
1375 //------------------------------------------------------------------------------
1376 Reference
< XConnection
> ODatabaseForm::getConnection()
1378 Reference
< XConnection
> xConn
;
1379 m_xAggregateSet
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xConn
;
1383 //------------------------------------------------------------------------------
1384 ::osl::Mutex
& ODatabaseForm::getMutex()
1389 //==============================================================================
1390 // property handling
1391 //------------------------------------------------------------------------------
1392 void ODatabaseForm::describeFixedAndAggregateProperties(
1393 Sequence
< Property
>& _rProps
,
1394 Sequence
< Property
>& _rAggregateProps
) const
1396 BEGIN_DESCRIBE_AGGREGATION_PROPERTIES(22, m_xAggregateSet
)
1397 // we want to "override" the privileges, since we have additional "AllowInsert" etc. properties
1398 RemoveProperty( _rAggregateProps
, PROPERTY_PRIVILEGES
);
1400 // InsertOnly is also to be overridden, since we sometimes change it ourself
1401 RemoveProperty( _rAggregateProps
, PROPERTY_INSERTONLY
);
1403 // we remove and re-declare the DataSourceName property, 'cause we want it to be constrained, and the
1404 // original property of our aggregate isn't
1405 RemoveProperty( _rAggregateProps
, PROPERTY_DATASOURCE
);
1407 // for connection sharing, we need to override the ActiveConnection property, too
1408 RemoveProperty( _rAggregateProps
, PROPERTY_ACTIVE_CONNECTION
);
1410 // the Filter property is also overwritten, since we have some implicit filters
1411 // (e.g. the ones which result from linking master fields to detail fields
1412 // via column names instead of parameters)
1413 RemoveProperty( _rAggregateProps
, PROPERTY_FILTER
);
1414 RemoveProperty( _rAggregateProps
, PROPERTY_APPLYFILTER
);
1416 DECL_IFACE_PROP4(ACTIVE_CONNECTION
, XConnection
, BOUND
, TRANSIENT
, MAYBEVOID
, CONSTRAINED
);
1417 DECL_BOOL_PROP2 ( APPLYFILTER
, BOUND
, MAYBEDEFAULT
);
1418 DECL_PROP1 ( NAME
, ::rtl::OUString
, BOUND
);
1419 DECL_PROP1 ( MASTERFIELDS
, Sequence
< ::rtl::OUString
>, BOUND
);
1420 DECL_PROP1 ( DETAILFIELDS
, Sequence
< ::rtl::OUString
>, BOUND
);
1421 DECL_PROP2 ( DATASOURCE
, ::rtl::OUString
, BOUND
, CONSTRAINED
);
1422 DECL_PROP3 ( CYCLE
, TabulatorCycle
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1423 DECL_PROP2 ( FILTER
, ::rtl::OUString
, BOUND
, MAYBEDEFAULT
);
1424 DECL_BOOL_PROP2 ( INSERTONLY
, BOUND
, MAYBEDEFAULT
);
1425 DECL_PROP1 ( NAVIGATION
, NavigationBarMode
, BOUND
);
1426 DECL_BOOL_PROP1 ( ALLOWADDITIONS
, BOUND
);
1427 DECL_BOOL_PROP1 ( ALLOWEDITS
, BOUND
);
1428 DECL_BOOL_PROP1 ( ALLOWDELETIONS
, BOUND
);
1429 DECL_PROP2 ( PRIVILEGES
, sal_Int32
, TRANSIENT
, READONLY
);
1430 DECL_PROP1 ( TARGET_URL
, ::rtl::OUString
, BOUND
);
1431 DECL_PROP1 ( TARGET_FRAME
, ::rtl::OUString
, BOUND
);
1432 DECL_PROP1 ( SUBMIT_METHOD
, FormSubmitMethod
, BOUND
);
1433 DECL_PROP1 ( SUBMIT_ENCODING
, FormSubmitEncoding
, BOUND
);
1434 DECL_BOOL_PROP3 ( DYNAMIC_CONTROL_BORDER
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1435 DECL_PROP3 ( CONTROL_BORDER_COLOR_FOCUS
, sal_Int32
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1436 DECL_PROP3 ( CONTROL_BORDER_COLOR_MOUSE
, sal_Int32
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1437 DECL_PROP3 ( CONTROL_BORDER_COLOR_INVALID
, sal_Int32
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1438 END_DESCRIBE_PROPERTIES();
1441 //------------------------------------------------------------------------------
1442 Reference
< XMultiPropertySet
> ODatabaseForm::getPropertiesInterface()
1444 return Reference
< XMultiPropertySet
>( *this, UNO_QUERY
);
1447 //------------------------------------------------------------------------------
1448 ::cppu::IPropertyArrayHelper
& ODatabaseForm::getInfoHelper()
1450 return m_aPropertyBagHelper
.getInfoHelper();
1453 //------------------------------------------------------------------------------
1454 Reference
< XPropertySetInfo
> ODatabaseForm::getPropertySetInfo() throw( RuntimeException
)
1456 return createPropertySetInfo( getInfoHelper() );
1459 //--------------------------------------------------------------------
1460 void SAL_CALL
ODatabaseForm::addProperty( const ::rtl::OUString
& _rName
, ::sal_Int16 _nAttributes
, const Any
& _rInitialValue
) throw (PropertyExistException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
1462 m_aPropertyBagHelper
.addProperty( _rName
, _nAttributes
, _rInitialValue
);
1465 //--------------------------------------------------------------------
1466 void SAL_CALL
ODatabaseForm::removeProperty( const ::rtl::OUString
& _rName
) throw (UnknownPropertyException
, NotRemoveableException
, RuntimeException
)
1468 m_aPropertyBagHelper
.removeProperty( _rName
);
1471 //--------------------------------------------------------------------
1472 Sequence
< PropertyValue
> SAL_CALL
ODatabaseForm::getPropertyValues() throw (RuntimeException
)
1474 return m_aPropertyBagHelper
.getPropertyValues();
1477 //--------------------------------------------------------------------
1478 void SAL_CALL
ODatabaseForm::setPropertyValues( const Sequence
< PropertyValue
>& _rProps
) throw (UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
1480 m_aPropertyBagHelper
.setPropertyValues( _rProps
);
1483 //------------------------------------------------------------------------------
1484 Any SAL_CALL
ODatabaseForm::getWarnings( ) throw (SQLException
, RuntimeException
)
1486 return m_aWarnings
.getWarnings();
1489 //------------------------------------------------------------------------------
1490 void SAL_CALL
ODatabaseForm::clearWarnings( ) throw (SQLException
, RuntimeException
)
1492 m_aWarnings
.clearWarnings();
1495 //------------------------------------------------------------------------------
1496 Reference
< XCloneable
> SAL_CALL
ODatabaseForm::createClone( ) throw (RuntimeException
)
1498 ODatabaseForm
* pClone
= new ODatabaseForm( *this );
1499 osl_incrementInterlockedCount( &pClone
->m_refCount
);
1500 pClone
->clonedFrom( *this );
1501 osl_decrementInterlockedCount( &pClone
->m_refCount
);
1505 //------------------------------------------------------------------------------
1506 void ODatabaseForm::fire( sal_Int32
* pnHandles
, const Any
* pNewValues
, const Any
* pOldValues
, sal_Int32 nCount
, sal_Bool bVetoable
)
1508 // same as in getFastPropertyValue(INT32) : if we're resetting currently don't fire any changes of the
1509 // IsModified property from FALSE to TRUE, as this is only temporary 'til the reset is done
1510 if (m_nResetsPending
> 0)
1512 // look for the PROPERTY_ID_ISMODIFIED
1514 for (nPos
=0; nPos
<nCount
; ++nPos
)
1515 if (pnHandles
[nPos
] == PROPERTY_ID_ISMODIFIED
)
1518 if ((nPos
< nCount
) && (pNewValues
[nPos
].getValueType().getTypeClass() == TypeClass_BOOLEAN
) && getBOOL(pNewValues
[nPos
]))
1519 { // yeah, we found it, and it changed to TRUE
1521 { // just cut the first element
1527 else if (nPos
== nCount
- 1)
1528 // just cut the last element
1531 { // split into two base class calls
1532 OPropertySetAggregationHelper::fire(pnHandles
, pNewValues
, pOldValues
, nPos
, bVetoable
);
1534 OPropertySetAggregationHelper::fire(pnHandles
+ nPos
, pNewValues
+ nPos
, pOldValues
+ nPos
, nCount
- nPos
, bVetoable
);
1540 OPropertySetAggregationHelper::fire(pnHandles
, pNewValues
, pOldValues
, nCount
, bVetoable
);
1543 //------------------------------------------------------------------------------
1544 Any SAL_CALL
ODatabaseForm::getFastPropertyValue( sal_Int32 nHandle
)
1545 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
1547 if ((nHandle
== PROPERTY_ID_ISMODIFIED
) && (m_nResetsPending
> 0))
1548 return ::cppu::bool2any((sal_False
));
1549 // don't allow the aggregate which is currently being reset to return a (temporary) "yes"
1551 return OPropertySetAggregationHelper::getFastPropertyValue(nHandle
);
1554 //------------------------------------------------------------------------------
1555 void ODatabaseForm::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
1559 case PROPERTY_ID_INSERTONLY
:
1560 rValue
<<= m_bInsertOnly
;
1563 case PROPERTY_ID_FILTER
:
1564 rValue
<<= m_aFilterManager
.getFilterComponent( FilterManager::fcPublicFilter
);
1567 case PROPERTY_ID_APPLYFILTER
:
1568 rValue
<<= m_aFilterManager
.isApplyPublicFilter();
1571 case PROPERTY_ID_DATASOURCE
:
1572 rValue
= m_xAggregateSet
->getPropertyValue( PROPERTY_DATASOURCE
);
1575 case PROPERTY_ID_TARGET_URL
:
1576 rValue
<<= m_aTargetURL
;
1578 case PROPERTY_ID_TARGET_FRAME
:
1579 rValue
<<= m_aTargetFrame
;
1581 case PROPERTY_ID_SUBMIT_METHOD
:
1582 rValue
<<= m_eSubmitMethod
;
1584 case PROPERTY_ID_SUBMIT_ENCODING
:
1585 rValue
<<= m_eSubmitEncoding
;
1587 case PROPERTY_ID_NAME
:
1590 case PROPERTY_ID_MASTERFIELDS
:
1591 rValue
<<= m_aMasterFields
;
1593 case PROPERTY_ID_DETAILFIELDS
:
1594 rValue
<<= m_aDetailFields
;
1596 case PROPERTY_ID_CYCLE
:
1599 case PROPERTY_ID_NAVIGATION
:
1600 rValue
<<= m_eNavigation
;
1602 case PROPERTY_ID_ALLOWADDITIONS
:
1603 rValue
<<= (sal_Bool
)m_bAllowInsert
;
1605 case PROPERTY_ID_ALLOWEDITS
:
1606 rValue
<<= (sal_Bool
)m_bAllowUpdate
;
1608 case PROPERTY_ID_ALLOWDELETIONS
:
1609 rValue
<<= (sal_Bool
)m_bAllowDelete
;
1611 case PROPERTY_ID_PRIVILEGES
:
1612 rValue
<<= (sal_Int32
)m_nPrivileges
;
1614 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1615 rValue
= m_aDynamicControlBorder
;
1617 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1618 rValue
= m_aControlBorderColorFocus
;
1620 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1621 rValue
= m_aControlBorderColorMouse
;
1623 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1624 rValue
= m_aControlBorderColorInvalid
;
1627 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( nHandle
) )
1628 m_aPropertyBagHelper
.getDynamicFastPropertyValue( nHandle
, rValue
);
1630 OPropertySetAggregationHelper::getFastPropertyValue( rValue
, nHandle
);
1635 //------------------------------------------------------------------------------
1636 sal_Bool
ODatabaseForm::convertFastPropertyValue( Any
& rConvertedValue
, Any
& rOldValue
,
1637 sal_Int32 nHandle
, const Any
& rValue
) throw( IllegalArgumentException
)
1639 sal_Bool
bModified(sal_False
);
1642 case PROPERTY_ID_INSERTONLY
:
1643 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_bInsertOnly
);
1646 case PROPERTY_ID_FILTER
:
1647 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aFilterManager
.getFilterComponent( FilterManager::fcPublicFilter
) );
1650 case PROPERTY_ID_APPLYFILTER
:
1651 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aFilterManager
.isApplyPublicFilter() );
1654 case PROPERTY_ID_DATASOURCE
:
1656 Any aAggregateProperty
;
1657 getFastPropertyValue(aAggregateProperty
, PROPERTY_ID_DATASOURCE
);
1658 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, aAggregateProperty
, ::getCppuType(static_cast<const ::rtl::OUString
*>(NULL
)));
1661 case PROPERTY_ID_TARGET_URL
:
1662 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aTargetURL
);
1664 case PROPERTY_ID_TARGET_FRAME
:
1665 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aTargetFrame
);
1667 case PROPERTY_ID_SUBMIT_METHOD
:
1668 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_eSubmitMethod
);
1670 case PROPERTY_ID_SUBMIT_ENCODING
:
1671 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_eSubmitEncoding
);
1673 case PROPERTY_ID_NAME
:
1674 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_sName
);
1676 case PROPERTY_ID_MASTERFIELDS
:
1677 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aMasterFields
);
1679 case PROPERTY_ID_DETAILFIELDS
:
1680 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aDetailFields
);
1682 case PROPERTY_ID_CYCLE
:
1683 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aCycle
, ::getCppuType(static_cast<const TabulatorCycle
*>(NULL
)));
1685 case PROPERTY_ID_NAVIGATION
:
1686 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_eNavigation
);
1688 case PROPERTY_ID_ALLOWADDITIONS
:
1689 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bAllowInsert
);
1691 case PROPERTY_ID_ALLOWEDITS
:
1692 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bAllowUpdate
);
1694 case PROPERTY_ID_ALLOWDELETIONS
:
1695 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bAllowDelete
);
1697 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1698 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aDynamicControlBorder
, ::getBooleanCppuType() );
1700 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1701 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aControlBorderColorFocus
, getCppuType( static_cast< sal_Int32
* >( NULL
) ) );
1703 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1704 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aControlBorderColorMouse
, getCppuType( static_cast< sal_Int32
* >( NULL
) ) );
1706 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1707 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aControlBorderColorInvalid
, getCppuType( static_cast< sal_Int32
* >( NULL
) ) );
1710 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle ( nHandle
) )
1711 bModified
= m_aPropertyBagHelper
.convertDynamicFastPropertyValue( nHandle
, rValue
, rConvertedValue
, rOldValue
);
1713 bModified
= OPropertySetAggregationHelper::convertFastPropertyValue( rConvertedValue
, rOldValue
, nHandle
, rValue
);
1719 //------------------------------------------------------------------------------
1720 void ODatabaseForm::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw( Exception
)
1724 case PROPERTY_ID_INSERTONLY
:
1725 rValue
>>= m_bInsertOnly
;
1726 if ( m_aIgnoreResult
.hasValue() )
1727 m_aIgnoreResult
<<= m_bInsertOnly
;
1729 m_xAggregateSet
->setPropertyValue( PROPERTY_INSERTONLY
, makeAny( m_bInsertOnly
) );
1732 case PROPERTY_ID_FILTER
:
1734 ::rtl::OUString sNewFilter
;
1735 rValue
>>= sNewFilter
;
1736 m_aFilterManager
.setFilterComponent( FilterManager::fcPublicFilter
, sNewFilter
);
1740 case PROPERTY_ID_APPLYFILTER
:
1742 sal_Bool bApply
= sal_True
;
1744 m_aFilterManager
.setApplyPublicFilter( bApply
);
1748 case PROPERTY_ID_DATASOURCE
:
1750 Reference
< XConnection
> xSomeConnection
;
1751 if ( ::dbtools::isEmbeddedInDatabase( getParent(), xSomeConnection
) )
1752 throw PropertyVetoException();
1756 m_xAggregateSet
->setPropertyValue(PROPERTY_DATASOURCE
, rValue
);
1758 catch(Exception
&) { }
1761 case PROPERTY_ID_TARGET_URL
:
1762 rValue
>>= m_aTargetURL
;
1764 case PROPERTY_ID_TARGET_FRAME
:
1765 rValue
>>= m_aTargetFrame
;
1767 case PROPERTY_ID_SUBMIT_METHOD
:
1768 rValue
>>= m_eSubmitMethod
;
1770 case PROPERTY_ID_SUBMIT_ENCODING
:
1771 rValue
>>= m_eSubmitEncoding
;
1773 case PROPERTY_ID_NAME
:
1776 case PROPERTY_ID_MASTERFIELDS
:
1777 rValue
>>= m_aMasterFields
;
1778 invlidateParameters();
1780 case PROPERTY_ID_DETAILFIELDS
:
1781 rValue
>>= m_aDetailFields
;
1782 invlidateParameters();
1784 case PROPERTY_ID_CYCLE
:
1787 case PROPERTY_ID_NAVIGATION
:
1788 rValue
>>= m_eNavigation
;
1790 case PROPERTY_ID_ALLOWADDITIONS
:
1791 m_bAllowInsert
= getBOOL(rValue
);
1793 case PROPERTY_ID_ALLOWEDITS
:
1794 m_bAllowUpdate
= getBOOL(rValue
);
1796 case PROPERTY_ID_ALLOWDELETIONS
:
1797 m_bAllowDelete
= getBOOL(rValue
);
1799 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1800 m_aDynamicControlBorder
= rValue
;
1802 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1803 m_aControlBorderColorFocus
= rValue
;
1805 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1806 m_aControlBorderColorMouse
= rValue
;
1808 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1809 m_aControlBorderColorInvalid
= rValue
;
1812 case PROPERTY_ID_ACTIVE_CONNECTION
:
1814 Reference
< XConnection
> xOuterConnection
;
1815 if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection
) )
1817 if ( xOuterConnection
!= Reference
< XConnection
>( rValue
, UNO_QUERY
) )
1818 // somebody's trying to set a connection which is not equal the connection
1819 // implied by the database we're embedded in
1820 throw PropertyVetoException();
1822 OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle
, rValue
);
1827 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( nHandle
) )
1828 m_aPropertyBagHelper
.setDynamicFastPropertyValue( nHandle
, rValue
);
1830 OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle
, rValue
);
1835 //------------------------------------------------------------------
1836 void SAL_CALL
ODatabaseForm::forwardingPropertyValue( sal_Int32 _nHandle
)
1838 OSL_ENSURE( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
, "ODatabaseForm::forwardingPropertyValue: unexpected property!" );
1839 if ( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
)
1841 if ( m_bSharingConnection
)
1842 stopSharingConnection( );
1843 m_bForwardingConnection
= sal_True
;
1847 //------------------------------------------------------------------
1848 void SAL_CALL
ODatabaseForm::forwardedPropertyValue( sal_Int32 _nHandle
, bool /*_bSuccess*/ )
1850 OSL_ENSURE( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
, "ODatabaseForm::forwardedPropertyValue: unexpected property!" );
1851 if ( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
)
1853 m_bForwardingConnection
= sal_False
;
1857 //==============================================================================
1858 // com::sun::star::beans::XPropertyState
1859 //------------------------------------------------------------------
1860 PropertyState
ODatabaseForm::getPropertyStateByHandle(sal_Int32 nHandle
)
1862 PropertyState eState
;
1865 case PROPERTY_ID_NAVIGATION
:
1866 return (NavigationBarMode_CURRENT
== m_eNavigation
) ? PropertyState_DEFAULT_VALUE
: PropertyState_DIRECT_VALUE
;
1868 case PROPERTY_ID_CYCLE
:
1869 eState
= m_aCycle
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1872 case PROPERTY_ID_INSERTONLY
:
1873 eState
= m_bInsertOnly
? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1876 case PROPERTY_ID_FILTER
:
1877 if ( !m_aFilterManager
.getFilterComponent( FilterManager::fcPublicFilter
).getLength() )
1878 eState
= PropertyState_DEFAULT_VALUE
;
1880 eState
= PropertyState_DIRECT_VALUE
;
1883 case PROPERTY_ID_APPLYFILTER
:
1884 eState
= m_aFilterManager
.isApplyPublicFilter() ? PropertyState_DEFAULT_VALUE
: PropertyState_DIRECT_VALUE
;
1887 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1888 eState
= m_aDynamicControlBorder
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1891 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1892 eState
= m_aControlBorderColorFocus
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1895 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1896 eState
= m_aControlBorderColorMouse
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1899 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1900 eState
= m_aControlBorderColorInvalid
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1904 eState
= OPropertySetAggregationHelper::getPropertyStateByHandle(nHandle
);
1909 //------------------------------------------------------------------
1910 void ODatabaseForm::setPropertyToDefaultByHandle(sal_Int32 nHandle
)
1914 case PROPERTY_ID_INSERTONLY
:
1915 case PROPERTY_ID_FILTER
:
1916 case PROPERTY_ID_APPLYFILTER
:
1917 case PROPERTY_ID_NAVIGATION
:
1918 case PROPERTY_ID_CYCLE
:
1919 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1920 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1921 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1922 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1923 setFastPropertyValue( nHandle
, getPropertyDefaultByHandle( nHandle
) );
1927 OPropertySetAggregationHelper::setPropertyToDefaultByHandle(nHandle
);
1931 //------------------------------------------------------------------
1932 Any
ODatabaseForm::getPropertyDefaultByHandle( sal_Int32 nHandle
) const
1937 case PROPERTY_ID_INSERTONLY
:
1938 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1939 aReturn
<<= sal_False
;
1942 case PROPERTY_ID_FILTER
:
1943 aReturn
<<= ::rtl::OUString();
1946 case PROPERTY_ID_APPLYFILTER
:
1947 aReturn
<<= sal_True
;
1950 case PROPERTY_ID_NAVIGATION
:
1951 aReturn
= makeAny(NavigationBarMode_CURRENT
);
1954 case PROPERTY_ID_CYCLE
:
1955 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1956 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1957 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1961 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( nHandle
) )
1962 m_aPropertyBagHelper
.getDynamicPropertyDefaultByHandle( nHandle
, aReturn
);
1964 aReturn
= OPropertySetAggregationHelper::getPropertyDefaultByHandle( nHandle
);
1970 //==============================================================================
1971 // com::sun::star::form::XReset
1972 //------------------------------------------------------------------------------
1973 void SAL_CALL
ODatabaseForm::reset() throw( RuntimeException
)
1975 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
1979 ::osl::MutexGuard
aResetGuard(m_aResetSafety
);
1985 if ( !m_aResetListeners
.empty() )
1987 ::osl::MutexGuard
aResetGuard(m_aResetSafety
);
1989 // create an own thread if we have (approve-)reset-listeners (so the listeners can't do that much damage
1990 // to this thread which is probably the main one)
1993 m_pThread
= new OFormSubmitResetThread(this);
1994 m_pThread
->acquire();
1995 m_pThread
->create();
1998 m_pThread
->addEvent(&aEvt
, sal_False
);
2002 // direct call without any approving by the listeners
2005 ::osl::MutexGuard
aResetGuard(m_aResetSafety
);
2011 //-----------------------------------------------------------------------------
2012 void ODatabaseForm::reset_impl(bool _bAproveByListeners
)
2014 if ( _bAproveByListeners
)
2015 if ( !m_aResetListeners
.approveReset() )
2018 ::osl::ResettableMutexGuard
aResetGuard(m_aResetSafety
);
2019 // do we have a database connected form and stay on the insert row
2020 sal_Bool bInsertRow
= sal_False
;
2021 if (m_xAggregateSet
.is())
2022 bInsertRow
= getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ISNEW
));
2027 // Iterate through all columns and set the default value
2028 Reference
< XColumnsSupplier
> xColsSuppl( m_xAggregateSet
, UNO_QUERY
);
2029 Reference
< XIndexAccess
> xIndexCols( xColsSuppl
->getColumns(), UNO_QUERY
);
2030 for (sal_Int32 i
= 0; i
< xIndexCols
->getCount(); ++i
)
2032 Reference
< XPropertySet
> xColProps
;
2033 xIndexCols
->getByIndex(i
) >>= xColProps
;
2035 Reference
< XColumnUpdate
> xColUpdate( xColProps
, UNO_QUERY
);
2036 if ( !xColUpdate
.is() )
2039 Reference
< XPropertySetInfo
> xPSI
;
2040 if ( xColProps
.is() )
2041 xPSI
= xColProps
->getPropertySetInfo( );
2043 static const ::rtl::OUString
PROPERTY_CONTROLDEFAULT( RTL_CONSTASCII_USTRINGPARAM( "ControlDefault" ) );
2044 if ( xPSI
.is() && xPSI
->hasPropertyByName( PROPERTY_CONTROLDEFAULT
) )
2046 Any aDefault
= xColProps
->getPropertyValue( PROPERTY_CONTROLDEFAULT
);
2048 sal_Bool bReadOnly
= sal_False
;
2049 if ( xPSI
->hasPropertyByName( PROPERTY_ISREADONLY
) )
2050 xColProps
->getPropertyValue( PROPERTY_ISREADONLY
) >>= bReadOnly
;
2056 if ( aDefault
.hasValue() )
2057 xColUpdate
->updateObject( aDefault
);
2061 DBG_UNHANDLED_EXCEPTION();
2073 Reference
< XColumnsSupplier
> xParentColSupp( m_xParent
, UNO_QUERY
);
2074 Reference
< XNameAccess
> xParentCols
;
2075 if ( xParentColSupp
.is() )
2076 xParentCols
= xParentColSupp
->getColumns();
2078 if ( xParentCols
.is() && xParentCols
->hasElements() && m_aMasterFields
.getLength() )
2082 // analyze our parameters
2083 if ( !m_aParameterManager
.isUpToDate() )
2084 updateParameterInfo();
2086 m_aParameterManager
.resetParameterValues( );
2088 catch(const Exception
&)
2090 OSL_ENSURE(sal_False
, "ODatabaseForm::reset_impl: could not initialize the master-detail-driven parameters!");
2096 aResetGuard
.clear();
2097 // iterate through all components. don't use an XIndexAccess as this will cause massive
2098 // problems with the count.
2099 Reference
<XEnumeration
> xIter
= createEnumeration();
2100 while (xIter
->hasMoreElements())
2102 Reference
<XReset
> xReset
;
2103 xIter
->nextElement() >>= xReset
;
2106 // TODO : all reset-methods have to be thread-safe
2111 aResetGuard
.reset();
2112 // ensure that the row isn't modified
2113 // (do this _before_ the listeners are notified ! their reaction (maybe asynchronous) may depend
2114 // on the modified state of the row
2115 // 21.02.00 - 73265 - FS)
2117 m_xAggregateSet
->setPropertyValue(PROPERTY_ISMODIFIED
, ::cppu::bool2any(sal_Bool(sal_False
)));
2119 aResetGuard
.clear();
2121 m_aResetListeners
.resetted();
2124 aResetGuard
.reset();
2125 // and again : ensure the row isn't modified
2126 // we already did this after we (and maybe our dependents) resetted the values, but the listeners may have changed the row, too
2128 m_xAggregateSet
->setPropertyValue(PROPERTY_ISMODIFIED
, ::cppu::bool2any((sal_False
)));
2133 //-----------------------------------------------------------------------------
2134 void SAL_CALL
ODatabaseForm::addResetListener(const Reference
<XResetListener
>& _rListener
) throw( RuntimeException
)
2136 m_aResetListeners
.addTypedListener( _rListener
);
2139 //-----------------------------------------------------------------------------
2140 void SAL_CALL
ODatabaseForm::removeResetListener(const Reference
<XResetListener
>& _rListener
) throw( RuntimeException
)
2142 m_aResetListeners
.removeTypedListener( _rListener
);
2145 //==============================================================================
2146 // com::sun::star::form::XSubmit
2147 //------------------------------------------------------------------------------
2148 void SAL_CALL
ODatabaseForm::submit( const Reference
<XControl
>& Control
,
2149 const ::com::sun::star::awt::MouseEvent
& MouseEvt
) throw( RuntimeException
)
2152 ::osl::MutexGuard
aGuard(m_aMutex
);
2153 // Sind Controls und eine Submit-URL vorhanden?
2154 if( !getCount() || !m_aTargetURL
.getLength() )
2158 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
2159 if (m_aSubmitListeners
.getLength())
2161 // create an own thread if we have (approve-)submit-listeners (so the listeners can't do that much damage
2162 // to this thread which is probably the main one)
2165 m_pThread
= new OFormSubmitResetThread(this);
2166 m_pThread
->acquire();
2167 m_pThread
->create();
2169 m_pThread
->addEvent(&MouseEvt
, Control
, sal_True
);
2173 // direct call without any approving by the listeners
2175 submit_impl( Control
, MouseEvt
, true );
2178 // -----------------------------------------------------------------------------
2179 void lcl_dispatch(const Reference
< XFrame
>& xFrame
,const Reference
<XURLTransformer
>& xTransformer
,const ::rtl::OUString
& aURLStr
,const ::rtl::OUString
& aReferer
,const ::rtl::OUString
& aTargetName
2180 ,const ::rtl::OUString
& aData
,rtl_TextEncoding _eEncoding
)
2183 aURL
.Complete
= aURLStr
;
2184 xTransformer
->parseStrict(aURL
);
2186 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aURL
, aTargetName
,
2187 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
| FrameSearchFlag::CHILDREN
|
2188 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
| FrameSearchFlag::TASKS
);
2192 Sequence
<PropertyValue
> aArgs(2);
2193 aArgs
.getArray()[0].Name
= ::rtl::OUString::createFromAscii("Referer");
2194 aArgs
.getArray()[0].Value
<<= aReferer
;
2196 // build a sequence from the to-be-submitted string
2197 ByteString
a8BitData(aData
.getStr(), (sal_uInt16
)aData
.getLength(), _eEncoding
);
2198 // always ANSI #58641
2199 Sequence
< sal_Int8
> aPostData((sal_Int8
*)a8BitData
.GetBuffer(), a8BitData
.Len());
2200 Reference
< XInputStream
> xPostData
= new SequenceInputStream(aPostData
);
2202 aArgs
.getArray()[1].Name
= ::rtl::OUString::createFromAscii("PostData");
2203 aArgs
.getArray()[1].Value
<<= xPostData
;
2205 xDisp
->dispatch(aURL
, aArgs
);
2206 } // if (xDisp.is())
2208 //------------------------------------------------------------------------------
2209 void ODatabaseForm::submit_impl(const Reference
<XControl
>& Control
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
, bool _bAproveByListeners
)
2212 if (_bAproveByListeners
)
2214 ::cppu::OInterfaceIteratorHelper
aIter(m_aSubmitListeners
);
2215 EventObject
aEvt(static_cast<XWeak
*>(this));
2216 sal_Bool bCanceled
= sal_False
;
2217 while (aIter
.hasMoreElements() && !bCanceled
)
2219 if (!((XSubmitListener
*)aIter
.next())->approveSubmit(aEvt
))
2220 bCanceled
= sal_True
;
2227 FormSubmitEncoding eSubmitEncoding
;
2228 FormSubmitMethod eSubmitMethod
;
2229 ::rtl::OUString aURLStr
;
2230 ::rtl::OUString aReferer
;
2231 ::rtl::OUString aTargetName
;
2232 Reference
< XModel
> xModel
;
2234 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
2237 Reference
<XChild
> xParent(m_xParent
, UNO_QUERY
);
2240 xModel
= getXModel(xParent
->getParent());
2243 aReferer
= xModel
->getURL();
2246 aTargetName
= m_aTargetFrame
;
2248 eSubmitEncoding
= m_eSubmitEncoding
;
2249 eSubmitMethod
= m_eSubmitMethod
;
2250 aURLStr
= m_aTargetURL
;
2255 Reference
< XFrame
> xFrame
= xModel
->getCurrentController()->getFrame();
2259 Reference
<XURLTransformer
>
2260 xTransformer(m_xServiceFactory
->createInstance(
2261 ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY
);
2262 DBG_ASSERT(xTransformer
.is(), "ODatabaseForm::submit_impl : could not create an URL transformer !");
2265 if( eSubmitEncoding
== FormSubmitEncoding_URL
)
2267 ::rtl::OUString aData
;
2269 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
2270 aData
= GetDataURLEncoded( Control
, MouseEvt
);
2275 if( eSubmitMethod
== FormSubmitMethod_GET
)
2277 INetURLObject
aUrlObj( aURLStr
, INetURLObject::WAS_ENCODED
);
2278 aUrlObj
.SetParam( aData
, INetURLObject::ENCODE_ALL
);
2279 aURL
.Complete
= aUrlObj
.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS
);
2280 if (xTransformer
.is())
2281 xTransformer
->parseStrict(aURL
);
2283 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aURL
, aTargetName
,
2284 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
| FrameSearchFlag::CHILDREN
|
2285 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
| FrameSearchFlag::TASKS
);
2289 Sequence
<PropertyValue
> aArgs(1);
2290 aArgs
.getArray()->Name
= ::rtl::OUString::createFromAscii("Referer");
2291 aArgs
.getArray()->Value
<<= aReferer
;
2292 xDisp
->dispatch(aURL
, aArgs
);
2296 else if( eSubmitMethod
== FormSubmitMethod_POST
)
2298 lcl_dispatch(xFrame
,xTransformer
,aURLStr
,aReferer
,aTargetName
,aData
,RTL_TEXTENCODING_MS_1252
);
2301 else if( eSubmitEncoding
== FormSubmitEncoding_MULTIPART
)
2304 aURL
.Complete
= aURLStr
;
2305 xTransformer
->parseStrict(aURL
);
2307 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aURL
, aTargetName
,
2308 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
| FrameSearchFlag::CHILDREN
|
2309 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
| FrameSearchFlag::TASKS
);
2313 ::rtl::OUString aContentType
;
2314 Sequence
<sal_Int8
> aData
;
2316 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
2317 aData
= GetDataMultiPartEncoded(Control
, MouseEvt
, aContentType
);
2319 if (!aData
.getLength())
2322 Sequence
<PropertyValue
> aArgs(3);
2323 aArgs
.getArray()[0].Name
= ::rtl::OUString::createFromAscii("Referer");
2324 aArgs
.getArray()[0].Value
<<= aReferer
;
2325 aArgs
.getArray()[1].Name
= ::rtl::OUString::createFromAscii("ContentType");
2326 aArgs
.getArray()[1].Value
<<= aContentType
;
2328 // build a sequence from the to-be-submitted string
2329 Reference
< XInputStream
> xPostData
= new SequenceInputStream(aData
);
2331 aArgs
.getArray()[2].Name
= ::rtl::OUString::createFromAscii("PostData");
2332 aArgs
.getArray()[2].Value
<<= xPostData
;
2334 xDisp
->dispatch(aURL
, aArgs
);
2337 else if( eSubmitEncoding
== FormSubmitEncoding_TEXT
)
2339 ::rtl::OUString aData
;
2341 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
2342 aData
= GetDataTextEncoded( Reference
<XControl
> (), MouseEvt
);
2345 lcl_dispatch(xFrame
,xTransformer
,aURLStr
,aReferer
,aTargetName
,aData
,osl_getThreadTextEncoding());
2348 DBG_ERROR("ODatabaseForm::submit_Impl : wrong encoding !");
2354 //------------------------------------------------------------------------------
2355 void SAL_CALL
ODatabaseForm::addSubmitListener(const Reference
<XSubmitListener
>& _rListener
) throw( RuntimeException
)
2357 m_aSubmitListeners
.addInterface(_rListener
);
2360 //------------------------------------------------------------------------------
2361 void SAL_CALL
ODatabaseForm::removeSubmitListener(const Reference
<XSubmitListener
>& _rListener
) throw( RuntimeException
)
2363 m_aSubmitListeners
.removeInterface(_rListener
);
2366 //==============================================================================
2367 // com::sun::star::sdbc::XSQLErrorBroadcaster
2368 //------------------------------------------------------------------------------
2369 void SAL_CALL
ODatabaseForm::addSQLErrorListener(const Reference
<XSQLErrorListener
>& _rListener
) throw( RuntimeException
)
2371 m_aErrorListeners
.addInterface(_rListener
);
2374 //------------------------------------------------------------------------------
2375 void SAL_CALL
ODatabaseForm::removeSQLErrorListener(const Reference
<XSQLErrorListener
>& _rListener
) throw( RuntimeException
)
2377 m_aErrorListeners
.removeInterface(_rListener
);
2380 //------------------------------------------------------------------------------
2381 void ODatabaseForm::invlidateParameters()
2383 ::osl::MutexGuard
aGuard(m_aMutex
);
2384 m_aParameterManager
.clearAllParameterInformation();
2387 //==============================================================================
2389 //------------------------------------------------------------------------------
2390 void ODatabaseForm::_propertyChanged(const PropertyChangeEvent
& evt
) throw( RuntimeException
)
2392 if ((0 == evt
.PropertyName
.compareToAscii(PROPERTY_ACTIVE_CONNECTION
)) && !m_bForwardingConnection
)
2394 // the rowset changed its active connection itself (without interaction from our side), so
2395 // we need to fire this event, too
2396 sal_Int32 nHandle
= PROPERTY_ID_ACTIVE_CONNECTION
;
2397 fire(&nHandle
, &evt
.NewValue
, &evt
.OldValue
, 1, sal_False
);
2399 else // it was one of the statement relevant props
2401 // if the statement has changed we have to delete the parameter info
2402 invlidateParameters();
2406 //==============================================================================
2408 //------------------------------------------------------------------------------
2409 void SAL_CALL
ODatabaseForm::setParent(const InterfaceRef
& Parent
) throw ( ::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
)
2411 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2413 Reference
<XForm
> xParentForm(getParent(), UNO_QUERY
);
2414 if (xParentForm
.is())
2418 Reference
< XRowSetApproveBroadcaster
> xParentApprBroadcast( xParentForm
, UNO_QUERY_THROW
);
2419 xParentApprBroadcast
->removeRowSetApproveListener( this );
2421 Reference
< XLoadable
> xParentLoadable( xParentForm
, UNO_QUERY_THROW
);
2422 xParentLoadable
->removeLoadListener( this );
2424 Reference
< XPropertySet
> xParentProperties( xParentForm
, UNO_QUERY_THROW
);
2425 xParentProperties
->removePropertyChangeListener( PROPERTY_ISNEW
, this );
2427 catch( const Exception
& )
2429 DBG_UNHANDLED_EXCEPTION();
2433 OFormComponents::setParent(Parent
);
2435 xParentForm
.set(getParent(), UNO_QUERY
);
2436 if ( xParentForm
.is() )
2440 Reference
< XRowSetApproveBroadcaster
> xParentApprBroadcast( xParentForm
, UNO_QUERY_THROW
);
2441 xParentApprBroadcast
->addRowSetApproveListener( this );
2443 Reference
< XLoadable
> xParentLoadable( xParentForm
, UNO_QUERY_THROW
);
2444 xParentLoadable
->addLoadListener( this );
2446 Reference
< XPropertySet
> xParentProperties( xParentForm
, UNO_QUERY_THROW
);
2447 xParentProperties
->addPropertyChangeListener( PROPERTY_ISNEW
, this );
2449 catch( const Exception
& )
2451 DBG_UNHANDLED_EXCEPTION();
2455 Reference
< XConnection
> xOuterConnection
;
2456 sal_Bool bIsEmbedded
= ::dbtools::isEmbeddedInDatabase( Parent
, xOuterConnection
);
2458 // clear the guard before setting property values, because of the notifications
2459 // which are triggered there
2462 m_xAggregateSet
->setPropertyValue( PROPERTY_DATASOURCE
, makeAny( ::rtl::OUString() ) );
2465 //==============================================================================
2466 // smartXTabControllerModel
2467 //------------------------------------------------------------------------------
2468 sal_Bool SAL_CALL
ODatabaseForm::getGroupControl() throw(com::sun::star::uno::RuntimeException
)
2470 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2472 // Sollen Controls in einer TabOrder gruppe zusammengefasst werden?
2473 if (m_aCycle
.hasValue())
2475 sal_Int32 nCycle
= 0;
2476 ::cppu::enum2int(nCycle
, m_aCycle
);
2477 return nCycle
!= TabulatorCycle_PAGE
;
2480 if (isLoaded() && getConnection().is())
2486 //------------------------------------------------------------------------------
2487 void SAL_CALL
ODatabaseForm::setControlModels(const Sequence
<Reference
<XControlModel
> >& rControls
) throw( RuntimeException
)
2489 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2491 // TabIndex in der Reihenfolge der Sequence setzen
2492 const Reference
<XControlModel
>* pControls
= rControls
.getConstArray();
2493 sal_Int16 nTabIndex
= 1;
2494 sal_Int32 nCount
= getCount();
2495 sal_Int32 nNewCount
= rControls
.getLength();
2497 // HiddenControls und Formulare werden nicht aufgefuehrt
2498 if (nNewCount
<= nCount
)
2501 for (sal_Int32 i
=0; i
< nNewCount
; ++i
, ++pControls
)
2503 Reference
<XFormComponent
> xComp(*pControls
, UNO_QUERY
);
2506 // suchen der Componente in der Liste
2507 for (sal_Int32 j
= 0; j
< nCount
; ++j
)
2509 Reference
<XFormComponent
> xElement
;
2510 ::cppu::extractInterface(xElement
, getByIndex(j
));
2511 if (xComp
== xElement
)
2513 Reference
<XPropertySet
> xSet(xComp
, UNO_QUERY
);
2514 if (xSet
.is() && hasProperty(PROPERTY_TABINDEX
, xSet
))
2515 xSet
->setPropertyValue( PROPERTY_TABINDEX
, makeAny(nTabIndex
++) );
2524 //------------------------------------------------------------------------------
2525 Sequence
<Reference
<XControlModel
> > SAL_CALL
ODatabaseForm::getControlModels() throw( RuntimeException
)
2527 ::osl::MutexGuard
aGuard(m_aMutex
);
2528 return m_pGroupManager
->getControlModels();
2531 //------------------------------------------------------------------------------
2532 void SAL_CALL
ODatabaseForm::setGroup( const Sequence
<Reference
<XControlModel
> >& _rGroup
, const ::rtl::OUString
& Name
) throw( RuntimeException
)
2534 ::osl::MutexGuard
aGuard(m_aMutex
);
2536 // Die Controls werden gruppiert, indem ihr Name dem Namen des ersten
2537 // Controls der Sequenz angepasst wird
2538 const Reference
<XControlModel
>* pControls
= _rGroup
.getConstArray();
2539 Reference
< XPropertySet
> xSet
;
2540 ::rtl::OUString
sGroupName( Name
);
2542 for( sal_Int32 i
=0; i
<_rGroup
.getLength(); ++i
, ++pControls
)
2544 xSet
= xSet
.query( *pControls
);
2547 // can't throw an exception other than a RuntimeException (which would not be appropriate),
2548 // so we ignore (and only assert) this
2549 OSL_ENSURE( sal_False
, "ODatabaseForm::setGroup: invalid arguments!" );
2553 if (!sGroupName
.getLength())
2554 xSet
->getPropertyValue(PROPERTY_NAME
) >>= sGroupName
;
2556 xSet
->setPropertyValue(PROPERTY_NAME
, makeAny(sGroupName
));
2560 //------------------------------------------------------------------------------
2561 sal_Int32 SAL_CALL
ODatabaseForm::getGroupCount() throw( RuntimeException
)
2563 ::osl::MutexGuard
aGuard(m_aMutex
);
2564 return m_pGroupManager
->getGroupCount();
2567 //------------------------------------------------------------------------------
2568 void SAL_CALL
ODatabaseForm::getGroup( sal_Int32 nGroup
, Sequence
<Reference
<XControlModel
> >& _rGroup
, ::rtl::OUString
& _rName
) throw( RuntimeException
)
2570 ::osl::MutexGuard
aGuard(m_aMutex
);
2572 _rName
= ::rtl::OUString();
2574 if ((nGroup
< 0) || (nGroup
>= m_pGroupManager
->getGroupCount()))
2576 m_pGroupManager
->getGroup( nGroup
, _rGroup
, _rName
);
2579 //------------------------------------------------------------------------------
2580 void SAL_CALL
ODatabaseForm::getGroupByName(const ::rtl::OUString
& Name
, Sequence
< Reference
<XControlModel
> >& _rGroup
) throw( RuntimeException
)
2582 ::osl::MutexGuard
aGuard(m_aMutex
);
2584 m_pGroupManager
->getGroupByName( Name
, _rGroup
);
2587 //==============================================================================
2588 // com::sun::star::lang::XEventListener
2589 //------------------------------------------------------------------------------
2590 void SAL_CALL
ODatabaseForm::disposing(const EventObject
& Source
) throw( RuntimeException
)
2592 // does the call come from the connection which we are sharing with our parent?
2593 if ( isSharingConnection() )
2595 Reference
< XConnection
> xConnSource( Source
.Source
, UNO_QUERY
);
2596 if ( xConnSource
.is() )
2598 #if OSL_DEBUG_LEVEL > 0
2599 Reference
< XConnection
> xActiveConn
;
2600 m_xAggregateSet
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xActiveConn
;
2601 OSL_ENSURE( xActiveConn
.get() == xConnSource
.get(), "ODatabaseForm::disposing: where did this come from?" );
2602 // there should be exactly one XConnection object we're listening at - our aggregate connection
2604 disposingSharedConnection( xConnSource
);
2608 OInterfaceContainer::disposing(Source
);
2610 // does the disposing come from the aggregate ?
2611 if (m_xAggregate
.is())
2612 { // no -> forward it
2613 com::sun::star::uno::Reference
<com::sun::star::lang::XEventListener
> xListener
;
2614 if (query_aggregation(m_xAggregate
, xListener
))
2615 xListener
->disposing(Source
);
2619 //------------------------------------------------------------------------------
2620 void ODatabaseForm::impl_createLoadTimer()
2622 OSL_PRECOND( m_pLoadTimer
== NULL
, "ODatabaseForm::impl_createLoadTimer: timer already exists!" );
2623 m_pLoadTimer
= new Timer();
2624 m_pLoadTimer
->SetTimeout(100);
2625 m_pLoadTimer
->SetTimeoutHdl(LINK(this,ODatabaseForm
,OnTimeout
));
2628 //==============================================================================
2629 // com::sun::star::form::XLoadListener
2630 //------------------------------------------------------------------------------
2631 void SAL_CALL
ODatabaseForm::loaded(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2633 // now start the rowset listening to recover cursor events
2634 load_impl(sal_True
);
2636 ::osl::MutexGuard
aGuard(m_aMutex
);
2637 Reference
<XRowSet
> xParentRowSet(m_xParent
, UNO_QUERY
);
2638 if (xParentRowSet
.is())
2639 xParentRowSet
->addRowSetListener(this);
2641 impl_createLoadTimer();
2645 //------------------------------------------------------------------------------
2646 void SAL_CALL
ODatabaseForm::unloading(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2649 // now stop the rowset listening if we are a subform
2650 ::osl::MutexGuard
aGuard(m_aMutex
);
2651 DELETEZ(m_pLoadTimer
);
2653 Reference
<XRowSet
> xParentRowSet(m_xParent
, UNO_QUERY
);
2654 if (xParentRowSet
.is())
2655 xParentRowSet
->removeRowSetListener(this);
2661 //------------------------------------------------------------------------------
2662 void SAL_CALL
ODatabaseForm::unloaded(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2667 //------------------------------------------------------------------------------
2668 void SAL_CALL
ODatabaseForm::reloading(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2670 // now stop the rowset listening if we are a subform
2671 ::osl::MutexGuard
aGuard(m_aMutex
);
2672 Reference
<XRowSet
> xParentRowSet(m_xParent
, UNO_QUERY
);
2673 if (xParentRowSet
.is())
2674 xParentRowSet
->removeRowSetListener(this);
2676 if (m_pLoadTimer
&& m_pLoadTimer
->IsActive())
2677 m_pLoadTimer
->Stop();
2680 //------------------------------------------------------------------------------
2681 void SAL_CALL
ODatabaseForm::reloaded(const EventObject
& /*aEvent*/) throw( RuntimeException
)
2683 reload_impl(sal_True
);
2685 ::osl::MutexGuard
aGuard(m_aMutex
);
2686 Reference
<XRowSet
> xParentRowSet(m_xParent
, UNO_QUERY
);
2687 if (xParentRowSet
.is())
2688 xParentRowSet
->addRowSetListener(this);
2692 //------------------------------------------------------------------------------
2693 IMPL_LINK( ODatabaseForm
, OnTimeout
, void*, EMPTYARG
)
2695 reload_impl(sal_True
);
2699 //==============================================================================
2700 // com::sun::star::form::XLoadable
2701 //------------------------------------------------------------------------------
2702 void SAL_CALL
ODatabaseForm::load() throw( RuntimeException
)
2704 load_impl(sal_False
);
2707 //------------------------------------------------------------------------------
2708 sal_Bool
ODatabaseForm::canShareConnection( const Reference
< XPropertySet
>& _rxParentProps
)
2710 // our own data source
2711 ::rtl::OUString sOwnDatasource
;
2712 m_xAggregateSet
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sOwnDatasource
;
2714 // our parents data source
2715 ::rtl::OUString sParentDataSource
;
2716 OSL_ENSURE( _rxParentProps
.is() && _rxParentProps
->getPropertySetInfo().is() && _rxParentProps
->getPropertySetInfo()->hasPropertyByName( PROPERTY_DATASOURCE
),
2717 "ODatabaseForm::doShareConnection: invalid parent form!" );
2718 if ( _rxParentProps
.is() )
2719 _rxParentProps
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sParentDataSource
;
2721 sal_Bool bCanShareConnection
= sal_False
;
2723 // both rowsets share are connected to the same data source
2724 if ( sParentDataSource
== sOwnDatasource
)
2726 if ( 0 != sParentDataSource
.getLength() )
2727 // and it's really a data source name (not empty)
2728 bCanShareConnection
= sal_True
;
2730 { // the data source name is empty
2731 // -> ook for the URL
2732 ::rtl::OUString sParentURL
;
2733 ::rtl::OUString sMyURL
;
2734 _rxParentProps
->getPropertyValue( PROPERTY_URL
) >>= sParentURL
;
2735 m_xAggregateSet
->getPropertyValue( PROPERTY_URL
) >>= sMyURL
;
2737 bCanShareConnection
= (sParentURL
== sMyURL
);
2741 if ( bCanShareConnection
)
2743 // check for the user/password
2745 // take the user property on the rowset (if any) into account
2746 ::rtl::OUString sParentUser
, sParentPwd
;
2747 _rxParentProps
->getPropertyValue( PROPERTY_USER
) >>= sParentUser
;
2748 _rxParentProps
->getPropertyValue( PROPERTY_PASSWORD
) >>= sParentPwd
;
2750 ::rtl::OUString sMyUser
, sMyPwd
;
2751 m_xAggregateSet
->getPropertyValue( PROPERTY_USER
) >>= sMyUser
;
2752 m_xAggregateSet
->getPropertyValue( PROPERTY_PASSWORD
) >>= sMyPwd
;
2754 bCanShareConnection
=
2755 ( sParentUser
== sMyUser
)
2756 && ( sParentPwd
== sMyPwd
);
2759 return bCanShareConnection
;
2762 //------------------------------------------------------------------------------
2763 void ODatabaseForm::doShareConnection( const Reference
< XPropertySet
>& _rxParentProps
)
2765 // get the conneciton of the parent
2766 Reference
< XConnection
> xParentConn
;
2767 _rxParentProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xParentConn
;
2768 OSL_ENSURE( xParentConn
.is(), "ODatabaseForm::doShareConnection: we're a valid sub-form, but the parent has no connection?!" );
2770 if ( xParentConn
.is() )
2772 // add as dispose listener to the connection
2773 Reference
< XComponent
> xParentConnComp( xParentConn
, UNO_QUERY
);
2774 OSL_ENSURE( xParentConnComp
.is(), "ODatabaseForm::doShareConnection: invalid connection!" );
2775 xParentConnComp
->addEventListener( static_cast< XLoadListener
* >( this ) );
2777 // forward the connection to our own aggreagte
2778 m_bForwardingConnection
= sal_True
;
2779 m_xAggregateSet
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( xParentConn
) );
2780 m_bForwardingConnection
= sal_False
;
2782 m_bSharingConnection
= sal_True
;
2785 m_bSharingConnection
= sal_False
;
2788 //------------------------------------------------------------------------------
2789 void ODatabaseForm::disposingSharedConnection( const Reference
< XConnection
>& /*_rxConn*/ )
2791 stopSharingConnection();
2793 // TODO: we could think about whether or not to re-connect.
2797 //------------------------------------------------------------------------------
2798 void ODatabaseForm::stopSharingConnection( )
2800 OSL_ENSURE( m_bSharingConnection
, "ODatabaseForm::stopSharingConnection: invalid call!" );
2802 if ( m_bSharingConnection
)
2804 // get the connection
2805 Reference
< XConnection
> xSharedConn
;
2806 m_xAggregateSet
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xSharedConn
;
2807 OSL_ENSURE( xSharedConn
.is(), "ODatabaseForm::stopSharingConnection: there's no conn!" );
2809 // remove ourself as event listener
2810 Reference
< XComponent
> xSharedConnComp( xSharedConn
, UNO_QUERY
);
2811 if ( xSharedConnComp
.is() )
2812 xSharedConnComp
->removeEventListener( static_cast< XLoadListener
* >( this ) );
2814 // no need to dispose the conn: we're not the owner, this is our parent
2815 // (in addition, this method may be called if the connection is beeing disposed while we use it)
2817 // reset the property
2818 xSharedConn
.clear();
2819 m_bForwardingConnection
= sal_True
;
2820 m_xAggregateSet
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( xSharedConn
) );
2821 m_bForwardingConnection
= sal_False
;
2824 m_bSharingConnection
= sal_False
;
2828 //------------------------------------------------------------------------------
2829 sal_Bool
ODatabaseForm::implEnsureConnection()
2833 if ( getConnection( ).is() )
2834 // if our aggregate already has a connection, nothing needs to be done about it
2837 // see whether we're an embedded form
2838 Reference
< XConnection
> xOuterConnection
;
2839 if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection
) )
2841 m_xAggregateSet
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( xOuterConnection
) );
2842 return xOuterConnection
.is();
2845 m_bSharingConnection
= sal_False
;
2847 // if we're a sub form, we try to re-use the connection of our parent
2850 OSL_ENSURE( Reference
< XForm
>( getParent(), UNO_QUERY
).is(),
2851 "ODatabaseForm::implEnsureConnection: m_bSubForm is TRUE, but the parent is no form?" );
2853 Reference
< XPropertySet
> xParentProps( getParent(), UNO_QUERY
);
2855 // can we re-use (aka share) the connection of the parent?
2856 if ( canShareConnection( xParentProps
) )
2859 doShareConnection( xParentProps
);
2861 if ( m_bSharingConnection
)
2862 // yes -> outta here
2867 if (m_xAggregateSet
.is())
2869 Reference
< XConnection
> xConnection
= connectRowset(
2870 Reference
<XRowSet
> (m_xAggregate
, UNO_QUERY
),
2872 sal_True
// set a calculated connection as ActiveConnection
2874 return xConnection
.is();
2877 catch(SQLException
& eDB
)
2879 onError(eDB
, FRM_RES_STRING(RID_STR_CONNECTERROR
));
2883 DBG_ERROR( "ODatabaseForm::implEnsureConnection: caught an exception which I cannot handle!" );
2889 //------------------------------------------------------------------------------
2890 void ODatabaseForm::load_impl(sal_Bool bCausedByParentForm
, sal_Bool bMoveToFirst
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
) throw( RuntimeException
)
2892 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2894 // are we already loaded?
2898 m_bSubForm
= bCausedByParentForm
;
2900 // if we don't have a connection, we are not intended to be a database form or the aggregate was not able
2901 // to establish a connection
2902 sal_Bool bConnected
= implEnsureConnection();
2904 // we don't have to execute if we do not have a command to execute
2905 sal_Bool bExecute
= bConnected
&& m_xAggregateSet
.is() && getString(m_xAggregateSet
->getPropertyValue(PROPERTY_COMMAND
)).getLength();
2907 // a database form always uses caching
2908 // we use starting fetchsize with at least 10 rows
2910 m_xAggregateSet
->setPropertyValue(PROPERTY_FETCHSIZE
, makeAny((sal_Int32
)10));
2912 // if we're loaded as sub form we got a "rowSetChanged" from the parent rowset _before_ we got the "loaded"
2913 // so we don't need to execute the statement again, this was already done
2914 // (and there were no relevant changes between these two listener calls, the "load" of a form is quite an
2915 // atomar operation.)
2917 sal_Bool bSuccess
= sal_False
;
2920 m_sCurrentErrorContext
= FRM_RES_STRING(RID_ERR_LOADING_FORM
);
2921 bSuccess
= executeRowSet(aGuard
, bMoveToFirst
, _rxCompletionHandler
);
2926 m_bLoaded
= sal_True
;
2928 EventObject
aEvt(static_cast<XWeak
*>(this));
2929 m_aLoadListeners
.notifyEach( &XLoadListener::loaded
, aEvt
);
2931 // if we are on the insert row, we have to reset all controls
2932 // to set the default values
2933 if (bExecute
&& getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ISNEW
)))
2938 //------------------------------------------------------------------------------
2939 void SAL_CALL
ODatabaseForm::unload() throw( RuntimeException
)
2941 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2945 DELETEZ(m_pLoadTimer
);
2948 EventObject
aEvt(static_cast<XWeak
*>(this));
2949 m_aLoadListeners
.notifyEach( &XLoadListener::unloading
, aEvt
);
2951 if (m_xAggregateAsRowSet
.is())
2953 // we may have reset the InsertOnly property on the aggregate - restore it
2954 restoreInsertOnlyState( );
2956 // clear the parameters if there are any
2957 invlidateParameters();
2961 // close the aggregate
2962 Reference
<XCloseable
> xCloseable
;
2963 query_aggregation( m_xAggregate
, xCloseable
);
2965 if (xCloseable
.is())
2966 xCloseable
->close();
2968 catch( const SQLException
& e
)
2975 m_bLoaded
= sal_False
;
2977 // if the connection we used while we were loaded is only shared with our parent, we
2979 if ( isSharingConnection() )
2980 stopSharingConnection();
2983 m_aLoadListeners
.notifyEach( &XLoadListener::unloaded
, aEvt
);
2986 //------------------------------------------------------------------------------
2987 void SAL_CALL
ODatabaseForm::reload() throw( RuntimeException
)
2989 reload_impl(sal_True
);
2992 //------------------------------------------------------------------------------
2993 void ODatabaseForm::reload_impl(sal_Bool bMoveToFirst
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
) throw( RuntimeException
)
2995 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2999 DocumentModifyGuard
aModifyGuard( *this );
3000 // ensures the document is not marked as "modified" just because we change some control's content during
3003 EventObject
aEvent(static_cast<XWeak
*>(this));
3005 // only if there is no approve listener we can post the event at this time
3006 // otherwise see approveRowsetChange
3007 // the aprrovement is done by the aggregate
3008 if (!m_aRowSetApproveListeners
.getLength())
3010 ::cppu::OInterfaceIteratorHelper
aIter(m_aLoadListeners
);
3013 while (aIter
.hasMoreElements())
3014 ((XLoadListener
*)aIter
.next())->reloading(aEvent
);
3020 sal_Bool bSuccess
= sal_True
;
3023 m_sCurrentErrorContext
= FRM_RES_STRING(RID_ERR_REFRESHING_FORM
);
3024 bSuccess
= executeRowSet(aGuard
, bMoveToFirst
, _rxCompletionHandler
);
3026 catch( const SQLException
& e
)
3028 DBG_ERROR("ODatabaseForm::reload_impl : shouldn't executeRowSet catch this exception?");
3034 ::cppu::OInterfaceIteratorHelper
aIter(m_aLoadListeners
);
3036 while (aIter
.hasMoreElements())
3037 ((XLoadListener
*)aIter
.next())->reloaded(aEvent
);
3039 // if we are on the insert row, we have to reset all controls
3040 // to set the default values
3041 if (getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ISNEW
)))
3045 m_bLoaded
= sal_False
;
3048 //------------------------------------------------------------------------------
3049 sal_Bool SAL_CALL
ODatabaseForm::isLoaded() throw( RuntimeException
)
3054 //------------------------------------------------------------------------------
3055 void SAL_CALL
ODatabaseForm::addLoadListener(const Reference
<XLoadListener
>& aListener
) throw( RuntimeException
)
3057 m_aLoadListeners
.addInterface(aListener
);
3060 //------------------------------------------------------------------------------
3061 void SAL_CALL
ODatabaseForm::removeLoadListener(const Reference
<XLoadListener
>& aListener
) throw( RuntimeException
)
3063 m_aLoadListeners
.removeInterface(aListener
);
3066 //==============================================================================
3067 // com::sun::star::sdbc::XCloseable
3068 //==============================================================================
3069 void SAL_CALL
ODatabaseForm::close() throw( SQLException
, RuntimeException
)
3071 // unload will close the aggregate
3075 //==============================================================================
3076 // com::sun::star::sdbc::XRowSetListener
3077 //------------------------------------------------------------------------------
3078 void SAL_CALL
ODatabaseForm::cursorMoved(const EventObject
& /*event*/) throw( RuntimeException
)
3080 // reload the subform with the new parameters of the parent
3081 // do this handling delayed to provide of execute too many SQL Statements
3082 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3084 DBG_ASSERT( m_pLoadTimer
, "ODatabaseForm::cursorMoved: how can this happen?!" );
3085 if ( !m_pLoadTimer
)
3086 impl_createLoadTimer();
3088 if ( m_pLoadTimer
->IsActive() )
3089 m_pLoadTimer
->Stop();
3091 // and start the timer again
3092 m_pLoadTimer
->Start();
3095 //------------------------------------------------------------------------------
3096 void SAL_CALL
ODatabaseForm::rowChanged(const EventObject
& /*event*/) throw( RuntimeException
)
3101 //------------------------------------------------------------------------------
3102 void SAL_CALL
ODatabaseForm::rowSetChanged(const EventObject
& /*event*/) throw( RuntimeException
)
3104 // not interested in :
3105 // if our parent is an ODatabaseForm, too, then after this rowSetChanged we'll get a "reloaded"
3106 // or a "loaded" event.
3107 // If somebody gave us another parent which is an XRowSet but doesn't handle an execute as
3108 // "load" respectivly "reload" ... can't do anything ....
3111 //------------------------------------------------------------------------------
3112 bool ODatabaseForm::impl_approveRowChange_throw( const EventObject
& _rEvent
, const bool _bAllowSQLException
,
3113 ::osl::ClearableMutexGuard
& _rGuard
)
3115 ::cppu::OInterfaceIteratorHelper
aIter( m_aRowSetApproveListeners
);
3117 while ( aIter
.hasMoreElements() )
3119 Reference
< XRowSetApproveListener
> xListener( static_cast< XRowSetApproveListener
* >( aIter
.next() ) );
3120 if ( !xListener
.is() )
3125 if ( !xListener
->approveRowSetChange( _rEvent
) )
3128 catch ( const DisposedException
& e
)
3130 if ( e
.Context
== xListener
)
3133 catch ( const RuntimeException
& ) { throw; }
3134 catch ( const SQLException
& )
3136 if ( _bAllowSQLException
)
3138 DBG_UNHANDLED_EXCEPTION();
3140 catch ( const Exception
& )
3142 DBG_UNHANDLED_EXCEPTION();
3148 //------------------------------------------------------------------------------
3149 sal_Bool SAL_CALL
ODatabaseForm::approveCursorMove(const EventObject
& event
) throw( RuntimeException
)
3151 // is our aggregate calling?
3152 if (event
.Source
== InterfaceRef(static_cast<XWeak
*>(this)))
3154 // Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
3155 // for XRowSetApproveBroadcaster-interface.
3156 // So we have to multiplex this approve request.
3157 ::cppu::OInterfaceIteratorHelper
aIter( m_aRowSetApproveListeners
);
3158 while ( aIter
.hasMoreElements() )
3160 Reference
< XRowSetApproveListener
> xListener( static_cast< XRowSetApproveListener
* >( aIter
.next() ) );
3161 if ( !xListener
.is() )
3166 if ( !xListener
->approveCursorMove( event
) )
3169 catch ( const DisposedException
& e
)
3171 if ( e
.Context
== xListener
)
3174 catch ( const RuntimeException
& ) { throw; }
3175 catch ( const Exception
& )
3177 DBG_UNHANDLED_EXCEPTION();
3184 // this is a call from our parent ...
3185 // a parent's cursor move will result in a re-execute of our own row-set, so we have to
3186 // ask our own RowSetChangesListeners, too
3187 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3188 if ( !impl_approveRowChange_throw( event
, false, aGuard
) )
3194 //------------------------------------------------------------------------------
3195 sal_Bool SAL_CALL
ODatabaseForm::approveRowChange(const RowChangeEvent
& event
) throw( RuntimeException
)
3197 // is our aggregate calling?
3198 if (event
.Source
== InterfaceRef(static_cast<XWeak
*>(this)))
3200 // Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
3201 // for XRowSetApproveBroadcaster-interface.
3202 // So we have to multiplex this approve request.
3203 ::cppu::OInterfaceIteratorHelper
aIter( m_aRowSetApproveListeners
);
3204 while ( aIter
.hasMoreElements() )
3206 Reference
< XRowSetApproveListener
> xListener( static_cast< XRowSetApproveListener
* >( aIter
.next() ) );
3207 if ( !xListener
.is() )
3212 if ( !xListener
->approveRowChange( event
) )
3215 catch ( const DisposedException
& e
)
3217 if ( e
.Context
== xListener
)
3220 catch ( const RuntimeException
& ) { throw; }
3221 catch ( const Exception
& )
3223 DBG_UNHANDLED_EXCEPTION();
3231 //------------------------------------------------------------------------------
3232 sal_Bool SAL_CALL
ODatabaseForm::approveRowSetChange(const EventObject
& event
) throw( RuntimeException
)
3234 if (event
.Source
== InterfaceRef(static_cast<XWeak
*>(this))) // ignore our aggregate as we handle this approve ourself
3236 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3237 bool bWasLoaded
= isLoaded();
3238 if ( !impl_approveRowChange_throw( event
, false, aGuard
) )
3243 m_aLoadListeners
.notifyEach( &XLoadListener::reloading
, event
);
3248 // this is a call from our parent ...
3249 // a parent's cursor move will result in a re-execute of our own row-set, so we have to
3250 // ask our own RowSetChangesListeners, too
3251 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3252 if ( !impl_approveRowChange_throw( event
, false, aGuard
) )
3258 //==============================================================================
3259 // com::sun::star::sdb::XRowSetApproveBroadcaster
3260 //------------------------------------------------------------------------------
3261 void SAL_CALL
ODatabaseForm::addRowSetApproveListener(const Reference
<XRowSetApproveListener
>& _rListener
) throw( RuntimeException
)
3263 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3264 m_aRowSetApproveListeners
.addInterface(_rListener
);
3266 // do we have to multiplex ?
3267 if (m_aRowSetApproveListeners
.getLength() == 1)
3269 Reference
<XRowSetApproveBroadcaster
> xBroadcaster
;
3270 if (query_aggregation( m_xAggregate
, xBroadcaster
))
3272 Reference
<XRowSetApproveListener
> xListener((XRowSetApproveListener
*)this);
3273 xBroadcaster
->addRowSetApproveListener(xListener
);
3278 //------------------------------------------------------------------------------
3279 void SAL_CALL
ODatabaseForm::removeRowSetApproveListener(const Reference
<XRowSetApproveListener
>& _rListener
) throw( RuntimeException
)
3281 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3282 // do we have to remove the multiplex ?
3283 m_aRowSetApproveListeners
.removeInterface(_rListener
);
3284 if ( m_aRowSetApproveListeners
.getLength() == 0 )
3286 Reference
<XRowSetApproveBroadcaster
> xBroadcaster
;
3287 if (query_aggregation( m_xAggregate
, xBroadcaster
))
3289 Reference
<XRowSetApproveListener
> xListener((XRowSetApproveListener
*)this);
3290 xBroadcaster
->removeRowSetApproveListener(xListener
);
3295 //==============================================================================
3296 // com::sun:star::form::XDatabaseParameterBroadcaster
3297 //------------------------------------------------------------------------------
3298 void SAL_CALL
ODatabaseForm::addDatabaseParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
)
3300 m_aParameterManager
.addParameterListener( _rListener
);
3302 //------------------------------------------------------------------------------
3303 void SAL_CALL
ODatabaseForm::removeDatabaseParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
)
3305 m_aParameterManager
.removeParameterListener( _rListener
);
3308 //------------------------------------------------------------------------------
3309 void SAL_CALL
ODatabaseForm::addParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
)
3311 ODatabaseForm::addDatabaseParameterListener( _rListener
);
3314 //------------------------------------------------------------------------------
3315 void SAL_CALL
ODatabaseForm::removeParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
)
3317 ODatabaseForm::removeDatabaseParameterListener( _rListener
);
3320 //==============================================================================
3321 // com::sun::star::sdb::XCompletedExecution
3322 //------------------------------------------------------------------------------
3323 void SAL_CALL
ODatabaseForm::executeWithCompletion( const Reference
< XInteractionHandler
>& _rxHandler
) throw(SQLException
, RuntimeException
)
3325 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
3326 // the difference between execute and load is, that we position on the first row in case of load
3327 // after execute we remain before the first row
3331 load_impl(sal_False
, sal_False
, _rxHandler
);
3335 EventObject
event(static_cast< XWeak
* >(this));
3336 if ( !impl_approveRowChange_throw( event
, true, aGuard
) )
3339 // we're loaded and somebody want's to execute ourself -> this means a reload
3340 reload_impl(sal_False
, _rxHandler
);
3344 //==============================================================================
3345 // com::sun::star::sdbc::XRowSet
3346 //------------------------------------------------------------------------------
3347 void SAL_CALL
ODatabaseForm::execute() throw( SQLException
, RuntimeException
)
3349 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3350 // if somebody calls an execute and we're not loaded we reroute this call to our load method.
3352 // the difference between execute and load is, that we position on the first row in case of load
3353 // after execute we remain before the first row
3357 load_impl(sal_False
, sal_False
);
3361 EventObject
event(static_cast< XWeak
* >(this));
3362 if ( !impl_approveRowChange_throw( event
, true, aGuard
) )
3365 // we're loaded and somebody want's to execute ourself -> this means a reload
3366 reload_impl(sal_False
);
3370 //------------------------------------------------------------------------------
3371 void SAL_CALL
ODatabaseForm::addRowSetListener(const Reference
<XRowSetListener
>& _rListener
) throw( RuntimeException
)
3373 if (m_xAggregateAsRowSet
.is())
3374 m_xAggregateAsRowSet
->addRowSetListener(_rListener
);
3377 //------------------------------------------------------------------------------
3378 void SAL_CALL
ODatabaseForm::removeRowSetListener(const Reference
<XRowSetListener
>& _rListener
) throw( RuntimeException
)
3380 if (m_xAggregateAsRowSet
.is())
3381 m_xAggregateAsRowSet
->removeRowSetListener(_rListener
);
3384 //==============================================================================
3385 // com::sun::star::sdbc::XResultSet
3386 //------------------------------------------------------------------------------
3387 sal_Bool SAL_CALL
ODatabaseForm::next() throw( SQLException
, RuntimeException
)
3389 return m_xAggregateAsRowSet
->next();
3392 //------------------------------------------------------------------------------
3393 sal_Bool SAL_CALL
ODatabaseForm::isBeforeFirst() throw( SQLException
, RuntimeException
)
3395 return m_xAggregateAsRowSet
->isBeforeFirst();
3398 //------------------------------------------------------------------------------
3399 sal_Bool SAL_CALL
ODatabaseForm::isAfterLast() throw( SQLException
, RuntimeException
)
3401 return m_xAggregateAsRowSet
->isAfterLast();
3404 //------------------------------------------------------------------------------
3405 sal_Bool SAL_CALL
ODatabaseForm::isFirst() throw( SQLException
, RuntimeException
)
3407 return m_xAggregateAsRowSet
->isFirst();
3410 //------------------------------------------------------------------------------
3411 sal_Bool SAL_CALL
ODatabaseForm::isLast() throw( SQLException
, RuntimeException
)
3413 return m_xAggregateAsRowSet
->isLast();
3416 //------------------------------------------------------------------------------
3417 void SAL_CALL
ODatabaseForm::beforeFirst() throw( SQLException
, RuntimeException
)
3419 m_xAggregateAsRowSet
->beforeFirst();
3422 //------------------------------------------------------------------------------
3423 void SAL_CALL
ODatabaseForm::afterLast() throw( SQLException
, RuntimeException
)
3425 m_xAggregateAsRowSet
->afterLast();
3428 //------------------------------------------------------------------------------
3429 sal_Bool SAL_CALL
ODatabaseForm::first() throw( SQLException
, RuntimeException
)
3431 return m_xAggregateAsRowSet
->first();
3434 //------------------------------------------------------------------------------
3435 sal_Bool SAL_CALL
ODatabaseForm::last() throw( SQLException
, RuntimeException
)
3437 return m_xAggregateAsRowSet
->last();
3440 //------------------------------------------------------------------------------
3441 sal_Int32 SAL_CALL
ODatabaseForm::getRow() throw( SQLException
, RuntimeException
)
3443 return m_xAggregateAsRowSet
->getRow();
3446 //------------------------------------------------------------------------------
3447 sal_Bool SAL_CALL
ODatabaseForm::absolute(sal_Int32 row
) throw( SQLException
, RuntimeException
)
3449 return m_xAggregateAsRowSet
->absolute(row
);
3452 //------------------------------------------------------------------------------
3453 sal_Bool SAL_CALL
ODatabaseForm::relative(sal_Int32 rows
) throw( SQLException
, RuntimeException
)
3455 return m_xAggregateAsRowSet
->relative(rows
);
3458 //------------------------------------------------------------------------------
3459 sal_Bool SAL_CALL
ODatabaseForm::previous() throw( SQLException
, RuntimeException
)
3461 return m_xAggregateAsRowSet
->previous();
3464 //------------------------------------------------------------------------------
3465 void SAL_CALL
ODatabaseForm::refreshRow() throw( SQLException
, RuntimeException
)
3467 m_xAggregateAsRowSet
->refreshRow();
3470 //------------------------------------------------------------------------------
3471 sal_Bool SAL_CALL
ODatabaseForm::rowUpdated() throw( SQLException
, RuntimeException
)
3473 return m_xAggregateAsRowSet
->rowUpdated();
3476 //------------------------------------------------------------------------------
3477 sal_Bool SAL_CALL
ODatabaseForm::rowInserted() throw( SQLException
, RuntimeException
)
3479 return m_xAggregateAsRowSet
->rowInserted();
3482 //------------------------------------------------------------------------------
3483 sal_Bool SAL_CALL
ODatabaseForm::rowDeleted() throw( SQLException
, RuntimeException
)
3485 return m_xAggregateAsRowSet
->rowDeleted();
3488 //------------------------------------------------------------------------------
3489 InterfaceRef SAL_CALL
ODatabaseForm::getStatement() throw( SQLException
, RuntimeException
)
3491 return m_xAggregateAsRowSet
->getStatement();
3494 // com::sun::star::sdbc::XResultSetUpdate
3495 // exceptions during insert update and delete will be forwarded to the errorlistener
3496 //------------------------------------------------------------------------------
3497 void SAL_CALL
ODatabaseForm::insertRow() throw( SQLException
, RuntimeException
)
3501 Reference
<XResultSetUpdate
> xUpdate
;
3502 if (query_aggregation( m_xAggregate
, xUpdate
))
3503 xUpdate
->insertRow();
3505 catch( const RowSetVetoException
& eVeto
)
3510 catch(SQLException
& eDb
)
3512 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD
));
3517 //------------------------------------------------------------------------------
3518 void SAL_CALL
ODatabaseForm::updateRow() throw( SQLException
, RuntimeException
)
3522 Reference
<XResultSetUpdate
> xUpdate
;
3523 if (query_aggregation( m_xAggregate
, xUpdate
))
3524 xUpdate
->updateRow();
3526 catch( const RowSetVetoException
& eVeto
)
3531 catch(SQLException
& eDb
)
3533 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_UPDATERECORD
));
3538 //------------------------------------------------------------------------------
3539 void SAL_CALL
ODatabaseForm::deleteRow() throw( SQLException
, RuntimeException
)
3543 Reference
<XResultSetUpdate
> xUpdate
;
3544 if (query_aggregation( m_xAggregate
, xUpdate
))
3545 xUpdate
->deleteRow();
3547 catch( const RowSetVetoException
& eVeto
)
3552 catch(SQLException
& eDb
)
3554 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_DELETERECORD
));
3559 //------------------------------------------------------------------------------
3560 void SAL_CALL
ODatabaseForm::cancelRowUpdates() throw( SQLException
, RuntimeException
)
3564 Reference
<XResultSetUpdate
> xUpdate
;
3565 if (query_aggregation( m_xAggregate
, xUpdate
))
3566 xUpdate
->cancelRowUpdates();
3568 catch( const RowSetVetoException
& eVeto
)
3573 catch(SQLException
& eDb
)
3575 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD
));
3580 //------------------------------------------------------------------------------
3581 void SAL_CALL
ODatabaseForm::moveToInsertRow() throw( SQLException
, RuntimeException
)
3583 Reference
<XResultSetUpdate
> xUpdate
;
3584 if (query_aggregation( m_xAggregate
, xUpdate
))
3586 // _always_ move to the insert row
3588 // Formerly, the following line was conditioned with a "not is new", means we did not move the aggregate
3589 // to the insert row if it was already positioned there.
3591 // This prevented the RowSet implementation from resetting it's column values. We, ourself, formerly
3592 // did this reset of columns in reset_impl, where we set every column to the ControlDefault, or, if this
3593 // was not present, to NULL. However, the problem with setting to NULL was #88888#, the problem with
3594 // _not_ setting to NULL (which was the original fix for #88888#) was #97955#.
3597 // * move our aggregate to the insert row
3599 // - set the control defaults into the columns if not void
3600 // - do _not_ set the columns to NULL if no control default is set
3601 // This fixes both #88888# and #97955#
3603 // Still, there is #72756#. During fixing this bug, DG introduced not calling the aggregate here. So
3604 // in theory, we re-introduced #72756#. But the bug described therein does not happen anymore, as the
3605 // preliminaries for it changed (no display of guessed values for new records with autoinc fields)
3607 // BTW: the public Issuezilla bug for #97955# is #i2815#
3609 // 16.04.2002 - 97955 - fs@openoffice.org
3610 xUpdate
->moveToInsertRow();
3612 // then set the default values and the parameters given from the parent
3617 //------------------------------------------------------------------------------
3618 void SAL_CALL
ODatabaseForm::moveToCurrentRow() throw( SQLException
, RuntimeException
)
3620 Reference
<XResultSetUpdate
> xUpdate
;
3621 if (query_aggregation( m_xAggregate
, xUpdate
))
3622 xUpdate
->moveToCurrentRow();
3625 // com::sun::star::sdbcx::XDeleteRows
3626 //------------------------------------------------------------------------------
3627 Sequence
<sal_Int32
> SAL_CALL
ODatabaseForm::deleteRows(const Sequence
<Any
>& rows
) throw( SQLException
, RuntimeException
)
3631 Reference
<XDeleteRows
> xDelete
;
3632 if (query_aggregation( m_xAggregate
, xDelete
))
3633 return xDelete
->deleteRows(rows
);
3635 catch( const RowSetVetoException
& eVeto
)
3637 (void)eVeto
; // make compiler happy
3640 catch(SQLException
& eDb
)
3642 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_DELETERECORDS
));
3646 return Sequence
< sal_Int32
>();
3649 // com::sun::star::sdbc::XParameters
3650 //------------------------------------------------------------------------------
3651 void SAL_CALL
ODatabaseForm::setNull(sal_Int32 parameterIndex
, sal_Int32 sqlType
) throw( SQLException
, RuntimeException
)
3653 m_aParameterManager
.setNull(parameterIndex
, sqlType
);
3656 //------------------------------------------------------------------------------
3657 void SAL_CALL
ODatabaseForm::setObjectNull(sal_Int32 parameterIndex
, sal_Int32 sqlType
, const ::rtl::OUString
& typeName
) throw( SQLException
, RuntimeException
)
3659 m_aParameterManager
.setObjectNull(parameterIndex
, sqlType
, typeName
);
3662 //------------------------------------------------------------------------------
3663 void SAL_CALL
ODatabaseForm::setBoolean(sal_Int32 parameterIndex
, sal_Bool x
) throw( SQLException
, RuntimeException
)
3665 m_aParameterManager
.setBoolean(parameterIndex
, x
);
3668 //------------------------------------------------------------------------------
3669 void SAL_CALL
ODatabaseForm::setByte(sal_Int32 parameterIndex
, sal_Int8 x
) throw( SQLException
, RuntimeException
)
3671 m_aParameterManager
.setByte(parameterIndex
, x
);
3674 //------------------------------------------------------------------------------
3675 void SAL_CALL
ODatabaseForm::setShort(sal_Int32 parameterIndex
, sal_Int16 x
) throw( SQLException
, RuntimeException
)
3677 m_aParameterManager
.setShort(parameterIndex
, x
);
3680 //------------------------------------------------------------------------------
3681 void SAL_CALL
ODatabaseForm::setInt(sal_Int32 parameterIndex
, sal_Int32 x
) throw( SQLException
, RuntimeException
)
3683 m_aParameterManager
.setInt(parameterIndex
, x
);
3686 //------------------------------------------------------------------------------
3687 void SAL_CALL
ODatabaseForm::setLong(sal_Int32 parameterIndex
, sal_Int64 x
) throw( SQLException
, RuntimeException
)
3689 m_aParameterManager
.setLong(parameterIndex
, x
);
3692 //------------------------------------------------------------------------------
3693 void SAL_CALL
ODatabaseForm::setFloat(sal_Int32 parameterIndex
, float x
) throw( SQLException
, RuntimeException
)
3695 m_aParameterManager
.setFloat(parameterIndex
, x
);
3698 //------------------------------------------------------------------------------
3699 void SAL_CALL
ODatabaseForm::setDouble(sal_Int32 parameterIndex
, double x
) throw( SQLException
, RuntimeException
)
3701 m_aParameterManager
.setDouble(parameterIndex
, x
);
3704 //------------------------------------------------------------------------------
3705 void SAL_CALL
ODatabaseForm::setString(sal_Int32 parameterIndex
, const ::rtl::OUString
& x
) throw( SQLException
, RuntimeException
)
3707 m_aParameterManager
.setString(parameterIndex
, x
);
3710 //------------------------------------------------------------------------------
3711 void SAL_CALL
ODatabaseForm::setBytes(sal_Int32 parameterIndex
, const Sequence
< sal_Int8
>& x
) throw( SQLException
, RuntimeException
)
3713 m_aParameterManager
.setBytes(parameterIndex
, x
);
3716 //------------------------------------------------------------------------------
3717 void SAL_CALL
ODatabaseForm::setDate(sal_Int32 parameterIndex
, const ::com::sun::star::util::Date
& x
) throw( SQLException
, RuntimeException
)
3719 m_aParameterManager
.setDate(parameterIndex
, x
);
3722 //------------------------------------------------------------------------------
3723 void SAL_CALL
ODatabaseForm::setTime(sal_Int32 parameterIndex
, const ::com::sun::star::util::Time
& x
) throw( SQLException
, RuntimeException
)
3725 m_aParameterManager
.setTime(parameterIndex
, x
);
3728 //------------------------------------------------------------------------------
3729 void SAL_CALL
ODatabaseForm::setTimestamp(sal_Int32 parameterIndex
, const ::com::sun::star::util::DateTime
& x
) throw( SQLException
, RuntimeException
)
3731 m_aParameterManager
.setTimestamp(parameterIndex
, x
);
3734 //------------------------------------------------------------------------------
3735 void SAL_CALL
ODatabaseForm::setBinaryStream(sal_Int32 parameterIndex
, const Reference
<XInputStream
>& x
, sal_Int32 length
) throw( SQLException
, RuntimeException
)
3737 m_aParameterManager
.setBinaryStream(parameterIndex
, x
, length
);
3740 //------------------------------------------------------------------------------
3741 void SAL_CALL
ODatabaseForm::setCharacterStream(sal_Int32 parameterIndex
, const Reference
<XInputStream
>& x
, sal_Int32 length
) throw( SQLException
, RuntimeException
)
3743 m_aParameterManager
.setCharacterStream(parameterIndex
, x
, length
);
3746 //------------------------------------------------------------------------------
3747 void SAL_CALL
ODatabaseForm::setObjectWithInfo(sal_Int32 parameterIndex
, const Any
& x
, sal_Int32 targetSqlType
, sal_Int32 scale
) throw( SQLException
, RuntimeException
)
3749 m_aParameterManager
.setObjectWithInfo(parameterIndex
, x
, targetSqlType
, scale
);
3752 //------------------------------------------------------------------------------
3753 void SAL_CALL
ODatabaseForm::setObject(sal_Int32 parameterIndex
, const Any
& x
) throw( SQLException
, RuntimeException
)
3755 m_aParameterManager
.setObject(parameterIndex
, x
);
3758 //------------------------------------------------------------------------------
3759 void SAL_CALL
ODatabaseForm::setRef(sal_Int32 parameterIndex
, const Reference
<XRef
>& x
) throw( SQLException
, RuntimeException
)
3761 m_aParameterManager
.setRef(parameterIndex
, x
);
3764 //------------------------------------------------------------------------------
3765 void SAL_CALL
ODatabaseForm::setBlob(sal_Int32 parameterIndex
, const Reference
<XBlob
>& x
) throw( SQLException
, RuntimeException
)
3767 m_aParameterManager
.setBlob(parameterIndex
, x
);
3770 //------------------------------------------------------------------------------
3771 void SAL_CALL
ODatabaseForm::setClob(sal_Int32 parameterIndex
, const Reference
<XClob
>& x
) throw( SQLException
, RuntimeException
)
3773 m_aParameterManager
.setClob(parameterIndex
, x
);
3776 //------------------------------------------------------------------------------
3777 void SAL_CALL
ODatabaseForm::setArray(sal_Int32 parameterIndex
, const Reference
<XArray
>& x
) throw( SQLException
, RuntimeException
)
3779 m_aParameterManager
.setArray(parameterIndex
, x
);
3782 //------------------------------------------------------------------------------
3783 void SAL_CALL
ODatabaseForm::clearParameters() throw( SQLException
, RuntimeException
)
3785 m_aParameterManager
.clearParameters();
3788 //------------------------------------------------------------------------------
3789 void SAL_CALL
ODatabaseForm::propertyChange( const PropertyChangeEvent
& evt
) throw (RuntimeException
)
3791 if ( evt
.Source
== m_xParent
)
3793 if ( evt
.PropertyName
== PROPERTY_ISNEW
)
3795 sal_Bool
bCurrentIsNew( sal_False
);
3796 OSL_VERIFY( evt
.NewValue
>>= bCurrentIsNew
);
3797 if ( !bCurrentIsNew
)
3798 reload_impl( sal_True
);
3802 OFormComponents::propertyChange( evt
);
3805 // com::sun::star::lang::XServiceInfo
3806 //------------------------------------------------------------------------------
3807 ::rtl::OUString SAL_CALL
ODatabaseForm::getImplementationName_Static()
3809 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.ODatabaseForm" ) );
3812 //------------------------------------------------------------------------------
3813 Sequence
< ::rtl::OUString
> SAL_CALL
ODatabaseForm::getCompatibleServiceNames_Static()
3815 Sequence
< ::rtl::OUString
> aServices( 1 );
3816 ::rtl::OUString
* pServices
= aServices
.getArray();
3818 *pServices
++ = FRM_COMPONENT_FORM
;
3823 //------------------------------------------------------------------------------
3824 Sequence
< ::rtl::OUString
> SAL_CALL
ODatabaseForm::getCurrentServiceNames_Static()
3826 Sequence
< ::rtl::OUString
> aServices( 5 );
3827 ::rtl::OUString
* pServices
= aServices
.getArray();
3829 *pServices
++ = FRM_SUN_FORMCOMPONENT
;
3830 *pServices
++ = ::rtl::OUString::createFromAscii("com.sun.star.form.FormComponents");
3831 *pServices
++ = FRM_SUN_COMPONENT_FORM
;
3832 *pServices
++ = FRM_SUN_COMPONENT_HTMLFORM
;
3833 *pServices
++ = FRM_SUN_COMPONENT_DATAFORM
;
3838 //------------------------------------------------------------------------------
3839 Sequence
< ::rtl::OUString
> SAL_CALL
ODatabaseForm::getSupportedServiceNames_Static()
3841 return ::comphelper::concatSequences(
3842 getCurrentServiceNames_Static(),
3843 getCompatibleServiceNames_Static()
3847 //------------------------------------------------------------------------------
3848 ::rtl::OUString SAL_CALL
ODatabaseForm::getImplementationName() throw( RuntimeException
)
3850 return getImplementationName_Static();
3853 //------------------------------------------------------------------------------
3854 Sequence
< ::rtl::OUString
> SAL_CALL
ODatabaseForm::getSupportedServiceNames() throw( RuntimeException
)
3856 // the services of our aggregate
3857 Sequence
< ::rtl::OUString
> aServices
;
3858 Reference
< XServiceInfo
> xInfo
;
3859 if (query_aggregation(m_xAggregate
, xInfo
))
3860 aServices
= xInfo
->getSupportedServiceNames();
3862 // concat with out own services
3863 return ::comphelper::concatSequences(
3864 getCurrentServiceNames_Static(),
3867 // use getCurrentXXX instead of getSupportedXXX, because at runtime, we do not want to have
3868 // the compatible names
3869 // This is maily to be consistent with the implementation before fixing #97083#, though the
3870 // better solution _may_ be to return the compatible names at runtime, too
3871 // 04.03.2002 - fs@openoffice.org
3874 //------------------------------------------------------------------------------
3875 sal_Bool SAL_CALL
ODatabaseForm::supportsService(const ::rtl::OUString
& ServiceName
) throw( RuntimeException
)
3877 Sequence
< ::rtl::OUString
> aSupported( getSupportedServiceNames() );
3878 const ::rtl::OUString
* pArray
= aSupported
.getConstArray();
3879 for( sal_Int32 i
= 0; i
< aSupported
.getLength(); ++i
, ++pArray
)
3880 if( pArray
->equals( ServiceName
) )
3885 //==============================================================================
3886 // com::sun::star::io::XPersistObject
3887 //------------------------------------------------------------------------------
3889 const sal_uInt16 CYCLE
= 0x0001;
3890 const sal_uInt16 DONTAPPLYFILTER
= 0x0002;
3892 //------------------------------------------------------------------------------
3893 ::rtl::OUString
ODatabaseForm::getServiceName() throw( RuntimeException
)
3895 return FRM_COMPONENT_FORM
; // old (non-sun) name for compatibility !
3898 //------------------------------------------------------------------------------
3899 void SAL_CALL
ODatabaseForm::write(const Reference
<XObjectOutputStream
>& _rxOutStream
) throw( IOException
, RuntimeException
)
3901 DBG_ASSERT(m_xAggregateSet
.is(), "ODatabaseForm::write : only to be called if the aggregate exists !");
3904 OFormComponents::write(_rxOutStream
);
3907 _rxOutStream
->writeShort(0x0003);
3910 _rxOutStream
<< m_sName
;
3912 ::rtl::OUString sDataSource
;
3913 if (m_xAggregateSet
.is())
3914 m_xAggregateSet
->getPropertyValue(PROPERTY_DATASOURCE
) >>= sDataSource
;
3915 _rxOutStream
<< sDataSource
;
3917 // former CursorSource
3918 ::rtl::OUString sCommand
;
3919 if (m_xAggregateSet
.is())
3920 m_xAggregateSet
->getPropertyValue(PROPERTY_COMMAND
) >>= sCommand
;
3921 _rxOutStream
<< sCommand
;
3923 // former MasterFields
3924 _rxOutStream
<< m_aMasterFields
;
3925 // former DetailFields
3926 _rxOutStream
<< m_aDetailFields
;
3928 // former DataSelectionType
3929 DataSelectionType eTranslated
= DataSelectionType_TABLE
;
3930 if (m_xAggregateSet
.is())
3932 sal_Int32 nCommandType
= 0;
3933 m_xAggregateSet
->getPropertyValue(PROPERTY_COMMANDTYPE
) >>= nCommandType
;
3934 switch (nCommandType
)
3936 case CommandType::TABLE
: eTranslated
= DataSelectionType_TABLE
; break;
3937 case CommandType::QUERY
: eTranslated
= DataSelectionType_QUERY
; break;
3938 case CommandType::COMMAND
:
3940 sal_Bool bEscapeProcessing
= getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ESCAPE_PROCESSING
));
3941 eTranslated
= bEscapeProcessing
? DataSelectionType_SQL
: DataSelectionType_SQLPASSTHROUGH
;
3944 default : DBG_ERROR("ODatabaseForm::write : wrong CommandType !");
3947 _rxOutStream
->writeShort((sal_Int16
)eTranslated
); // former DataSelectionType
3949 // very old versions expect a CursorType here
3950 _rxOutStream
->writeShort(DatabaseCursorType_KEYSET
);
3952 _rxOutStream
->writeBoolean(m_eNavigation
!= NavigationBarMode_NONE
);
3955 if (m_xAggregateSet
.is())
3956 _rxOutStream
->writeBoolean(getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_INSERTONLY
)));
3958 _rxOutStream
->writeBoolean(sal_False
);
3960 _rxOutStream
->writeBoolean(m_bAllowInsert
);
3961 _rxOutStream
->writeBoolean(m_bAllowUpdate
);
3962 _rxOutStream
->writeBoolean(m_bAllowDelete
);
3965 ::rtl::OUString sTmp
= INetURLObject::decode( m_aTargetURL
, '%', INetURLObject::DECODE_UNAMBIGUOUS
);
3966 _rxOutStream
<< sTmp
;
3967 _rxOutStream
->writeShort( (sal_Int16
)m_eSubmitMethod
);
3968 _rxOutStream
->writeShort( (sal_Int16
)m_eSubmitEncoding
);
3969 _rxOutStream
<< m_aTargetFrame
;
3971 // version 2 didn't know some options and the "default" state
3972 sal_Int32 nCycle
= TabulatorCycle_RECORDS
;
3973 if (m_aCycle
.hasValue())
3975 ::cppu::enum2int(nCycle
, m_aCycle
);
3976 if (m_aCycle
== TabulatorCycle_PAGE
)
3977 // unknown in earlier versions
3978 nCycle
= TabulatorCycle_RECORDS
;
3980 _rxOutStream
->writeShort((sal_Int16
) nCycle
);
3982 _rxOutStream
->writeShort((sal_Int16
)m_eNavigation
);
3984 ::rtl::OUString sFilter
;
3985 ::rtl::OUString sOrder
;
3986 if (m_xAggregateSet
.is())
3988 m_xAggregateSet
->getPropertyValue(PROPERTY_FILTER
) >>= sFilter
;
3989 m_xAggregateSet
->getPropertyValue(PROPERTY_SORT
) >>= sOrder
;
3991 _rxOutStream
<< sFilter
;
3992 _rxOutStream
<< sOrder
;
3996 sal_uInt16 nAnyMask
= 0;
3997 if (m_aCycle
.hasValue())
4000 if (m_xAggregateSet
.is() && !getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_APPLYFILTER
)))
4001 nAnyMask
|= DONTAPPLYFILTER
;
4003 _rxOutStream
->writeShort(nAnyMask
);
4005 if (nAnyMask
& CYCLE
)
4007 sal_Int32 nRealCycle
= 0;
4008 ::cppu::enum2int(nRealCycle
, m_aCycle
);
4009 _rxOutStream
->writeShort((sal_Int16
)nRealCycle
);
4013 //------------------------------------------------------------------------------
4014 void SAL_CALL
ODatabaseForm::read(const Reference
<XObjectInputStream
>& _rxInStream
) throw( IOException
, RuntimeException
)
4016 DBG_ASSERT(m_xAggregateSet
.is(), "ODatabaseForm::read : only to be called if the aggregate exists !");
4018 OFormComponents::read(_rxInStream
);
4021 sal_uInt16 nVersion
= _rxInStream
->readShort();
4023 _rxInStream
>> m_sName
;
4025 ::rtl::OUString sAggregateProp
;
4026 _rxInStream
>> sAggregateProp
;
4027 if (m_xAggregateSet
.is())
4028 m_xAggregateSet
->setPropertyValue(PROPERTY_DATASOURCE
, makeAny(sAggregateProp
));
4029 _rxInStream
>> sAggregateProp
;
4030 if (m_xAggregateSet
.is())
4031 m_xAggregateSet
->setPropertyValue(PROPERTY_COMMAND
, makeAny(sAggregateProp
));
4033 _rxInStream
>> m_aMasterFields
;
4034 _rxInStream
>> m_aDetailFields
;
4036 sal_Int16 nCursorSourceType
= _rxInStream
->readShort();
4037 sal_Int32 nCommandType
= 0;
4038 switch ((DataSelectionType
)nCursorSourceType
)
4040 case DataSelectionType_TABLE
: nCommandType
= CommandType::TABLE
; break;
4041 case DataSelectionType_QUERY
: nCommandType
= CommandType::QUERY
; break;
4042 case DataSelectionType_SQL
:
4043 case DataSelectionType_SQLPASSTHROUGH
:
4045 nCommandType
= CommandType::COMMAND
;
4046 sal_Bool bEscapeProcessing
= ((DataSelectionType
)nCursorSourceType
) != DataSelectionType_SQLPASSTHROUGH
;
4047 m_xAggregateSet
->setPropertyValue(PROPERTY_ESCAPE_PROCESSING
, makeAny((sal_Bool
)bEscapeProcessing
));
4050 default : DBG_ERROR("ODatabaseForm::read : wrong CommandType !");
4052 if (m_xAggregateSet
.is())
4053 m_xAggregateSet
->setPropertyValue(PROPERTY_COMMANDTYPE
, makeAny(nCommandType
));
4056 _rxInStream
->readShort();
4058 // navigation mode was a boolean in version 1
4059 // war in der version 1 ein sal_Bool
4060 sal_Bool bNavigation
= _rxInStream
->readBoolean();
4062 m_eNavigation
= bNavigation
? NavigationBarMode_CURRENT
: NavigationBarMode_NONE
;
4064 sal_Bool bInsertOnly
= _rxInStream
->readBoolean();
4065 if (m_xAggregateSet
.is())
4066 m_xAggregateSet
->setPropertyValue(PROPERTY_INSERTONLY
, makeAny(bInsertOnly
));
4068 m_bAllowInsert
= _rxInStream
->readBoolean();
4069 m_bAllowUpdate
= _rxInStream
->readBoolean();
4070 m_bAllowDelete
= _rxInStream
->readBoolean();
4073 ::rtl::OUString sTmp
;
4074 _rxInStream
>> sTmp
;
4075 m_aTargetURL
= INetURLObject::decode( sTmp
, '%', INetURLObject::DECODE_UNAMBIGUOUS
);
4076 m_eSubmitMethod
= (FormSubmitMethod
)_rxInStream
->readShort();
4077 m_eSubmitEncoding
= (FormSubmitEncoding
)_rxInStream
->readShort();
4078 _rxInStream
>> m_aTargetFrame
;
4082 sal_Int32 nCycle
= _rxInStream
->readShort();
4083 m_aCycle
= ::cppu::int2enum(nCycle
, ::getCppuType(static_cast<const TabulatorCycle
*>(NULL
)));
4084 m_eNavigation
= (NavigationBarMode
)_rxInStream
->readShort();
4086 _rxInStream
>> sAggregateProp
;
4087 setPropertyValue(PROPERTY_FILTER
, makeAny(sAggregateProp
));
4089 _rxInStream
>> sAggregateProp
;
4090 if (m_xAggregateSet
.is())
4091 m_xAggregateSet
->setPropertyValue(PROPERTY_SORT
, makeAny(sAggregateProp
));
4094 sal_uInt16 nAnyMask
= 0;
4097 nAnyMask
= _rxInStream
->readShort();
4098 if (nAnyMask
& CYCLE
)
4100 sal_Int32 nCycle
= _rxInStream
->readShort();
4101 m_aCycle
= ::cppu::int2enum(nCycle
, ::getCppuType(static_cast<const TabulatorCycle
*>(NULL
)));
4106 if (m_xAggregateSet
.is())
4107 m_xAggregateSet
->setPropertyValue(PROPERTY_APPLYFILTER
, makeAny((sal_Bool
)((nAnyMask
& DONTAPPLYFILTER
) == 0)));
4110 //------------------------------------------------------------------------------
4111 void ODatabaseForm::implInserted( const ElementDescription
* _pElement
)
4113 OFormComponents::implInserted( _pElement
);
4115 Reference
< XSQLErrorBroadcaster
> xBroadcaster( _pElement
->xInterface
, UNO_QUERY
);
4116 Reference
< XForm
> xForm ( _pElement
->xInterface
, UNO_QUERY
);
4118 if ( xBroadcaster
.is() && !xForm
.is() )
4119 { // the object is an error broadcaster, but no form itself -> add ourself as listener
4120 xBroadcaster
->addSQLErrorListener( this );
4124 //------------------------------------------------------------------------------
4125 void ODatabaseForm::implRemoved(const InterfaceRef
& _rxObject
)
4127 OFormComponents::implRemoved( _rxObject
);
4129 Reference
<XSQLErrorBroadcaster
> xBroadcaster(_rxObject
, UNO_QUERY
);
4130 Reference
<XForm
> xForm(_rxObject
, UNO_QUERY
);
4131 if (xBroadcaster
.is() && !xForm
.is())
4132 { // the object is an error broadcaster, but no form itself -> remove ourself as listener
4133 xBroadcaster
->removeSQLErrorListener(this);
4137 //------------------------------------------------------------------------------
4138 void SAL_CALL
ODatabaseForm::errorOccured(const SQLErrorEvent
& _rEvent
) throw( RuntimeException
)
4140 // give it to my own error listener
4142 // TODO : think about extending the chain with an SQLContext object saying
4143 // "this was an error of one of my children"
4146 // com::sun::star::container::XNamed
4147 //------------------------------------------------------------------------------
4148 ::rtl::OUString SAL_CALL
ODatabaseForm::getName() throw( RuntimeException
)
4150 ::rtl::OUString sReturn
;
4151 OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME
) >>= sReturn
;
4155 //------------------------------------------------------------------------------
4156 void SAL_CALL
ODatabaseForm::setName(const ::rtl::OUString
& aName
) throw( RuntimeException
)
4158 setFastPropertyValue(PROPERTY_ID_NAME
, makeAny(aName
));
4161 //.........................................................................
4163 //.........................................................................