1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "componenttools.hxx"
22 #include "DatabaseForm.hxx"
23 #include "EventThread.hxx"
24 #include "frm_resource.hrc"
25 #include "frm_resource.hxx"
26 #include "GroupManager.hxx"
27 #include "property.hrc"
28 #include "property.hxx"
29 #include "services.hxx"
31 #include <com/sun/star/awt/XControlContainer.hpp>
32 #include <com/sun/star/awt/XTextComponent.hpp>
33 #include <com/sun/star/form/DataSelectionType.hpp>
34 #include <com/sun/star/form/FormComponentType.hpp>
35 #include <com/sun/star/form/TabulatorCycle.hpp>
36 #include <com/sun/star/frame/FrameSearchFlag.hpp>
37 #include <com/sun/star/frame/XDispatch.hpp>
38 #include <com/sun/star/frame/XDispatchProvider.hpp>
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/io/XObjectInputStream.hpp>
41 #include <com/sun/star/io/XObjectOutputStream.hpp>
42 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
43 #include <com/sun/star/sdb/CommandType.hpp>
44 #include <com/sun/star/sdb/RowSetVetoException.hpp>
45 #include <com/sun/star/sdb/SQLContext.hpp>
46 #include <com/sun/star/sdb/XColumnUpdate.hpp>
47 #include <com/sun/star/sdbc/DataType.hpp>
48 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
49 #include <com/sun/star/sdbc/ResultSetType.hpp>
50 #include <com/sun/star/sdbc/XRowSet.hpp>
51 #include <com/sun/star/sdbcx/Privilege.hpp>
52 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
53 #include <com/sun/star/util/XCancellable.hpp>
54 #include <com/sun/star/util/URLTransformer.hpp>
55 #include <com/sun/star/util/XURLTransformer.hpp>
56 #include <com/sun/star/util/XModifiable2.hpp>
58 #include <comphelper/basicio.hxx>
59 #include <comphelper/container.hxx>
60 #include <comphelper/enumhelper.hxx>
61 #include <comphelper/processfactory.hxx>
62 #include <comphelper/seqstream.hxx>
63 #include <comphelper/sequence.hxx>
64 #include <connectivity/dbtools.hxx>
65 #include <cppuhelper/exc_hlp.hxx>
66 #include <cppuhelper/implbase2.hxx>
67 #include <cppuhelper/supportsservice.hxx>
68 #include <rtl/math.hxx>
69 #include <rtl/tencinfo.h>
70 #include <svl/inettype.hxx>
71 #include <tools/datetime.hxx>
72 #include <tools/debug.hxx>
73 #include <tools/diagnose_ex.h>
74 #include <tools/inetmsg.hxx>
75 #include <tools/inetstrm.hxx>
76 #include <tools/urlobj.hxx>
77 #include <unotools/ucbstreamhelper.hxx>
78 #include <vcl/svapp.hxx>
79 #include <vcl/timer.hxx>
80 #include <osl/mutex.hxx>
83 #include <unordered_map>
85 // compatibility: DatabaseCursorType is dead, but for compatibility reasons we still have to write it ...
91 enum DatabaseCursorType
93 DatabaseCursorType_FORWARD
= 0,
94 DatabaseCursorType_SNAPSHOT
= 1,
95 DatabaseCursorType_KEYSET
= 2,
96 DatabaseCursorType_DYNAMIC
= 3,
97 DatabaseCursorType_MAKE_FIXED_SIZE
= SAL_MAX_ENUM
102 using namespace ::dbtools
;
103 using namespace ::comphelper
;
104 using namespace ::com::sun::star::uno
;
105 using namespace ::com::sun::star::sdb
;
106 using namespace ::com::sun::star::sdbc
;
107 using namespace ::com::sun::star::sdbcx
;
108 using namespace ::com::sun::star::beans
;
109 using namespace ::com::sun::star::container
;
110 using namespace ::com::sun::star::task
;
111 using namespace ::com::sun::star::frame
;
112 using namespace ::com::sun::star::form
;
113 using namespace ::com::sun::star::awt
;
114 using namespace ::com::sun::star::io
;
115 using namespace ::com::sun::star::lang
;
116 using namespace ::com::sun::star::data
;
117 using namespace ::com::sun::star::util
;
123 class DocumentModifyGuard
126 DocumentModifyGuard( const Reference
< XInterface
>& _rxFormComponent
)
127 :m_xDocumentModify( getXModel( _rxFormComponent
), UNO_QUERY
)
129 impl_changeModifiableFlag_nothrow( false );
131 ~DocumentModifyGuard()
133 impl_changeModifiableFlag_nothrow( true );
137 void impl_changeModifiableFlag_nothrow( const bool _enable
)
141 if ( m_xDocumentModify
.is() )
142 _enable
? m_xDocumentModify
->enableSetModified() : m_xDocumentModify
->disableSetModified();
144 catch(const Exception
&)
146 DBG_UNHANDLED_EXCEPTION();
151 Reference
< XModifiable2
> m_xDocumentModify
;
154 // submitting and resetting html-forms asynchronously
155 class OFormSubmitResetThread
: public OComponentEventThread
159 // duplicate an event with respect to it's type
160 virtual EventObject
*cloneEvent( const EventObject
*pEvt
) const SAL_OVERRIDE
;
162 // process an event. while processing the mutex isn't locked, and pCompImpl
163 // is made sure to remain valid
164 virtual void processEvent( ::cppu::OComponentHelper
* _pCompImpl
,
165 const EventObject
* _pEvt
,
166 const Reference
<XControl
>& _rControl
,
167 bool _bSubmit
) SAL_OVERRIDE
;
171 OFormSubmitResetThread(ODatabaseForm
* pControl
) : OComponentEventThread(pControl
) { }
175 EventObject
* OFormSubmitResetThread::cloneEvent(
176 const EventObject
*pEvt
) const
178 return new ::com::sun::star::awt::MouseEvent( *static_cast<const ::com::sun::star::awt::MouseEvent
*>(pEvt
) );
182 void OFormSubmitResetThread::processEvent(
183 ::cppu::OComponentHelper
* pCompImpl
,
184 const EventObject
*_pEvt
,
185 const Reference
<XControl
>& _rControl
,
189 static_cast<ODatabaseForm
*>(pCompImpl
)->submit_impl(_rControl
, *static_cast<const ::com::sun::star::awt::MouseEvent
*>(_pEvt
), true);
191 static_cast<ODatabaseForm
*>(pCompImpl
)->reset_impl(true);
197 Sequence
<sal_Int8
> SAL_CALL
ODatabaseForm::getImplementationId() throw(RuntimeException
, std::exception
)
199 return css::uno::Sequence
<sal_Int8
>();
203 Sequence
<Type
> SAL_CALL
ODatabaseForm::getTypes() throw(RuntimeException
, std::exception
)
206 Sequence
<Type
> aAggregateTypes
;
207 Reference
<XTypeProvider
> xAggregateTypes
;
208 if (query_aggregation(m_xAggregate
, xAggregateTypes
))
209 aAggregateTypes
= xAggregateTypes
->getTypes();
211 Sequence
< Type
> aRet
= concatSequences(
212 aAggregateTypes
, ODatabaseForm_BASE1::getTypes(), OFormComponents::getTypes()
214 aRet
= concatSequences( aRet
, ODatabaseForm_BASE2::getTypes(), ODatabaseForm_BASE3::getTypes() );
215 return concatSequences( aRet
, OPropertySetAggregationHelper::getTypes() );
219 Any SAL_CALL
ODatabaseForm::queryAggregation(const Type
& _rType
) throw(RuntimeException
, std::exception
)
221 Any aReturn
= ODatabaseForm_BASE1::queryInterface(_rType
);
222 // our own interfaces
223 if (!aReturn
.hasValue())
225 aReturn
= ODatabaseForm_BASE2::queryInterface(_rType
);
226 // property set related interfaces
227 if (!aReturn
.hasValue())
229 aReturn
= OPropertySetAggregationHelper::queryInterface(_rType
);
231 // form component collection related interfaces
232 if (!aReturn
.hasValue())
234 aReturn
= OFormComponents::queryAggregation(_rType
);
236 // interfaces already present in the aggregate which we want to reroute
237 // only available if we could create the aggregate
238 if (!aReturn
.hasValue() && m_xAggregateAsRowSet
.is())
239 aReturn
= ODatabaseForm_BASE3::queryInterface(_rType
);
241 // aggregate interfaces
242 // (ask the aggregated object _after_ the OComponentHelper (base of OFormComponents),
243 // so calls to the XComponent interface reach us and not the aggregation)
244 if (!aReturn
.hasValue() && m_xAggregate
.is())
245 aReturn
= m_xAggregate
->queryAggregation(_rType
);
254 ODatabaseForm::ODatabaseForm(const Reference
<XComponentContext
>& _rxContext
)
255 :OFormComponents(_rxContext
)
256 ,OPropertySetAggregationHelper(OComponentHelper::rBHelper
)
257 ,OPropertyChangeListener(m_aMutex
)
258 ,m_aLoadListeners(m_aMutex
)
259 ,m_aRowSetApproveListeners(m_aMutex
)
260 ,m_aRowSetListeners(m_aMutex
)
261 ,m_aSubmitListeners(m_aMutex
)
262 ,m_aErrorListeners(m_aMutex
)
263 ,m_aResetListeners( *this, m_aMutex
)
264 ,m_aPropertyBagHelper( *this )
265 ,m_pAggregatePropertyMultiplexer(NULL
)
266 ,m_pGroupManager( NULL
)
267 ,m_aParameterManager( m_aMutex
, _rxContext
)
273 ,m_bInsertOnly( false )
274 ,m_eSubmitMethod(FormSubmitMethod_GET
)
275 ,m_eSubmitEncoding(FormSubmitEncoding_URL
)
276 ,m_eNavigation(NavigationBarMode_CURRENT
)
277 ,m_bAllowInsert(true)
278 ,m_bAllowUpdate(true)
279 ,m_bAllowDelete(true)
282 ,m_bForwardingConnection(false)
283 ,m_bSharingConnection( false )
289 ODatabaseForm::ODatabaseForm( const ODatabaseForm
& _cloneSource
)
290 :OFormComponents( _cloneSource
)
291 ,OPropertySetAggregationHelper( OComponentHelper::rBHelper
)
292 ,OPropertyChangeListener( m_aMutex
)
293 ,ODatabaseForm_BASE1()
294 ,ODatabaseForm_BASE2()
295 ,ODatabaseForm_BASE3()
296 ,IPropertyBagHelperContext()
297 ,m_aLoadListeners( m_aMutex
)
298 ,m_aRowSetApproveListeners( m_aMutex
)
299 ,m_aRowSetListeners( m_aMutex
)
300 ,m_aSubmitListeners( m_aMutex
)
301 ,m_aErrorListeners( m_aMutex
)
302 ,m_aResetListeners( *this, m_aMutex
)
303 ,m_aPropertyBagHelper( *this )
304 ,m_pAggregatePropertyMultiplexer( NULL
)
305 ,m_pGroupManager( NULL
)
306 ,m_aParameterManager( m_aMutex
, _cloneSource
.m_xContext
)
308 ,m_pLoadTimer( NULL
)
310 ,m_nResetsPending( 0 )
312 ,m_bInsertOnly( _cloneSource
.m_bInsertOnly
)
313 ,m_aControlBorderColorFocus( _cloneSource
.m_aControlBorderColorFocus
)
314 ,m_aControlBorderColorMouse( _cloneSource
.m_aControlBorderColorMouse
)
315 ,m_aControlBorderColorInvalid( _cloneSource
.m_aControlBorderColorInvalid
)
316 ,m_aDynamicControlBorder( _cloneSource
.m_aDynamicControlBorder
)
317 ,m_sName( _cloneSource
.m_sName
)
318 ,m_aTargetURL( _cloneSource
.m_aTargetURL
)
319 ,m_aTargetFrame( _cloneSource
.m_aTargetFrame
)
320 ,m_eSubmitMethod( _cloneSource
.m_eSubmitMethod
)
321 ,m_eSubmitEncoding( _cloneSource
.m_eSubmitEncoding
)
322 ,m_eNavigation( _cloneSource
.m_eNavigation
)
323 ,m_bAllowInsert( _cloneSource
.m_bAllowInsert
)
324 ,m_bAllowUpdate( _cloneSource
.m_bAllowUpdate
)
325 ,m_bAllowDelete( _cloneSource
.m_bAllowDelete
)
328 ,m_bForwardingConnection( false )
329 ,m_bSharingConnection( false )
334 osl_atomic_increment( &m_refCount
);
336 // our aggregated rowset itself is not cloneable, so simply copy the properties
337 ::comphelper::copyProperties( _cloneSource
.m_xAggregateSet
, m_xAggregateSet
);
339 // also care for the dynamic properties: If the clone source has properties which we do not have,
343 Reference
< XPropertySet
> xSourceProps( const_cast< ODatabaseForm
& >( _cloneSource
).queryAggregation(
344 cppu::UnoType
<XPropertySet
>::get() ), UNO_QUERY_THROW
);
345 Reference
< XPropertySetInfo
> xSourcePSI( xSourceProps
->getPropertySetInfo(), UNO_SET_THROW
);
346 Reference
< XPropertyState
> xSourcePropState( xSourceProps
, UNO_QUERY
);
348 Reference
< XPropertySetInfo
> xDestPSI( getPropertySetInfo(), UNO_QUERY_THROW
);
350 Sequence
< Property
> aSourceProperties( xSourcePSI
->getProperties() );
351 for ( const Property
* pSourceProperty
= aSourceProperties
.getConstArray();
352 pSourceProperty
!= aSourceProperties
.getConstArray() + aSourceProperties
.getLength();
356 if ( xDestPSI
->hasPropertyByName( pSourceProperty
->Name
) )
359 // the initial value passed to XPropertyContainer is also used as default, usually. So, try
360 // to retrieve the default of the source property
362 if ( xSourcePropState
.is() )
364 aInitialValue
= xSourcePropState
->getPropertyDefault( pSourceProperty
->Name
);
368 aInitialValue
= xSourceProps
->getPropertyValue( pSourceProperty
->Name
);
370 addProperty( pSourceProperty
->Name
, pSourceProperty
->Attributes
, aInitialValue
);
371 setPropertyValue( pSourceProperty
->Name
, xSourceProps
->getPropertyValue( pSourceProperty
->Name
) );
374 catch(const RuntimeException
&)
378 catch(const Exception
&)
380 css::uno::Any
a(cppu::getCaughtException());
381 throw WrappedTargetRuntimeException(
382 "Could not clone the given database form.",
383 *const_cast< ODatabaseForm
* >( &_cloneSource
),
388 osl_atomic_decrement( &m_refCount
);
391 void ODatabaseForm::impl_construct()
393 // aggregate a row set
394 osl_atomic_increment(&m_refCount
);
396 m_xAggregate
= Reference
< XAggregation
>( m_xContext
->getServiceManager()->createInstanceWithContext(SRV_SDB_ROWSET
, m_xContext
), UNO_QUERY_THROW
);
397 m_xAggregateAsRowSet
.set( m_xAggregate
, UNO_QUERY_THROW
);
398 setAggregation( m_xAggregate
);
401 // listen for the properties, important for Parameters
402 if ( m_xAggregateSet
.is() )
404 m_pAggregatePropertyMultiplexer
= new OPropertyChangeMultiplexer(this, m_xAggregateSet
, false);
405 m_pAggregatePropertyMultiplexer
->acquire();
406 m_pAggregatePropertyMultiplexer
->addProperty(PROPERTY_COMMAND
);
407 m_pAggregatePropertyMultiplexer
->addProperty(PROPERTY_ACTIVE_CONNECTION
);
411 Reference
< XWarningsSupplier
> xRowSetWarnings( m_xAggregate
, UNO_QUERY
);
412 m_aWarnings
.setExternalWarnings( xRowSetWarnings
);
415 if ( m_xAggregate
.is() )
417 m_xAggregate
->setDelegator( static_cast< XWeak
* >( this ) );
421 m_aFilterManager
.initialize( m_xAggregateSet
);
422 m_aParameterManager
.initialize( this, m_xAggregate
);
424 declareForwardedProperty( PROPERTY_ID_ACTIVE_CONNECTION
);
426 osl_atomic_decrement( &m_refCount
);
428 m_pGroupManager
= new OGroupManager( this );
429 m_pGroupManager
->acquire();
433 ODatabaseForm::~ODatabaseForm()
436 m_pGroupManager
->release();
437 m_pGroupManager
= NULL
;
439 if (m_xAggregate
.is())
440 m_xAggregate
->setDelegator( NULL
);
442 m_aWarnings
.setExternalWarnings( NULL
);
444 if (m_pAggregatePropertyMultiplexer
)
446 m_pAggregatePropertyMultiplexer
->dispose();
447 m_pAggregatePropertyMultiplexer
->release();
448 m_pAggregatePropertyMultiplexer
= NULL
;
455 OUString
ODatabaseForm::GetDataURLEncoded(const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
457 return GetDataEncoded(true,SubmitButton
,MouseEvt
);
460 OUString
ODatabaseForm::GetDataEncoded(bool _bURLEncoded
,const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
462 // Fill List of successful Controls
463 HtmlSuccessfulObjList aSuccObjList
;
464 FillSuccessfulList( aSuccObjList
, SubmitButton
, MouseEvt
);
467 // Aggregate Liste to OUString
468 OUStringBuffer aResult
;
472 for ( HtmlSuccessfulObjList::iterator pSuccObj
= aSuccObjList
.begin();
473 pSuccObj
< aSuccObjList
.end();
477 aName
= pSuccObj
->aName
;
478 aValue
= pSuccObj
->aValue
;
479 if( pSuccObj
->nRepresentation
== SUCCESSFUL_REPRESENT_FILE
&& !aValue
.isEmpty() )
481 // For File URLs we transfer the file name and not a URL, because Netscape does it like that
483 aURL
.SetSmartProtocol(INetProtocol::File
);
484 aURL
.SetSmartURL(aValue
);
485 if( INetProtocol::File
== aURL
.GetProtocol() )
486 aValue
= INetURLObject::decode(aURL
.PathToFileName(), INetURLObject::DECODE_UNAMBIGUOUS
);
491 aResult
.append(aName
);
493 aResult
.append(aValue
);
495 if (pSuccObj
< aSuccObjList
.end() - 1)
500 aResult
.appendAscii("\r\n");
505 aSuccObjList
.clear();
507 return aResult
.makeStringAndClear();
513 OUString
ODatabaseForm::GetDataTextEncoded(const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
515 return GetDataEncoded(false,SubmitButton
,MouseEvt
);
519 Sequence
<sal_Int8
> ODatabaseForm::GetDataMultiPartEncoded(const Reference
<XControl
>& SubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
, OUString
& rContentType
)
523 INetMIMEMessage aParent
;
524 aParent
.EnableAttachChild( INETMSG_MULTIPART_FORM_DATA
);
527 // Fill List of successful Controls
528 HtmlSuccessfulObjList aSuccObjList
;
529 FillSuccessfulList( aSuccObjList
, SubmitButton
, MouseEvt
);
532 // Aggregate Liste to OUString
533 for ( HtmlSuccessfulObjList::iterator pSuccObj
= aSuccObjList
.begin();
534 pSuccObj
< aSuccObjList
.end();
538 if( pSuccObj
->nRepresentation
== SUCCESSFUL_REPRESENT_TEXT
)
539 InsertTextPart( aParent
, pSuccObj
->aName
, pSuccObj
->aValue
);
540 else if( pSuccObj
->nRepresentation
== SUCCESSFUL_REPRESENT_FILE
)
541 InsertFilePart( aParent
, pSuccObj
->aName
, pSuccObj
->aValue
);
546 aSuccObjList
.clear();
548 // Create MessageStream for parent
549 INetMIMEMessageStream aMessStream
;
550 aMessStream
.SetSourceMessage( &aParent
);
551 aMessStream
.SetHeaderGenerated();
553 // Copy MessageStream to SvStream
554 SvMemoryStream aMemStream
;
555 char* pBuf
= new char[1025];
557 while( (nRead
= aMessStream
.Read(pBuf
, 1024)) > 0 )
558 aMemStream
.Write( pBuf
, nRead
);
562 aMemStream
.Seek( 0 );
563 void const * pData
= aMemStream
.GetData();
564 sal_Int32 nLen
= aMemStream
.Seek(STREAM_SEEK_TO_END
);
566 rContentType
= aParent
.GetContentType();
567 return Sequence
<sal_Int8
>(static_cast<sal_Int8
const *>(pData
), nLen
);
573 static void appendDigits( sal_Int32 _nNumber
, sal_Int8 nDigits
, OUStringBuffer
& _rOut
)
575 sal_Int32 nCurLen
= _rOut
.getLength();
576 _rOut
.append( _nNumber
);
577 while ( _rOut
.getLength() - nCurLen
< nDigits
)
578 _rOut
.insert( nCurLen
, '0' );
583 void ODatabaseForm::AppendComponent(HtmlSuccessfulObjList
& rList
, const Reference
<XPropertySet
>& xComponentSet
, const OUString
& rNamePrefix
,
584 const Reference
<XControl
>& rxSubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
586 if (!xComponentSet
.is())
589 // TODO: Catch nested Forms; or would we need to submit them?
590 if (!hasProperty(PROPERTY_CLASSID
, xComponentSet
))
594 if (!hasProperty(PROPERTY_NAME
, xComponentSet
))
597 sal_Int16 nClassId
= 0;
598 xComponentSet
->getPropertyValue(PROPERTY_CLASSID
) >>= nClassId
;
600 xComponentSet
->getPropertyValue( PROPERTY_NAME
) >>= aName
;
601 if( aName
.isEmpty() && nClassId
!= FormComponentType::IMAGEBUTTON
)
603 else // Extend name with the prefix
604 aName
= rNamePrefix
+ aName
;
609 case FormComponentType::COMMANDBUTTON
:
611 // We only evaluate the pressed Submit button
612 // If one is passed at all
613 if( rxSubmitButton
.is() )
615 Reference
<XPropertySet
> xSubmitButtonComponent(rxSubmitButton
->getModel(), UNO_QUERY
);
616 if (xSubmitButtonComponent
== xComponentSet
&& hasProperty(PROPERTY_LABEL
, xComponentSet
))
620 xComponentSet
->getPropertyValue( PROPERTY_LABEL
) >>= aLabel
;
621 rList
.push_back( HtmlSuccessfulObj(aName
, aLabel
) );
627 case FormComponentType::IMAGEBUTTON
:
629 // We only evaluate the pressed Submit button
630 // If one is passed at all
631 if( rxSubmitButton
.is() )
633 Reference
<XPropertySet
> xSubmitButtonComponent(rxSubmitButton
->getModel(), UNO_QUERY
);
634 if (xSubmitButtonComponent
== xComponentSet
)
636 // <name>.x=<pos.X>&<name>.y=<pos.Y>
637 OUString aRhs
= OUString::number( MouseEvt
.X
);
639 // Only if a name is available we have a name.x
640 OUStringBuffer
aLhs(aName
);
641 if (!aName
.isEmpty())
645 rList
.push_back( HtmlSuccessfulObj(aLhs
.makeStringAndClear(), aRhs
) );
648 aRhs
= OUString::number( MouseEvt
.Y
);
649 if (!aName
.isEmpty())
653 rList
.push_back( HtmlSuccessfulObj(aLhs
.makeStringAndClear(), aRhs
) );
658 // CheckBoxes/RadioButtons
659 case FormComponentType::CHECKBOX
:
660 case FormComponentType::RADIOBUTTON
:
663 if( !hasProperty(PROPERTY_STATE
, xComponentSet
) )
665 sal_Int16 nChecked
= 0;
666 xComponentSet
->getPropertyValue( PROPERTY_STATE
) >>= nChecked
;
671 if( hasProperty(PROPERTY_REFVALUE
, xComponentSet
) )
672 xComponentSet
->getPropertyValue( PROPERTY_REFVALUE
) >>= aStrValue
;
674 rList
.push_back( HtmlSuccessfulObj(aName
, aStrValue
) );
678 case FormComponentType::TEXTFIELD
:
681 if( !hasProperty(PROPERTY_TEXT
, xComponentSet
) )
684 // Special treatment for multiline edit only if we have a control for it
685 Any aTmp
= xComponentSet
->getPropertyValue( PROPERTY_MULTILINE
);
686 bool bMulti
= rxSubmitButton
.is()
687 && (aTmp
.getValueType().getTypeClass() == TypeClass_BOOLEAN
)
690 if ( bMulti
) // For multiline edit, get the text at the control
693 Reference
<XControlContainer
> xControlContainer(rxSubmitButton
->getContext(), UNO_QUERY
);
694 if( !xControlContainer
.is() ) break;
696 Sequence
<Reference
<XControl
> > aControlSeq
= xControlContainer
->getControls();
697 Reference
<XControl
> xControl
;
698 Reference
<XFormComponent
> xControlComponent
;
700 // Find the right control
702 for( i
=0; i
<aControlSeq
.getLength(); i
++ )
704 xControl
= aControlSeq
.getConstArray()[i
];
705 Reference
<XPropertySet
> xModel(xControl
->getModel(), UNO_QUERY
);
706 if (xModel
== xComponentSet
)
708 Reference
<XTextComponent
> xTextComponent(xControl
, UNO_QUERY
);
709 if( xTextComponent
.is() )
710 sText
= xTextComponent
->getText();
714 // Couldn't find control or it does not exist (edit in the grid)
715 if (i
== aControlSeq
.getLength())
716 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= sText
;
719 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= sText
;
721 rList
.push_back( HtmlSuccessfulObj(aName
, sText
) );
724 // ComboBox, Patternfield
725 case FormComponentType::COMBOBOX
:
726 case FormComponentType::PATTERNFIELD
:
729 if( hasProperty(PROPERTY_TEXT
, xComponentSet
) )
732 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= aText
;
733 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
736 case FormComponentType::CURRENCYFIELD
:
737 case FormComponentType::NUMERICFIELD
:
739 // <name>=<value> // Value is a double with dot as decimal delimiter
740 // no value (NULL) means empty value
741 if( hasProperty(PROPERTY_VALUE
, xComponentSet
) )
744 Any aVal
= xComponentSet
->getPropertyValue( PROPERTY_VALUE
);
746 double aDoubleVal
= 0;
747 if (aVal
>>= aDoubleVal
)
749 sal_Int16 nScale
= 0;
750 xComponentSet
->getPropertyValue( PROPERTY_DECIMAL_ACCURACY
) >>= nScale
;
751 aText
= ::rtl::math::doubleToUString(aDoubleVal
, rtl_math_StringFormat_F
, nScale
, '.', true);
753 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
756 case FormComponentType::DATEFIELD
:
758 // <name>=<value> // Value is a Date with the format MM-DD-YYYY
759 // no value (NULL) means empty value
760 if( hasProperty(PROPERTY_DATE
, xComponentSet
) )
763 Any aVal
= xComponentSet
->getPropertyValue( PROPERTY_DATE
);
764 sal_Int32 nInt32Val
= 0;
765 if (aVal
>>= nInt32Val
)
767 ::Date
aDate( nInt32Val
);
768 OUStringBuffer aBuffer
;
769 appendDigits( aDate
.GetMonth(), 2, aBuffer
);
770 aBuffer
.append( '-' );
771 appendDigits( aDate
.GetDay(), 2, aBuffer
);
772 aBuffer
.append( '-' );
773 appendDigits( aDate
.GetYear(), 4, aBuffer
);
774 aText
= aBuffer
.makeStringAndClear();
776 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
779 case FormComponentType::TIMEFIELD
:
781 // <name>=<value> // Value is a Time with the format HH:MM:SS
782 // no value (NULL) means empty value
783 if( hasProperty(PROPERTY_TIME
, xComponentSet
) )
786 Any aVal
= xComponentSet
->getPropertyValue( PROPERTY_TIME
);
787 sal_Int32 nInt32Val
= 0;
788 if (aVal
>>= nInt32Val
)
790 ::tools::Time
aTime(nInt32Val
);
791 OUStringBuffer aBuffer
;
792 appendDigits( aTime
.GetHour(), 2, aBuffer
);
793 aBuffer
.append( '-' );
794 appendDigits( aTime
.GetMin(), 2, aBuffer
);
795 aBuffer
.append( '-' );
796 appendDigits( aTime
.GetSec(), 2, aBuffer
);
797 aText
= aBuffer
.makeStringAndClear();
799 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
804 case FormComponentType::HIDDENCONTROL
:
808 if( hasProperty(PROPERTY_HIDDEN_VALUE
, xComponentSet
) )
811 xComponentSet
->getPropertyValue( PROPERTY_HIDDEN_VALUE
) >>= aText
;
812 rList
.push_back( HtmlSuccessfulObj(aName
, aText
) );
817 case FormComponentType::FILECONTROL
:
820 if( hasProperty(PROPERTY_TEXT
, xComponentSet
) )
824 xComponentSet
->getPropertyValue( PROPERTY_TEXT
) >>= aText
;
825 rList
.push_back( HtmlSuccessfulObj(aName
, aText
, SUCCESSFUL_REPRESENT_FILE
) );
830 case FormComponentType::LISTBOX
:
833 // <name>=<Token0>&<name>=<Token1>&...&<name>=<TokenN> (multiple selection)
834 if (!hasProperty(PROPERTY_SELECT_SEQ
, xComponentSet
) ||
835 !hasProperty(PROPERTY_STRINGITEMLIST
, xComponentSet
))
839 Sequence
< OUString
> aVisibleList
;
840 xComponentSet
->getPropertyValue( PROPERTY_STRINGITEMLIST
) >>= aVisibleList
;
841 sal_Int32 nStringCnt
= aVisibleList
.getLength();
842 const OUString
* pStrings
= aVisibleList
.getConstArray();
845 Sequence
< OUString
> aValueList
;
846 xComponentSet
->getPropertyValue( PROPERTY_VALUE_SEQ
) >>= aValueList
;
847 sal_Int32 nValCnt
= aValueList
.getLength();
848 const OUString
* pVals
= aValueList
.getConstArray();
851 Sequence
<sal_Int16
> aSelectList
;
852 xComponentSet
->getPropertyValue( PROPERTY_SELECT_SEQ
) >>= aSelectList
;
853 sal_Int32 nSelCount
= aSelectList
.getLength();
854 const sal_Int16
* pSels
= aSelectList
.getConstArray();
856 // Simple or multiple selection
857 // For simple selections MT only accounts for the list's first entry.
858 if (nSelCount
> 1 && !getBOOL(xComponentSet
->getPropertyValue(PROPERTY_MULTISELECTION
)))
861 // The indices in the selection list can also be invalid, so we first have to
862 // find the valid ones to determine the length of the new list.
863 sal_Int32 nCurCnt
= 0;
865 for( i
=0; i
<nSelCount
; ++i
)
867 if( pSels
[i
] < nStringCnt
)
872 for(i
=0; i
<nCurCnt
; ++i
)
874 sal_Int16 nSelPos
= pSels
[i
];
875 if (nSelPos
< nValCnt
&& !pVals
[nSelPos
].isEmpty())
877 aSubValue
= pVals
[nSelPos
];
881 aSubValue
= pStrings
[nSelPos
];
883 rList
.push_back( HtmlSuccessfulObj(aName
, aSubValue
) );
886 case FormComponentType::GRIDCONTROL
:
888 // Each of the column values is sent;
889 // the name is extended by the grid's prefix.
890 Reference
<XIndexAccess
> xContainer(xComponentSet
, UNO_QUERY
);
891 if (!xContainer
.is())
896 Reference
<XPropertySet
> xSet
;
897 sal_Int32 nCount
= xContainer
->getCount();
898 // we know already how many objects should be appended,
899 // so why not allocate the space for them
900 rList
.reserve( nCount
+ rList
.capacity() ); // not size()
901 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
903 xContainer
->getByIndex(i
) >>= xSet
;
905 AppendComponent(rList
, xSet
, aName
, rxSubmitButton
, MouseEvt
);
912 void ODatabaseForm::FillSuccessfulList( HtmlSuccessfulObjList
& rList
,
913 const Reference
<XControl
>& rxSubmitButton
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
)
917 // Iterate over Components
918 Reference
<XPropertySet
> xComponentSet
;
921 // we know already how many objects should be appended,
922 // so why not allocate the space for them
923 rList
.reserve( getCount() );
924 for( sal_Int32 nIndex
=0; nIndex
< getCount(); nIndex
++ )
926 getByIndex( nIndex
) >>= xComponentSet
;
927 AppendComponent(rList
, xComponentSet
, aPrefix
, rxSubmitButton
, MouseEvt
);
932 void ODatabaseForm::Encode( OUString
& rString
)
934 OUStringBuffer aResult
;
936 // Line endings are represented as CR
937 rString
= convertLineEnd(rString
, LINEEND_CR
);
939 // Check each character
940 sal_Int32 nStrLen
= rString
.getLength();
941 sal_Unicode nCharCode
;
942 for( sal_Int32 nCurPos
=0; nCurPos
< nStrLen
; ++nCurPos
)
944 nCharCode
= rString
[nCurPos
];
946 // Handle chars, which are not an alphanumeric character and character codes > 127
947 if( (!isalnum(nCharCode
) && nCharCode
!= ' ') || nCharCode
> 127 )
952 aResult
.append("%0D%0A"); // CR LF in hex
956 // Special treatment for Netscape
962 aResult
.append(nCharCode
);
968 short nHi
= ((sal_Int16
)nCharCode
) / 16;
969 short nLo
= ((sal_Int16
)nCharCode
) - (nHi
*16);
970 if( nHi
> 9 ) nHi
+= (int)'A'-10; else nHi
+= (int)'0';
971 if( nLo
> 9 ) nLo
+= (int)'A'-10; else nLo
+= (int)'0';
973 aResult
.append((sal_Unicode
)nHi
);
974 aResult
.append((sal_Unicode
)nLo
);
979 aResult
.append(nCharCode
);
982 // Replace spaces with '+'
983 rString
= aResult
.makeStringAndClear().replace(' ', '+');
987 void ODatabaseForm::InsertTextPart( INetMIMEMessage
& rParent
, const OUString
& rName
,
988 const OUString
& rData
)
991 // Create part as MessageChild
992 INetMIMEMessage
* pChild
= new INetMIMEMessage();
996 OUStringBuffer aContentDisp
;
997 aContentDisp
.append("form-data; name=\"");
998 aContentDisp
.append(rName
);
999 aContentDisp
.append('\"');
1000 pChild
->SetContentDisposition(aContentDisp
.makeStringAndClear());
1001 pChild
->SetContentType(OUString("text/plain"));
1003 rtl_TextEncoding eSystemEncoding
= osl_getThreadTextEncoding();
1004 const sal_Char
* pBestMatchingEncoding
= rtl_getBestMimeCharsetFromTextEncoding( eSystemEncoding
);
1005 OUString aBestMatchingEncoding
= OUString::createFromAscii(pBestMatchingEncoding
);
1006 pChild
->SetContentTransferEncoding(aBestMatchingEncoding
);
1009 SvMemoryStream
* pStream
= new SvMemoryStream
;
1010 pStream
->WriteLine( OUStringToOString(rData
, rtl_getTextEncodingFromMimeCharset(pBestMatchingEncoding
)) );
1013 pChild
->SetDocumentLB( new SvLockBytes(pStream
, true) );
1014 rParent
.AttachChild( *pChild
);
1018 bool ODatabaseForm::InsertFilePart( INetMIMEMessage
& rParent
, const OUString
& rName
,
1019 const OUString
& rFileName
)
1021 OUString
aFileName(rFileName
);
1022 OUString
aContentType(CONTENT_TYPE_STR_TEXT_PLAIN
);
1023 SvStream
*pStream
= 0;
1025 if (!aFileName
.isEmpty())
1027 // We can only process File URLs yet
1029 aURL
.SetSmartProtocol(INetProtocol::File
);
1030 aURL
.SetSmartURL(rFileName
);
1031 if( INetProtocol::File
== aURL
.GetProtocol() )
1033 aFileName
= INetURLObject::decode(aURL
.PathToFileName(), INetURLObject::DECODE_UNAMBIGUOUS
);
1034 pStream
= ::utl::UcbStreamHelper::CreateStream(aFileName
, StreamMode::READ
);
1035 if (!pStream
|| (pStream
->GetError() != ERRCODE_NONE
))
1040 sal_Int32 nSepInd
= aFileName
.lastIndexOf('.');
1041 OUString aExtension
= aFileName
.copy( nSepInd
+ 1, aFileName
.getLength() - nSepInd
- 1 );
1042 INetContentType eContentType
= INetContentTypes::GetContentType4Extension( aExtension
);
1043 if (eContentType
!= CONTENT_TYPE_UNKNOWN
)
1044 aContentType
= INetContentTypes::GetContentType(eContentType
);
1048 // If something didn't work, we create an empty MemoryStream
1050 pStream
= new SvMemoryStream
;
1053 // Create part as MessageChild
1054 INetMIMEMessage
* pChild
= new INetMIMEMessage
;
1058 OUStringBuffer aContentDisp
;
1059 aContentDisp
.append("form-data; name=\"");
1060 aContentDisp
.append(rName
);
1061 aContentDisp
.append('\"');
1062 aContentDisp
.append("; filename=\"");
1063 aContentDisp
.append(aFileName
);
1064 aContentDisp
.append('\"');
1065 pChild
->SetContentDisposition(aContentDisp
.makeStringAndClear());
1066 pChild
->SetContentType( aContentType
);
1067 pChild
->SetContentTransferEncoding(OUString("8bit"));
1071 pChild
->SetDocumentLB( new SvLockBytes(pStream
, true) );
1072 rParent
.AttachChild( *pChild
);
1080 void ODatabaseForm::onError( const SQLErrorEvent
& _rEvent
)
1082 m_aErrorListeners
.notifyEach( &XSQLErrorListener::errorOccured
, _rEvent
);
1086 void ODatabaseForm::onError( const SQLException
& _rException
, const OUString
& _rContextDescription
)
1088 if ( !m_aErrorListeners
.getLength() )
1091 SQLErrorEvent
aEvent( *this, makeAny( prependErrorInfo( _rException
, *this, _rContextDescription
) ) );
1096 void ODatabaseForm::updateParameterInfo()
1098 m_aParameterManager
.updateParameterInfo( m_aFilterManager
);
1102 bool ODatabaseForm::hasValidParent() const
1104 // do we have to fill the parameters again?
1107 Reference
<XResultSet
> xResultSet(m_xParent
, UNO_QUERY
);
1108 if (!xResultSet
.is())
1110 OSL_FAIL("ODatabaseForm::hasValidParent() : no parent resultset !");
1115 Reference
< XPropertySet
> xSet( m_xParent
, UNO_QUERY
);
1116 Reference
< XLoadable
> xLoad( m_xParent
, UNO_QUERY
);
1117 if ( xLoad
->isLoaded()
1118 && ( xResultSet
->isBeforeFirst()
1119 || xResultSet
->isAfterLast()
1120 || getBOOL( xSet
->getPropertyValue( PROPERTY_ISNEW
) )
1123 // the parent form is loaded and on a "virtual" row -> not valid
1126 catch(const Exception
&)
1128 // parent could be forwardonly?
1136 bool ODatabaseForm::fillParameters( ::osl::ResettableMutexGuard
& _rClearForNotifies
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
)
1138 // do we have to fill the parameters again?
1139 if ( !m_aParameterManager
.isUpToDate() )
1140 updateParameterInfo();
1142 // is there a valid parent?
1143 if ( m_bSubForm
&& !hasValidParent() )
1146 // ensure we're connected
1147 if ( !implEnsureConnection() )
1150 if ( m_aParameterManager
.isUpToDate() )
1151 return m_aParameterManager
.fillParameterValues( _rxCompletionHandler
, _rClearForNotifies
);
1157 void ODatabaseForm::saveInsertOnlyState( )
1159 OSL_ENSURE( !m_aIgnoreResult
.hasValue(), "ODatabaseForm::saveInsertOnlyState: overriding old value!" );
1160 m_aIgnoreResult
= m_xAggregateSet
->getPropertyValue( PROPERTY_INSERTONLY
);
1164 void ODatabaseForm::restoreInsertOnlyState( )
1166 if ( m_aIgnoreResult
.hasValue() )
1168 m_xAggregateSet
->setPropertyValue( PROPERTY_INSERTONLY
, m_aIgnoreResult
);
1169 m_aIgnoreResult
= Any();
1174 bool ODatabaseForm::executeRowSet(::osl::ResettableMutexGuard
& _rClearForNotifies
, bool bMoveToFirst
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
)
1176 if (!m_xAggregateAsRowSet
.is())
1179 if (!fillParameters(_rClearForNotifies
, _rxCompletionHandler
))
1182 restoreInsertOnlyState( );
1184 // ensure the aggregated row set has the correct properties
1185 sal_Int32 nConcurrency
= ResultSetConcurrency::READ_ONLY
;
1187 // if we have a parent, who is not positioned on a valid row
1188 // we can't be updatable!
1189 if (m_bSubForm
&& !hasValidParent())
1191 nConcurrency
= ResultSetConcurrency::READ_ONLY
;
1193 // don't use any parameters if we don't have a valid parent
1194 m_aParameterManager
.setAllParametersNull();
1196 // switch to "insert only" mode
1197 saveInsertOnlyState( );
1198 m_xAggregateSet
->setPropertyValue( PROPERTY_INSERTONLY
, makeAny( sal_True
) );
1200 else if (m_bAllowInsert
|| m_bAllowUpdate
|| m_bAllowDelete
)
1201 nConcurrency
= ResultSetConcurrency::UPDATABLE
;
1203 nConcurrency
= ResultSetConcurrency::READ_ONLY
;
1205 m_xAggregateSet
->setPropertyValue( PROPERTY_RESULTSET_CONCURRENCY
, makeAny( (sal_Int32
)nConcurrency
) );
1206 m_xAggregateSet
->setPropertyValue( PROPERTY_RESULTSET_TYPE
, makeAny( (sal_Int32
)ResultSetType::SCROLL_SENSITIVE
) );
1208 bool bSuccess
= false;
1211 m_xAggregateAsRowSet
->execute();
1214 catch(const RowSetVetoException
&)
1217 catch(const SQLException
& eDb
)
1219 _rClearForNotifies
.clear();
1220 if (!m_sCurrentErrorContext
.isEmpty())
1221 onError(eDb
, m_sCurrentErrorContext
);
1223 onError(eDb
, FRM_RES_STRING(RID_STR_READERROR
));
1224 _rClearForNotifies
.reset();
1226 restoreInsertOnlyState( );
1231 // adjust the privilege property
1233 m_xAggregateSet
->getPropertyValue(PROPERTY_PRIVILEGES
) >>= m_nPrivileges
;
1234 if (!m_bAllowInsert
)
1235 m_nPrivileges
&= ~Privilege::INSERT
;
1236 if (!m_bAllowUpdate
)
1237 m_nPrivileges
&= ~Privilege::UPDATE
;
1238 if (!m_bAllowDelete
)
1239 m_nPrivileges
&= ~Privilege::DELETE
;
1243 // the row set is positioned _before_ the first row (per definitionem), so move the set ...
1246 // if we have an insert only rowset we move to the insert row
1248 if (((m_nPrivileges
& Privilege::INSERT
) == Privilege::INSERT
)
1251 // move on the insert row of set
1252 // resetting must be done later, after the load events have been posted
1253 // see: moveToInsertRow and load , reload
1254 Reference
<XResultSetUpdate
> xUpdate
;
1255 if (query_aggregation( m_xAggregate
, xUpdate
))
1256 xUpdate
->moveToInsertRow();
1259 catch(const SQLException
& eDB
)
1261 _rClearForNotifies
.clear();
1262 if (!m_sCurrentErrorContext
.isEmpty())
1263 onError(eDB
, m_sCurrentErrorContext
);
1265 onError(eDB
, FRM_RES_STRING(RID_STR_READERROR
));
1266 _rClearForNotifies
.reset();
1275 void ODatabaseForm::disposing()
1277 if (m_pAggregatePropertyMultiplexer
)
1278 m_pAggregatePropertyMultiplexer
->dispose();
1283 // cancel the submit/reset-thread
1285 ::osl::MutexGuard
aGuard( m_aMutex
);
1288 m_pThread
->release();
1293 EventObject
aEvt(static_cast<XWeak
*>(this));
1294 m_aLoadListeners
.disposeAndClear(aEvt
);
1295 m_aRowSetApproveListeners
.disposeAndClear(aEvt
);
1296 m_aResetListeners
.disposing();
1297 m_aSubmitListeners
.disposeAndClear(aEvt
);
1298 m_aErrorListeners
.disposeAndClear(aEvt
);
1300 m_aParameterManager
.dispose(); // To free any references it may have to be me
1301 m_aFilterManager
.dispose(); // (dito)
1303 OFormComponents::disposing();
1304 OPropertySetAggregationHelper::disposing();
1306 // stop listening on the aggregate
1307 if (m_xAggregateAsRowSet
.is())
1308 m_xAggregateAsRowSet
->removeRowSetListener(this);
1310 // dispose the active connection
1311 Reference
<XComponent
> xAggregationComponent
;
1312 if (query_aggregation(m_xAggregate
, xAggregationComponent
))
1313 xAggregationComponent
->dispose();
1315 m_aPropertyBagHelper
.dispose();
1319 Reference
< XConnection
> ODatabaseForm::getConnection()
1321 Reference
< XConnection
> xConn
;
1322 m_xAggregateSet
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xConn
;
1327 ::osl::Mutex
& ODatabaseForm::getMutex()
1333 // property handling
1335 void ODatabaseForm::describeFixedAndAggregateProperties(
1336 Sequence
< Property
>& _rProps
,
1337 Sequence
< Property
>& _rAggregateProps
) const
1339 BEGIN_DESCRIBE_AGGREGATION_PROPERTIES(22, m_xAggregateSet
)
1340 // we want to "override" the privileges, since we have additional "AllowInsert" etc. properties
1341 RemoveProperty( _rAggregateProps
, PROPERTY_PRIVILEGES
);
1343 // InsertOnly is also to be overridden, since we sometimes change it ourself
1344 RemoveProperty( _rAggregateProps
, PROPERTY_INSERTONLY
);
1346 // we remove and re-declare the DataSourceName property, 'cause we want it to be constrained, and the
1347 // original property of our aggregate isn't
1348 RemoveProperty( _rAggregateProps
, PROPERTY_DATASOURCE
);
1350 // for connection sharing, we need to override the ActiveConnection property, too
1351 RemoveProperty( _rAggregateProps
, PROPERTY_ACTIVE_CONNECTION
);
1353 // the Filter property is also overwritten, since we have some implicit filters
1354 // (e.g. the ones which result from linking master fields to detail fields
1355 // via column names instead of parameters)
1356 RemoveProperty( _rAggregateProps
, PROPERTY_FILTER
);
1357 RemoveProperty( _rAggregateProps
, PROPERTY_APPLYFILTER
);
1359 DECL_IFACE_PROP4(ACTIVE_CONNECTION
, XConnection
, BOUND
, TRANSIENT
, MAYBEVOID
, CONSTRAINED
);
1360 DECL_BOOL_PROP2 ( APPLYFILTER
, BOUND
, MAYBEDEFAULT
);
1361 DECL_PROP1 ( NAME
, OUString
, BOUND
);
1362 DECL_PROP1 ( MASTERFIELDS
, Sequence
< OUString
>, BOUND
);
1363 DECL_PROP1 ( DETAILFIELDS
, Sequence
< OUString
>, BOUND
);
1364 DECL_PROP2 ( DATASOURCE
, OUString
, BOUND
, CONSTRAINED
);
1365 DECL_PROP3 ( CYCLE
, TabulatorCycle
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1366 DECL_PROP2 ( FILTER
, OUString
, BOUND
, MAYBEDEFAULT
);
1367 DECL_BOOL_PROP2 ( INSERTONLY
, BOUND
, MAYBEDEFAULT
);
1368 DECL_PROP1 ( NAVIGATION
, NavigationBarMode
, BOUND
);
1369 DECL_BOOL_PROP1 ( ALLOWADDITIONS
, BOUND
);
1370 DECL_BOOL_PROP1 ( ALLOWEDITS
, BOUND
);
1371 DECL_BOOL_PROP1 ( ALLOWDELETIONS
, BOUND
);
1372 DECL_PROP2 ( PRIVILEGES
, sal_Int32
, TRANSIENT
, READONLY
);
1373 DECL_PROP1 ( TARGET_URL
, OUString
, BOUND
);
1374 DECL_PROP1 ( TARGET_FRAME
, OUString
, BOUND
);
1375 DECL_PROP1 ( SUBMIT_METHOD
, FormSubmitMethod
, BOUND
);
1376 DECL_PROP1 ( SUBMIT_ENCODING
, FormSubmitEncoding
, BOUND
);
1377 DECL_BOOL_PROP3 ( DYNAMIC_CONTROL_BORDER
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1378 DECL_PROP3 ( CONTROL_BORDER_COLOR_FOCUS
, sal_Int32
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1379 DECL_PROP3 ( CONTROL_BORDER_COLOR_MOUSE
, sal_Int32
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1380 DECL_PROP3 ( CONTROL_BORDER_COLOR_INVALID
, sal_Int32
, BOUND
, MAYBEVOID
, MAYBEDEFAULT
);
1381 END_DESCRIBE_PROPERTIES();
1385 Reference
< XMultiPropertySet
> ODatabaseForm::getPropertiesInterface()
1387 return Reference
< XMultiPropertySet
>( *this, UNO_QUERY
);
1391 ::cppu::IPropertyArrayHelper
& ODatabaseForm::getInfoHelper()
1393 return m_aPropertyBagHelper
.getInfoHelper();
1397 Reference
< XPropertySetInfo
> ODatabaseForm::getPropertySetInfo() throw( RuntimeException
, std::exception
)
1399 return createPropertySetInfo( getInfoHelper() );
1403 void SAL_CALL
ODatabaseForm::addProperty( const OUString
& _rName
, ::sal_Int16 _nAttributes
, const Any
& _rInitialValue
) throw (PropertyExistException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
, std::exception
)
1405 m_aPropertyBagHelper
.addProperty( _rName
, _nAttributes
, _rInitialValue
);
1409 void SAL_CALL
ODatabaseForm::removeProperty( const OUString
& _rName
) throw (UnknownPropertyException
, NotRemoveableException
, RuntimeException
, std::exception
)
1411 m_aPropertyBagHelper
.removeProperty( _rName
);
1415 Sequence
< PropertyValue
> SAL_CALL
ODatabaseForm::getPropertyValues() throw (RuntimeException
, std::exception
)
1417 return m_aPropertyBagHelper
.getPropertyValues();
1421 void SAL_CALL
ODatabaseForm::setPropertyValues( const Sequence
< PropertyValue
>& _rProps
) throw (UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
, std::exception
)
1423 m_aPropertyBagHelper
.setPropertyValues( _rProps
);
1427 Any SAL_CALL
ODatabaseForm::getWarnings( ) throw (SQLException
, RuntimeException
, std::exception
)
1429 return m_aWarnings
.getWarnings();
1433 void SAL_CALL
ODatabaseForm::clearWarnings( ) throw (SQLException
, RuntimeException
, std::exception
)
1435 m_aWarnings
.clearWarnings();
1439 Reference
< XCloneable
> SAL_CALL
ODatabaseForm::createClone( ) throw (RuntimeException
, std::exception
)
1441 ODatabaseForm
* pClone
= new ODatabaseForm( *this );
1442 osl_atomic_increment( &pClone
->m_refCount
);
1443 pClone
->clonedFrom( *this );
1444 osl_atomic_decrement( &pClone
->m_refCount
);
1449 void ODatabaseForm::fire( sal_Int32
* pnHandles
, const Any
* pNewValues
, const Any
* pOldValues
, sal_Int32 nCount
, bool bVetoable
)
1451 // same as in getFastPropertyValue(sal_Int32) : if we're resetting currently don't fire any changes of the
1452 // IsModified property from sal_False to sal_True, as this is only temporary 'til the reset is done
1453 if (m_nResetsPending
> 0)
1455 // look for the PROPERTY_ID_ISMODIFIED
1457 for (nPos
=0; nPos
<nCount
; ++nPos
)
1458 if (pnHandles
[nPos
] == PROPERTY_ID_ISMODIFIED
)
1461 if ((nPos
< nCount
) && (pNewValues
[nPos
].getValueType().getTypeClass() == TypeClass_BOOLEAN
) && getBOOL(pNewValues
[nPos
]))
1462 { // yeah, we found it, and it changed to TRUE
1464 { // just cut the first element
1470 else if (nPos
== nCount
- 1)
1471 // just cut the last element
1474 { // split into two base class calls
1475 OPropertySetAggregationHelper::fire(pnHandles
, pNewValues
, pOldValues
, nPos
, bVetoable
);
1477 OPropertySetAggregationHelper::fire(pnHandles
+ nPos
, pNewValues
+ nPos
, pOldValues
+ nPos
, nCount
- nPos
, bVetoable
);
1483 OPropertySetAggregationHelper::fire(pnHandles
, pNewValues
, pOldValues
, nCount
, bVetoable
);
1487 Any SAL_CALL
ODatabaseForm::getFastPropertyValue( sal_Int32 nHandle
)
1488 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
, std::exception
)
1490 if ((nHandle
== PROPERTY_ID_ISMODIFIED
) && (m_nResetsPending
> 0))
1491 return css::uno::Any(false);
1492 // don't allow the aggregate which is currently being reset to return a (temporary) "yes"
1494 return OPropertySetAggregationHelper::getFastPropertyValue(nHandle
);
1498 void ODatabaseForm::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
1502 case PROPERTY_ID_INSERTONLY
:
1503 rValue
<<= m_bInsertOnly
;
1506 case PROPERTY_ID_FILTER
:
1507 rValue
<<= m_aFilterManager
.getFilterComponent( FilterManager::fcPublicFilter
);
1510 case PROPERTY_ID_APPLYFILTER
:
1511 rValue
<<= m_aFilterManager
.isApplyPublicFilter();
1514 case PROPERTY_ID_DATASOURCE
:
1515 rValue
= m_xAggregateSet
->getPropertyValue( PROPERTY_DATASOURCE
);
1518 case PROPERTY_ID_TARGET_URL
:
1519 rValue
<<= m_aTargetURL
;
1521 case PROPERTY_ID_TARGET_FRAME
:
1522 rValue
<<= m_aTargetFrame
;
1524 case PROPERTY_ID_SUBMIT_METHOD
:
1525 rValue
<<= m_eSubmitMethod
;
1527 case PROPERTY_ID_SUBMIT_ENCODING
:
1528 rValue
<<= m_eSubmitEncoding
;
1530 case PROPERTY_ID_NAME
:
1533 case PROPERTY_ID_MASTERFIELDS
:
1534 rValue
<<= m_aMasterFields
;
1536 case PROPERTY_ID_DETAILFIELDS
:
1537 rValue
<<= m_aDetailFields
;
1539 case PROPERTY_ID_CYCLE
:
1542 case PROPERTY_ID_NAVIGATION
:
1543 rValue
<<= m_eNavigation
;
1545 case PROPERTY_ID_ALLOWADDITIONS
:
1546 rValue
<<= m_bAllowInsert
;
1548 case PROPERTY_ID_ALLOWEDITS
:
1549 rValue
<<= m_bAllowUpdate
;
1551 case PROPERTY_ID_ALLOWDELETIONS
:
1552 rValue
<<= m_bAllowDelete
;
1554 case PROPERTY_ID_PRIVILEGES
:
1555 rValue
<<= (sal_Int32
)m_nPrivileges
;
1557 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1558 rValue
= m_aDynamicControlBorder
;
1560 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1561 rValue
= m_aControlBorderColorFocus
;
1563 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1564 rValue
= m_aControlBorderColorMouse
;
1566 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1567 rValue
= m_aControlBorderColorInvalid
;
1570 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( nHandle
) )
1571 m_aPropertyBagHelper
.getDynamicFastPropertyValue( nHandle
, rValue
);
1573 OPropertySetAggregationHelper::getFastPropertyValue( rValue
, nHandle
);
1579 sal_Bool
ODatabaseForm::convertFastPropertyValue( Any
& rConvertedValue
, Any
& rOldValue
,
1580 sal_Int32 nHandle
, const Any
& rValue
) throw( IllegalArgumentException
)
1582 bool bModified(false);
1585 case PROPERTY_ID_INSERTONLY
:
1586 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_bInsertOnly
);
1589 case PROPERTY_ID_FILTER
:
1590 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aFilterManager
.getFilterComponent( FilterManager::fcPublicFilter
) );
1593 case PROPERTY_ID_APPLYFILTER
:
1594 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aFilterManager
.isApplyPublicFilter() );
1597 case PROPERTY_ID_DATASOURCE
:
1599 Any aAggregateProperty
;
1600 getFastPropertyValue(aAggregateProperty
, PROPERTY_ID_DATASOURCE
);
1601 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, aAggregateProperty
, cppu::UnoType
<OUString
>::get());
1604 case PROPERTY_ID_TARGET_URL
:
1605 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aTargetURL
);
1607 case PROPERTY_ID_TARGET_FRAME
:
1608 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aTargetFrame
);
1610 case PROPERTY_ID_SUBMIT_METHOD
:
1611 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_eSubmitMethod
);
1613 case PROPERTY_ID_SUBMIT_ENCODING
:
1614 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_eSubmitEncoding
);
1616 case PROPERTY_ID_NAME
:
1617 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_sName
);
1619 case PROPERTY_ID_MASTERFIELDS
:
1620 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aMasterFields
);
1622 case PROPERTY_ID_DETAILFIELDS
:
1623 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aDetailFields
);
1625 case PROPERTY_ID_CYCLE
:
1626 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aCycle
, cppu::UnoType
<TabulatorCycle
>::get());
1628 case PROPERTY_ID_NAVIGATION
:
1629 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_eNavigation
);
1631 case PROPERTY_ID_ALLOWADDITIONS
:
1632 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bAllowInsert
);
1634 case PROPERTY_ID_ALLOWEDITS
:
1635 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bAllowUpdate
);
1637 case PROPERTY_ID_ALLOWDELETIONS
:
1638 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bAllowDelete
);
1640 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1641 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aDynamicControlBorder
, cppu::UnoType
<bool>::get() );
1643 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1644 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aControlBorderColorFocus
, cppu::UnoType
<sal_Int32
>::get() );
1646 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1647 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aControlBorderColorMouse
, cppu::UnoType
<sal_Int32
>::get() );
1649 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1650 bModified
= tryPropertyValue( rConvertedValue
, rOldValue
, rValue
, m_aControlBorderColorInvalid
, cppu::UnoType
<sal_Int32
>::get() );
1653 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle ( nHandle
) )
1654 bModified
= m_aPropertyBagHelper
.convertDynamicFastPropertyValue( nHandle
, rValue
, rConvertedValue
, rOldValue
);
1656 bModified
= OPropertySetAggregationHelper::convertFastPropertyValue( rConvertedValue
, rOldValue
, nHandle
, rValue
);
1663 void ODatabaseForm::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw( Exception
, std::exception
)
1667 case PROPERTY_ID_INSERTONLY
:
1668 rValue
>>= m_bInsertOnly
;
1669 if ( m_aIgnoreResult
.hasValue() )
1670 m_aIgnoreResult
<<= m_bInsertOnly
;
1672 m_xAggregateSet
->setPropertyValue( PROPERTY_INSERTONLY
, makeAny( m_bInsertOnly
) );
1675 case PROPERTY_ID_FILTER
:
1677 OUString sNewFilter
;
1678 rValue
>>= sNewFilter
;
1679 m_aFilterManager
.setFilterComponent( FilterManager::fcPublicFilter
, sNewFilter
);
1683 case PROPERTY_ID_APPLYFILTER
:
1687 m_aFilterManager
.setApplyPublicFilter( bApply
);
1691 case PROPERTY_ID_DATASOURCE
:
1693 Reference
< XConnection
> xSomeConnection
;
1694 if ( ::dbtools::isEmbeddedInDatabase( getParent(), xSomeConnection
) )
1695 throw PropertyVetoException();
1699 m_xAggregateSet
->setPropertyValue(PROPERTY_DATASOURCE
, rValue
);
1701 catch(const Exception
&)
1706 case PROPERTY_ID_TARGET_URL
:
1707 rValue
>>= m_aTargetURL
;
1709 case PROPERTY_ID_TARGET_FRAME
:
1710 rValue
>>= m_aTargetFrame
;
1712 case PROPERTY_ID_SUBMIT_METHOD
:
1713 rValue
>>= m_eSubmitMethod
;
1715 case PROPERTY_ID_SUBMIT_ENCODING
:
1716 rValue
>>= m_eSubmitEncoding
;
1718 case PROPERTY_ID_NAME
:
1721 case PROPERTY_ID_MASTERFIELDS
:
1722 rValue
>>= m_aMasterFields
;
1723 invlidateParameters();
1725 case PROPERTY_ID_DETAILFIELDS
:
1726 rValue
>>= m_aDetailFields
;
1727 invlidateParameters();
1729 case PROPERTY_ID_CYCLE
:
1732 case PROPERTY_ID_NAVIGATION
:
1733 rValue
>>= m_eNavigation
;
1735 case PROPERTY_ID_ALLOWADDITIONS
:
1736 m_bAllowInsert
= getBOOL(rValue
);
1738 case PROPERTY_ID_ALLOWEDITS
:
1739 m_bAllowUpdate
= getBOOL(rValue
);
1741 case PROPERTY_ID_ALLOWDELETIONS
:
1742 m_bAllowDelete
= getBOOL(rValue
);
1744 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1745 m_aDynamicControlBorder
= rValue
;
1747 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1748 m_aControlBorderColorFocus
= rValue
;
1750 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1751 m_aControlBorderColorMouse
= rValue
;
1753 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1754 m_aControlBorderColorInvalid
= rValue
;
1757 case PROPERTY_ID_ACTIVE_CONNECTION
:
1759 Reference
< XConnection
> xOuterConnection
;
1760 if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection
) )
1762 if ( xOuterConnection
!= Reference
< XConnection
>( rValue
, UNO_QUERY
) )
1763 // somebody's trying to set a connection which is not equal the connection
1764 // implied by the database we're embedded in
1765 throw PropertyVetoException();
1767 OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle
, rValue
);
1772 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( nHandle
) )
1773 m_aPropertyBagHelper
.setDynamicFastPropertyValue( nHandle
, rValue
);
1775 OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle
, rValue
);
1781 void ODatabaseForm::forwardingPropertyValue( sal_Int32 _nHandle
)
1783 OSL_ENSURE( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
, "ODatabaseForm::forwardingPropertyValue: unexpected property!" );
1784 if ( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
)
1786 if ( m_bSharingConnection
)
1787 stopSharingConnection( );
1788 m_bForwardingConnection
= true;
1793 void ODatabaseForm::forwardedPropertyValue( sal_Int32 _nHandle
)
1795 OSL_ENSURE( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
, "ODatabaseForm::forwardedPropertyValue: unexpected property!" );
1796 if ( _nHandle
== PROPERTY_ID_ACTIVE_CONNECTION
)
1798 m_bForwardingConnection
= false;
1803 // com::sun::star::beans::XPropertyState
1805 PropertyState
ODatabaseForm::getPropertyStateByHandle(sal_Int32 nHandle
)
1807 PropertyState eState
;
1810 case PROPERTY_ID_NAVIGATION
:
1811 return (NavigationBarMode_CURRENT
== m_eNavigation
) ? PropertyState_DEFAULT_VALUE
: PropertyState_DIRECT_VALUE
;
1813 case PROPERTY_ID_CYCLE
:
1814 eState
= m_aCycle
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1817 case PROPERTY_ID_INSERTONLY
:
1818 eState
= m_bInsertOnly
? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1821 case PROPERTY_ID_FILTER
:
1822 if ( m_aFilterManager
.getFilterComponent( FilterManager::fcPublicFilter
).isEmpty() )
1823 eState
= PropertyState_DEFAULT_VALUE
;
1825 eState
= PropertyState_DIRECT_VALUE
;
1828 case PROPERTY_ID_APPLYFILTER
:
1829 eState
= m_aFilterManager
.isApplyPublicFilter() ? PropertyState_DEFAULT_VALUE
: PropertyState_DIRECT_VALUE
;
1832 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1833 eState
= m_aDynamicControlBorder
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1836 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1837 eState
= m_aControlBorderColorFocus
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1840 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1841 eState
= m_aControlBorderColorMouse
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1844 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1845 eState
= m_aControlBorderColorInvalid
.hasValue() ? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1849 eState
= OPropertySetAggregationHelper::getPropertyStateByHandle(nHandle
);
1855 void ODatabaseForm::setPropertyToDefaultByHandle(sal_Int32 nHandle
)
1859 case PROPERTY_ID_INSERTONLY
:
1860 case PROPERTY_ID_FILTER
:
1861 case PROPERTY_ID_APPLYFILTER
:
1862 case PROPERTY_ID_NAVIGATION
:
1863 case PROPERTY_ID_CYCLE
:
1864 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1865 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1866 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1867 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1868 setFastPropertyValue( nHandle
, getPropertyDefaultByHandle( nHandle
) );
1872 OPropertySetAggregationHelper::setPropertyToDefaultByHandle(nHandle
);
1877 Any
ODatabaseForm::getPropertyDefaultByHandle( sal_Int32 nHandle
) const
1882 case PROPERTY_ID_INSERTONLY
:
1883 case PROPERTY_ID_DYNAMIC_CONTROL_BORDER
:
1884 aReturn
<<= sal_False
;
1887 case PROPERTY_ID_FILTER
:
1888 aReturn
<<= OUString();
1891 case PROPERTY_ID_APPLYFILTER
:
1892 aReturn
<<= sal_True
;
1895 case PROPERTY_ID_NAVIGATION
:
1896 aReturn
= makeAny(NavigationBarMode_CURRENT
);
1899 case PROPERTY_ID_CYCLE
:
1900 case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS
:
1901 case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE
:
1902 case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID
:
1906 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( nHandle
) )
1907 m_aPropertyBagHelper
.getDynamicPropertyDefaultByHandle( nHandle
, aReturn
);
1909 aReturn
= OPropertySetAggregationHelper::getPropertyDefaultByHandle( nHandle
);
1916 // com::sun::star::form::XReset
1918 void SAL_CALL
ODatabaseForm::reset() throw( RuntimeException
, std::exception
)
1920 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
1924 ::osl::MutexGuard
aResetGuard(m_aResetSafety
);
1930 if ( !m_aResetListeners
.empty() )
1932 ::osl::MutexGuard
aResetGuard(m_aResetSafety
);
1934 // create an own thread if we have (approve-)reset-listeners (so the listeners can't do that much damage
1935 // to this thread which is probably the main one)
1938 m_pThread
= new OFormSubmitResetThread(this);
1939 m_pThread
->acquire();
1940 m_pThread
->create();
1943 m_pThread
->addEvent(&aEvt
, false);
1947 // direct call without any approving by the listeners
1950 ::osl::MutexGuard
aResetGuard(m_aResetSafety
);
1957 void ODatabaseForm::reset_impl(bool _bAproveByListeners
)
1959 if ( _bAproveByListeners
)
1960 if ( !m_aResetListeners
.approveReset() )
1963 ::osl::ResettableMutexGuard
aResetGuard(m_aResetSafety
);
1964 // do we have a database connected form and stay on the insert row
1965 bool bInsertRow
= false;
1966 if (m_xAggregateSet
.is())
1967 bInsertRow
= getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ISNEW
));
1972 // Iterate through all columns and set the default value
1973 Reference
< XColumnsSupplier
> xColsSuppl( m_xAggregateSet
, UNO_QUERY
);
1974 Reference
< XIndexAccess
> xIndexCols( xColsSuppl
->getColumns(), UNO_QUERY
);
1975 for (sal_Int32 i
= 0; i
< xIndexCols
->getCount(); ++i
)
1977 Reference
< XPropertySet
> xColProps
;
1978 xIndexCols
->getByIndex(i
) >>= xColProps
;
1980 Reference
< XColumnUpdate
> xColUpdate( xColProps
, UNO_QUERY
);
1981 if ( !xColUpdate
.is() )
1984 Reference
< XPropertySetInfo
> xPSI
;
1985 if ( xColProps
.is() )
1986 xPSI
= xColProps
->getPropertySetInfo( );
1988 static const char PROPERTY_CONTROLDEFAULT
[] = "ControlDefault";
1989 if ( xPSI
.is() && xPSI
->hasPropertyByName( PROPERTY_CONTROLDEFAULT
) )
1991 Any aDefault
= xColProps
->getPropertyValue( PROPERTY_CONTROLDEFAULT
);
1993 bool bReadOnly
= false;
1994 if ( xPSI
->hasPropertyByName( PROPERTY_ISREADONLY
) )
1995 xColProps
->getPropertyValue( PROPERTY_ISREADONLY
) >>= bReadOnly
;
2001 if ( aDefault
.hasValue() )
2002 xColUpdate
->updateObject( aDefault
);
2004 catch(const Exception
&)
2006 DBG_UNHANDLED_EXCEPTION();
2012 catch(const Exception
&)
2018 Reference
< XColumnsSupplier
> xParentColSupp( m_xParent
, UNO_QUERY
);
2019 Reference
< XNameAccess
> xParentCols
;
2020 if ( xParentColSupp
.is() )
2021 xParentCols
= xParentColSupp
->getColumns();
2023 if ( xParentCols
.is() && xParentCols
->hasElements() && m_aMasterFields
.getLength() )
2027 // analyze our parameters
2028 if ( !m_aParameterManager
.isUpToDate() )
2029 updateParameterInfo();
2031 m_aParameterManager
.resetParameterValues( );
2033 catch(const Exception
&)
2035 OSL_FAIL("ODatabaseForm::reset_impl: could not initialize the master-detail-driven parameters!");
2041 aResetGuard
.clear();
2042 // iterate through all components. don't use an XIndexAccess as this will cause massive
2043 // problems with the count.
2044 Reference
<XEnumeration
> xIter
= createEnumeration();
2045 while (xIter
->hasMoreElements())
2047 Reference
<XReset
> xReset
;
2048 xIter
->nextElement() >>= xReset
;
2051 // TODO: all reset-methods have to be thread-safe
2056 aResetGuard
.reset();
2057 // ensure that the row isn't modified
2058 // (do this _before_ the listeners are notified ! their reaction (maybe asynchronous) may depend
2059 // on the modified state of the row)
2061 m_xAggregateSet
->setPropertyValue(PROPERTY_ISMODIFIED
, css::uno::Any(false));
2063 aResetGuard
.clear();
2065 m_aResetListeners
.resetted();
2068 aResetGuard
.reset();
2069 // and again : ensure the row isn't modified
2070 // we already did this after we (and maybe our dependents) resetted the values, but the listeners may have changed the row, too
2072 m_xAggregateSet
->setPropertyValue(PROPERTY_ISMODIFIED
, css::uno::Any(false));
2078 void SAL_CALL
ODatabaseForm::addResetListener(const Reference
<XResetListener
>& _rListener
) throw( RuntimeException
, std::exception
)
2080 m_aResetListeners
.addTypedListener( _rListener
);
2084 void SAL_CALL
ODatabaseForm::removeResetListener(const Reference
<XResetListener
>& _rListener
) throw( RuntimeException
, std::exception
)
2086 m_aResetListeners
.removeTypedListener( _rListener
);
2090 // com::sun::star::form::XSubmit
2092 void SAL_CALL
ODatabaseForm::submit( const Reference
<XControl
>& Control
,
2093 const ::com::sun::star::awt::MouseEvent
& MouseEvt
) throw( RuntimeException
, std::exception
)
2096 ::osl::MutexGuard
aGuard(m_aMutex
);
2097 // Do we have controls and a Submit URL?
2098 if( !getCount() || m_aTargetURL
.isEmpty() )
2102 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
2103 if (m_aSubmitListeners
.getLength())
2105 // create an own thread if we have (approve-)submit-listeners (so the listeners can't do that much damage
2106 // to this thread which is probably the main one)
2109 m_pThread
= new OFormSubmitResetThread(this);
2110 m_pThread
->acquire();
2111 m_pThread
->create();
2113 m_pThread
->addEvent(&MouseEvt
, Control
, true);
2117 // direct call without any approving by the listeners
2119 submit_impl( Control
, MouseEvt
, true );
2123 void lcl_dispatch(const Reference
< XFrame
>& xFrame
,const Reference
<XURLTransformer
>& xTransformer
,const OUString
& aURLStr
,const OUString
& aReferer
,const OUString
& aTargetName
2124 ,const OUString
& aData
,rtl_TextEncoding _eEncoding
)
2127 aURL
.Complete
= aURLStr
;
2128 xTransformer
->parseStrict(aURL
);
2130 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aURL
, aTargetName
,
2131 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
| FrameSearchFlag::CHILDREN
|
2132 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
| FrameSearchFlag::TASKS
);
2136 Sequence
<PropertyValue
> aArgs(2);
2137 aArgs
.getArray()[0].Name
= "Referer";
2138 aArgs
.getArray()[0].Value
<<= aReferer
;
2140 // build a sequence from the to-be-submitted string
2141 OString
a8BitData(OUStringToOString(aData
, _eEncoding
));
2142 // always ANSI #58641
2143 Sequence
< sal_Int8
> aPostData(reinterpret_cast<const sal_Int8
*>(a8BitData
.getStr()), a8BitData
.getLength());
2144 Reference
< XInputStream
> xPostData
= new SequenceInputStream(aPostData
);
2146 aArgs
.getArray()[1].Name
= "PostData";
2147 aArgs
.getArray()[1].Value
<<= xPostData
;
2149 xDisp
->dispatch(aURL
, aArgs
);
2150 } // if (xDisp.is())
2153 void ODatabaseForm::submit_impl(const Reference
<XControl
>& Control
, const ::com::sun::star::awt::MouseEvent
& MouseEvt
, bool _bAproveByListeners
)
2156 if (_bAproveByListeners
)
2158 ::cppu::OInterfaceIteratorHelper
aIter(m_aSubmitListeners
);
2159 EventObject
aEvt(static_cast<XWeak
*>(this));
2160 bool bCanceled
= false;
2161 while (aIter
.hasMoreElements() && !bCanceled
)
2163 if (!static_cast<XSubmitListener
*>(aIter
.next())->approveSubmit(aEvt
))
2171 FormSubmitEncoding eSubmitEncoding
;
2172 FormSubmitMethod eSubmitMethod
;
2175 OUString aTargetName
;
2176 Reference
< XModel
> xModel
;
2178 SolarMutexGuard aGuard
;
2181 Reference
<XChild
> xParent(m_xParent
, UNO_QUERY
);
2184 xModel
= getXModel(xParent
->getParent());
2187 aReferer
= xModel
->getURL();
2190 aTargetName
= m_aTargetFrame
;
2192 eSubmitEncoding
= m_eSubmitEncoding
;
2193 eSubmitMethod
= m_eSubmitMethod
;
2194 aURLStr
= m_aTargetURL
;
2199 Reference
< XFrame
> xFrame
= xModel
->getCurrentController()->getFrame();
2203 Reference
<XURLTransformer
> xTransformer(URLTransformer::create(m_xContext
));
2206 if( eSubmitEncoding
== FormSubmitEncoding_URL
)
2210 SolarMutexGuard aGuard
;
2211 aData
= GetDataURLEncoded( Control
, MouseEvt
);
2216 if( eSubmitMethod
== FormSubmitMethod_GET
)
2218 INetURLObject
aUrlObj( aURLStr
, INetURLObject::WAS_ENCODED
);
2219 aUrlObj
.SetParam( aData
, INetURLObject::ENCODE_ALL
);
2220 aURL
.Complete
= aUrlObj
.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS
);
2221 if (xTransformer
.is())
2222 xTransformer
->parseStrict(aURL
);
2224 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aURL
, aTargetName
,
2225 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
| FrameSearchFlag::CHILDREN
|
2226 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
| FrameSearchFlag::TASKS
);
2230 Sequence
<PropertyValue
> aArgs(1);
2231 aArgs
.getArray()->Name
= "Referer";
2232 aArgs
.getArray()->Value
<<= aReferer
;
2233 xDisp
->dispatch(aURL
, aArgs
);
2237 else if( eSubmitMethod
== FormSubmitMethod_POST
)
2239 lcl_dispatch(xFrame
,xTransformer
,aURLStr
,aReferer
,aTargetName
,aData
,RTL_TEXTENCODING_MS_1252
);
2242 else if( eSubmitEncoding
== FormSubmitEncoding_MULTIPART
)
2245 aURL
.Complete
= aURLStr
;
2246 xTransformer
->parseStrict(aURL
);
2248 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aURL
, aTargetName
,
2249 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
| FrameSearchFlag::CHILDREN
|
2250 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
| FrameSearchFlag::TASKS
);
2254 OUString aContentType
;
2255 Sequence
<sal_Int8
> aData
;
2257 SolarMutexGuard aGuard
;
2258 aData
= GetDataMultiPartEncoded(Control
, MouseEvt
, aContentType
);
2260 if (!aData
.getLength())
2263 Sequence
<PropertyValue
> aArgs(3);
2264 aArgs
.getArray()[0].Name
= "Referer";
2265 aArgs
.getArray()[0].Value
<<= aReferer
;
2266 aArgs
.getArray()[1].Name
= "ContentType";
2267 aArgs
.getArray()[1].Value
<<= aContentType
;
2269 // build a sequence from the to-be-submitted string
2270 Reference
< XInputStream
> xPostData
= new SequenceInputStream(aData
);
2272 aArgs
.getArray()[2].Name
= "PostData";
2273 aArgs
.getArray()[2].Value
<<= xPostData
;
2275 xDisp
->dispatch(aURL
, aArgs
);
2278 else if( eSubmitEncoding
== FormSubmitEncoding_TEXT
)
2282 SolarMutexGuard aGuard
;
2283 aData
= GetDataTextEncoded( Reference
<XControl
> (), MouseEvt
);
2286 lcl_dispatch(xFrame
,xTransformer
,aURLStr
,aReferer
,aTargetName
,aData
,osl_getThreadTextEncoding());
2289 OSL_FAIL("ODatabaseForm::submit_Impl : wrong encoding !");
2296 void SAL_CALL
ODatabaseForm::addSubmitListener(const Reference
<XSubmitListener
>& _rListener
) throw( RuntimeException
, std::exception
)
2298 m_aSubmitListeners
.addInterface(_rListener
);
2302 void SAL_CALL
ODatabaseForm::removeSubmitListener(const Reference
<XSubmitListener
>& _rListener
) throw( RuntimeException
, std::exception
)
2304 m_aSubmitListeners
.removeInterface(_rListener
);
2308 // com::sun::star::sdbc::XSQLErrorBroadcaster
2310 void SAL_CALL
ODatabaseForm::addSQLErrorListener(const Reference
<XSQLErrorListener
>& _rListener
) throw( RuntimeException
, std::exception
)
2312 m_aErrorListeners
.addInterface(_rListener
);
2316 void SAL_CALL
ODatabaseForm::removeSQLErrorListener(const Reference
<XSQLErrorListener
>& _rListener
) throw( RuntimeException
, std::exception
)
2318 m_aErrorListeners
.removeInterface(_rListener
);
2322 void ODatabaseForm::invlidateParameters()
2324 ::osl::MutexGuard
aGuard(m_aMutex
);
2325 m_aParameterManager
.clearAllParameterInformation();
2331 void ODatabaseForm::_propertyChanged(const PropertyChangeEvent
& evt
) throw( RuntimeException
)
2333 if (evt
.PropertyName
== PROPERTY_ACTIVE_CONNECTION
&& !m_bForwardingConnection
)
2335 // the rowset changed its active connection itself (without interaction from our side), so
2336 // we need to fire this event, too
2337 sal_Int32 nHandle
= PROPERTY_ID_ACTIVE_CONNECTION
;
2338 fire(&nHandle
, &evt
.NewValue
, &evt
.OldValue
, 1, false);
2340 else // it was one of the statement relevant props
2342 // if the statement has changed we have to delete the parameter info
2343 invlidateParameters();
2350 void SAL_CALL
ODatabaseForm::setParent(const InterfaceRef
& Parent
) throw ( ::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
2352 // SYNCHRONIZED ----->
2353 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2355 Reference
<XForm
> xParentForm(getParent(), UNO_QUERY
);
2356 if (xParentForm
.is())
2360 Reference
< XRowSetApproveBroadcaster
> xParentApprBroadcast( xParentForm
, UNO_QUERY_THROW
);
2361 xParentApprBroadcast
->removeRowSetApproveListener( this );
2363 Reference
< XLoadable
> xParentLoadable( xParentForm
, UNO_QUERY_THROW
);
2364 xParentLoadable
->removeLoadListener( this );
2366 Reference
< XPropertySet
> xParentProperties( xParentForm
, UNO_QUERY_THROW
);
2367 xParentProperties
->removePropertyChangeListener( PROPERTY_ISNEW
, this );
2369 catch(const Exception
&)
2371 DBG_UNHANDLED_EXCEPTION();
2375 OFormComponents::setParent(Parent
);
2377 xParentForm
.set(getParent(), UNO_QUERY
);
2378 if ( xParentForm
.is() )
2382 Reference
< XRowSetApproveBroadcaster
> xParentApprBroadcast( xParentForm
, UNO_QUERY_THROW
);
2383 xParentApprBroadcast
->addRowSetApproveListener( this );
2385 Reference
< XLoadable
> xParentLoadable( xParentForm
, UNO_QUERY_THROW
);
2386 xParentLoadable
->addLoadListener( this );
2388 Reference
< XPropertySet
> xParentProperties( xParentForm
, UNO_QUERY_THROW
);
2389 xParentProperties
->addPropertyChangeListener( PROPERTY_ISNEW
, this );
2391 catch(const Exception
&)
2393 DBG_UNHANDLED_EXCEPTION();
2397 Reference
< XPropertySet
> xAggregateProperties( m_xAggregateSet
);
2399 // <----- SYNCHRONIZED
2401 Reference
< XConnection
> xOuterConnection
;
2402 bool bIsEmbedded
= ::dbtools::isEmbeddedInDatabase( Parent
, xOuterConnection
);
2405 xAggregateProperties
->setPropertyValue( PROPERTY_DATASOURCE
, makeAny( OUString() ) );
2409 // smartXTabControllerModel
2411 sal_Bool SAL_CALL
ODatabaseForm::getGroupControl() throw(com::sun::star::uno::RuntimeException
, std::exception
)
2413 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2415 // Should controls be combined into a TabOrder group?
2416 if (m_aCycle
.hasValue())
2418 sal_Int32 nCycle
= 0;
2419 ::cppu::enum2int(nCycle
, m_aCycle
);
2420 return nCycle
!= TabulatorCycle_PAGE
;
2423 if (isLoaded() && getConnection().is())
2430 void SAL_CALL
ODatabaseForm::setControlModels(const Sequence
<Reference
<XControlModel
> >& rControls
) throw( RuntimeException
, std::exception
)
2432 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2434 // Set TabIndex in the order of the sequence
2435 const Reference
<XControlModel
>* pControls
= rControls
.getConstArray();
2436 sal_Int32 nCount
= getCount();
2437 sal_Int32 nNewCount
= rControls
.getLength();
2439 // HiddenControls and forms are not listed
2440 if (nNewCount
<= nCount
)
2442 sal_Int16 nTabIndex
= 1;
2443 for (sal_Int32 i
=0; i
< nNewCount
; ++i
, ++pControls
)
2445 Reference
<XFormComponent
> xComp(*pControls
, UNO_QUERY
);
2448 // Find component in the list
2449 for (sal_Int32 j
= 0; j
< nCount
; ++j
)
2451 Reference
<XFormComponent
> xElement(
2452 getByIndex(j
), css::uno::UNO_QUERY
);
2453 if (xComp
== xElement
)
2455 Reference
<XPropertySet
> xSet(xComp
, UNO_QUERY
);
2456 if (xSet
.is() && hasProperty(PROPERTY_TABINDEX
, xSet
))
2457 xSet
->setPropertyValue( PROPERTY_TABINDEX
, makeAny(nTabIndex
++) );
2467 Sequence
<Reference
<XControlModel
> > SAL_CALL
ODatabaseForm::getControlModels() throw( RuntimeException
, std::exception
)
2469 ::osl::MutexGuard
aGuard(m_aMutex
);
2470 return m_pGroupManager
->getControlModels();
2474 void SAL_CALL
ODatabaseForm::setGroup( const Sequence
<Reference
<XControlModel
> >& _rGroup
, const OUString
& Name
) throw( RuntimeException
, std::exception
)
2476 ::osl::MutexGuard
aGuard(m_aMutex
);
2478 // The controls are grouped by adjusting their names to the name of the
2479 // first control of the sequence
2480 const Reference
<XControlModel
>* pControls
= _rGroup
.getConstArray();
2481 Reference
< XPropertySet
> xSet
;
2482 OUString
sGroupName( Name
);
2484 for( sal_Int32 i
=0; i
<_rGroup
.getLength(); ++i
, ++pControls
)
2486 xSet
.set(*pControls
, css::uno::UNO_QUERY
);
2489 // can't throw an exception other than a RuntimeException (which would not be appropriate),
2490 // so we ignore (and only assert) this
2491 OSL_FAIL( "ODatabaseForm::setGroup: invalid arguments!" );
2495 if (sGroupName
.isEmpty())
2496 xSet
->getPropertyValue(PROPERTY_NAME
) >>= sGroupName
;
2498 xSet
->setPropertyValue(PROPERTY_NAME
, makeAny(sGroupName
));
2503 sal_Int32 SAL_CALL
ODatabaseForm::getGroupCount() throw( RuntimeException
, std::exception
)
2505 ::osl::MutexGuard
aGuard(m_aMutex
);
2506 return m_pGroupManager
->getGroupCount();
2510 void SAL_CALL
ODatabaseForm::getGroup( sal_Int32 nGroup
, Sequence
<Reference
<XControlModel
> >& _rGroup
, OUString
& _rName
) throw( RuntimeException
, std::exception
)
2512 ::osl::MutexGuard
aGuard(m_aMutex
);
2516 if ((nGroup
< 0) || (nGroup
>= m_pGroupManager
->getGroupCount()))
2518 m_pGroupManager
->getGroup( nGroup
, _rGroup
, _rName
);
2522 void SAL_CALL
ODatabaseForm::getGroupByName(const OUString
& Name
, Sequence
< Reference
<XControlModel
> >& _rGroup
) throw( RuntimeException
, std::exception
)
2524 ::osl::MutexGuard
aGuard(m_aMutex
);
2526 m_pGroupManager
->getGroupByName( Name
, _rGroup
);
2530 // com::sun::star::lang::XEventListener
2532 void SAL_CALL
ODatabaseForm::disposing(const EventObject
& Source
) throw( RuntimeException
, std::exception
)
2534 // does the call come from the connection which we are sharing with our parent?
2535 if ( isSharingConnection() )
2537 Reference
< XConnection
> xConnSource( Source
.Source
, UNO_QUERY
);
2538 if ( xConnSource
.is() )
2540 #if OSL_DEBUG_LEVEL > 0
2541 Reference
< XConnection
> xActiveConn
;
2542 m_xAggregateSet
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xActiveConn
;
2543 OSL_ENSURE( xActiveConn
.get() == xConnSource
.get(), "ODatabaseForm::disposing: where did this come from?" );
2544 // there should be exactly one XConnection object we're listening at - our aggregate connection
2546 disposingSharedConnection( xConnSource
);
2550 OInterfaceContainer::disposing(Source
);
2552 // does the disposing come from the aggregate ?
2553 if (m_xAggregate
.is())
2554 { // no -> forward it
2555 com::sun::star::uno::Reference
<com::sun::star::lang::XEventListener
> xListener
;
2556 if (query_aggregation(m_xAggregate
, xListener
))
2557 xListener
->disposing(Source
);
2562 void ODatabaseForm::impl_createLoadTimer()
2564 OSL_PRECOND( m_pLoadTimer
== NULL
, "ODatabaseForm::impl_createLoadTimer: timer already exists!" );
2565 m_pLoadTimer
= new Timer();
2566 m_pLoadTimer
->SetTimeout(100);
2567 m_pLoadTimer
->SetTimeoutHdl(LINK(this,ODatabaseForm
,OnTimeout
));
2571 // com::sun::star::form::XLoadListener
2573 void SAL_CALL
ODatabaseForm::loaded(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
2576 ::osl::MutexGuard
aGuard( m_aMutex
);
2577 Reference
< XRowSet
> xParentRowSet( m_xParent
, UNO_QUERY_THROW
);
2578 xParentRowSet
->addRowSetListener( this );
2580 impl_createLoadTimer();
2587 void SAL_CALL
ODatabaseForm::unloading(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
2590 // now stop the rowset listening if we are a subform
2591 ::osl::MutexGuard
aGuard( m_aMutex
);
2593 if ( m_pLoadTimer
&& m_pLoadTimer
->IsActive() )
2594 m_pLoadTimer
->Stop();
2595 DELETEZ( m_pLoadTimer
);
2597 Reference
< XRowSet
> xParentRowSet( m_xParent
, UNO_QUERY_THROW
);
2598 xParentRowSet
->removeRowSetListener( this );
2605 void SAL_CALL
ODatabaseForm::unloaded(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
2611 void SAL_CALL
ODatabaseForm::reloading(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
2613 // now stop the rowset listening if we are a subform
2614 ::osl::MutexGuard
aGuard(m_aMutex
);
2615 Reference
<XRowSet
> xParentRowSet(m_xParent
, UNO_QUERY
);
2616 if (xParentRowSet
.is())
2617 xParentRowSet
->removeRowSetListener(this);
2619 if (m_pLoadTimer
&& m_pLoadTimer
->IsActive())
2620 m_pLoadTimer
->Stop();
2624 void SAL_CALL
ODatabaseForm::reloaded(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
2628 ::osl::MutexGuard
aGuard(m_aMutex
);
2629 Reference
<XRowSet
> xParentRowSet(m_xParent
, UNO_QUERY
);
2630 if (xParentRowSet
.is())
2631 xParentRowSet
->addRowSetListener(this);
2636 IMPL_LINK_NOARG_TYPED(ODatabaseForm
, OnTimeout
, Timer
*, void)
2642 // com::sun::star::form::XLoadable
2644 void SAL_CALL
ODatabaseForm::load() throw( RuntimeException
, std::exception
)
2650 bool ODatabaseForm::canShareConnection( const Reference
< XPropertySet
>& _rxParentProps
)
2652 // our own data source
2653 OUString sOwnDatasource
;
2654 m_xAggregateSet
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sOwnDatasource
;
2656 // our parents data source
2657 OUString sParentDataSource
;
2658 OSL_ENSURE( _rxParentProps
.is() && _rxParentProps
->getPropertySetInfo().is() && _rxParentProps
->getPropertySetInfo()->hasPropertyByName( PROPERTY_DATASOURCE
),
2659 "ODatabaseForm::doShareConnection: invalid parent form!" );
2660 if ( _rxParentProps
.is() )
2661 _rxParentProps
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sParentDataSource
;
2663 bool bCanShareConnection
= false;
2665 // both rowsets share are connected to the same data source
2666 if ( sParentDataSource
== sOwnDatasource
)
2668 if ( !sParentDataSource
.isEmpty() )
2669 // and it's really a data source name (not empty)
2670 bCanShareConnection
= true;
2672 { // the data source name is empty
2673 // -> ok for the URL
2674 OUString sParentURL
;
2676 _rxParentProps
->getPropertyValue( PROPERTY_URL
) >>= sParentURL
;
2677 m_xAggregateSet
->getPropertyValue( PROPERTY_URL
) >>= sMyURL
;
2679 bCanShareConnection
= (sParentURL
== sMyURL
);
2683 if ( bCanShareConnection
)
2685 // check for the user/password
2687 // take the user property on the rowset (if any) into account
2688 OUString sParentUser
, sParentPwd
;
2689 _rxParentProps
->getPropertyValue( PROPERTY_USER
) >>= sParentUser
;
2690 _rxParentProps
->getPropertyValue( PROPERTY_PASSWORD
) >>= sParentPwd
;
2692 OUString sMyUser
, sMyPwd
;
2693 m_xAggregateSet
->getPropertyValue( PROPERTY_USER
) >>= sMyUser
;
2694 m_xAggregateSet
->getPropertyValue( PROPERTY_PASSWORD
) >>= sMyPwd
;
2696 bCanShareConnection
=
2697 ( sParentUser
== sMyUser
)
2698 && ( sParentPwd
== sMyPwd
);
2701 return bCanShareConnection
;
2705 void ODatabaseForm::doShareConnection( const Reference
< XPropertySet
>& _rxParentProps
)
2707 // get the conneciton of the parent
2708 Reference
< XConnection
> xParentConn
;
2709 _rxParentProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xParentConn
;
2710 OSL_ENSURE( xParentConn
.is(), "ODatabaseForm::doShareConnection: we're a valid sub-form, but the parent has no connection?!" );
2712 if ( xParentConn
.is() )
2714 // add as dispose listener to the connection
2715 Reference
< XComponent
> xParentConnComp( xParentConn
, UNO_QUERY
);
2716 OSL_ENSURE( xParentConnComp
.is(), "ODatabaseForm::doShareConnection: invalid connection!" );
2717 xParentConnComp
->addEventListener( static_cast< XLoadListener
* >( this ) );
2719 // forward the connection to our own aggregate
2720 m_bForwardingConnection
= true;
2721 m_xAggregateSet
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( xParentConn
) );
2722 m_bForwardingConnection
= false;
2724 m_bSharingConnection
= true;
2727 m_bSharingConnection
= false;
2731 void ODatabaseForm::disposingSharedConnection( const Reference
< XConnection
>& /*_rxConn*/ )
2733 stopSharingConnection();
2735 // TODO: we could think about whether or not to re-connect.
2740 void ODatabaseForm::stopSharingConnection( )
2742 OSL_ENSURE( m_bSharingConnection
, "ODatabaseForm::stopSharingConnection: invalid call!" );
2744 if ( m_bSharingConnection
)
2746 // get the connection
2747 Reference
< XConnection
> xSharedConn
;
2748 m_xAggregateSet
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xSharedConn
;
2749 OSL_ENSURE( xSharedConn
.is(), "ODatabaseForm::stopSharingConnection: there's no conn!" );
2751 // remove ourself as event listener
2752 Reference
< XComponent
> xSharedConnComp( xSharedConn
, UNO_QUERY
);
2753 if ( xSharedConnComp
.is() )
2754 xSharedConnComp
->removeEventListener( static_cast< XLoadListener
* >( this ) );
2756 // no need to dispose the conn: we're not the owner, this is our parent
2757 // (in addition, this method may be called if the connection is being disposed while we use it)
2759 // reset the property
2760 xSharedConn
.clear();
2761 m_bForwardingConnection
= true;
2762 m_xAggregateSet
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( xSharedConn
) );
2763 m_bForwardingConnection
= false;
2766 m_bSharingConnection
= false;
2771 bool ODatabaseForm::implEnsureConnection()
2775 if ( getConnection( ).is() )
2776 // if our aggregate already has a connection, nothing needs to be done about it
2779 // see whether we're an embedded form
2780 Reference
< XConnection
> xOuterConnection
;
2781 if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection
) )
2783 m_xAggregateSet
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( xOuterConnection
) );
2784 return xOuterConnection
.is();
2787 m_bSharingConnection
= false;
2789 // if we're a sub form, we try to re-use the connection of our parent
2792 OSL_ENSURE( Reference
< XForm
>( getParent(), UNO_QUERY
).is(),
2793 "ODatabaseForm::implEnsureConnection: m_bSubForm is TRUE, but the parent is no form?" );
2795 Reference
< XPropertySet
> xParentProps( getParent(), UNO_QUERY
);
2797 // can we re-use (aka share) the connection of the parent?
2798 if ( canShareConnection( xParentProps
) )
2801 doShareConnection( xParentProps
);
2803 if ( m_bSharingConnection
)
2804 // yes -> outta here
2809 if (m_xAggregateSet
.is())
2811 Reference
< XConnection
> xConnection
= connectRowset(
2812 Reference
<XRowSet
> (m_xAggregate
, UNO_QUERY
),
2814 true // set a calculated connection as ActiveConnection
2816 return xConnection
.is();
2819 catch(const SQLException
& eDB
)
2821 onError(eDB
, FRM_RES_STRING(RID_STR_CONNECTERROR
));
2823 catch(const Exception
&)
2825 DBG_UNHANDLED_EXCEPTION();
2832 void ODatabaseForm::load_impl(bool bCausedByParentForm
, bool bMoveToFirst
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
) throw( RuntimeException
)
2834 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2836 // are we already loaded?
2840 m_bSubForm
= bCausedByParentForm
;
2842 // if we don't have a connection, we are not intended to be a database form or the aggregate was not able
2843 // to establish a connection
2844 bool bConnected
= implEnsureConnection();
2846 // we don't have to execute if we do not have a command to execute
2847 bool bExecute
= bConnected
&& m_xAggregateSet
.is() && !getString(m_xAggregateSet
->getPropertyValue(PROPERTY_COMMAND
)).isEmpty();
2849 // a database form always uses caching
2850 // we use starting fetchsize with at least 10 rows
2852 m_xAggregateSet
->setPropertyValue(PROPERTY_FETCHSIZE
, makeAny((sal_Int32
)40));
2854 // if we're loaded as sub form we got a "rowSetChanged" from the parent rowset _before_ we got the "loaded"
2855 // so we don't need to execute the statement again, this was already done
2856 // (and there were no relevant changes between these two listener calls, the "load" of a form is quite an
2857 // atomic operation.)
2859 bool bSuccess
= false;
2862 m_sCurrentErrorContext
= FRM_RES_STRING(RID_ERR_LOADING_FORM
);
2863 bSuccess
= executeRowSet(aGuard
, bMoveToFirst
, _rxCompletionHandler
);
2870 EventObject
aEvt(static_cast<XWeak
*>(this));
2871 m_aLoadListeners
.notifyEach( &XLoadListener::loaded
, aEvt
);
2873 // if we are on the insert row, we have to reset all controls
2874 // to set the default values
2875 if (bExecute
&& getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ISNEW
)))
2881 void SAL_CALL
ODatabaseForm::unload() throw( RuntimeException
, std::exception
)
2883 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2887 DELETEZ(m_pLoadTimer
);
2890 EventObject
aEvt(static_cast<XWeak
*>(this));
2891 m_aLoadListeners
.notifyEach( &XLoadListener::unloading
, aEvt
);
2893 if (m_xAggregateAsRowSet
.is())
2895 // we may have reset the InsertOnly property on the aggregate - restore it
2896 restoreInsertOnlyState( );
2898 // clear the parameters if there are any
2899 invlidateParameters();
2903 // close the aggregate
2904 Reference
<XCloseable
> xCloseable
;
2905 query_aggregation( m_xAggregate
, xCloseable
);
2907 if (xCloseable
.is())
2908 xCloseable
->close();
2910 catch(const SQLException
&)
2918 // if the connection we used while we were loaded is only shared with our parent, we
2920 if ( isSharingConnection() )
2921 stopSharingConnection();
2924 m_aLoadListeners
.notifyEach( &XLoadListener::unloaded
, aEvt
);
2928 void SAL_CALL
ODatabaseForm::reload() throw( RuntimeException
, std::exception
)
2934 void ODatabaseForm::reload_impl(bool bMoveToFirst
, const Reference
< XInteractionHandler
>& _rxCompletionHandler
) throw( RuntimeException
)
2936 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
2940 DocumentModifyGuard
aModifyGuard( *this );
2941 // ensures the document is not marked as "modified" just because we change some control's content during
2944 EventObject
aEvent(static_cast<XWeak
*>(this));
2946 // only if there is no approve listener we can post the event at this time
2947 // otherwise see approveRowsetChange
2948 // the aprrovement is done by the aggregate
2949 if (!m_aRowSetApproveListeners
.getLength())
2951 ::cppu::OInterfaceIteratorHelper
aIter(m_aLoadListeners
);
2954 while (aIter
.hasMoreElements())
2955 static_cast<XLoadListener
*>(aIter
.next())->reloading(aEvent
);
2961 bool bSuccess
= true;
2964 m_sCurrentErrorContext
= FRM_RES_STRING(RID_ERR_REFRESHING_FORM
);
2965 bSuccess
= executeRowSet(aGuard
, bMoveToFirst
, _rxCompletionHandler
);
2967 catch(const SQLException
&)
2969 OSL_FAIL("ODatabaseForm::reload_impl : shouldn't executeRowSet catch this exception?");
2974 ::cppu::OInterfaceIteratorHelper
aIter(m_aLoadListeners
);
2976 while (aIter
.hasMoreElements())
2977 static_cast<XLoadListener
*>(aIter
.next())->reloaded(aEvent
);
2979 // if we are on the insert row, we have to reset all controls
2980 // to set the default values
2981 if (getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ISNEW
)))
2989 sal_Bool SAL_CALL
ODatabaseForm::isLoaded() throw( RuntimeException
, std::exception
)
2995 void SAL_CALL
ODatabaseForm::addLoadListener(const Reference
<XLoadListener
>& aListener
) throw( RuntimeException
, std::exception
)
2997 m_aLoadListeners
.addInterface(aListener
);
3001 void SAL_CALL
ODatabaseForm::removeLoadListener(const Reference
<XLoadListener
>& aListener
) throw( RuntimeException
, std::exception
)
3003 m_aLoadListeners
.removeInterface(aListener
);
3007 // com::sun::star::sdbc::XCloseable
3008 void SAL_CALL
ODatabaseForm::close() throw( SQLException
, RuntimeException
, std::exception
)
3010 // unload will close the aggregate
3015 // com::sun::star::sdbc::XRowSetListener
3017 void SAL_CALL
ODatabaseForm::cursorMoved(const EventObject
& /*event*/) throw( RuntimeException
, std::exception
)
3019 // reload the subform with the new parameters of the parent
3020 // do this handling delayed to provide of execute too many SQL Statements
3021 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3023 DBG_ASSERT( m_pLoadTimer
, "ODatabaseForm::cursorMoved: how can this happen?!" );
3024 if ( !m_pLoadTimer
)
3025 impl_createLoadTimer();
3027 if ( m_pLoadTimer
->IsActive() )
3028 m_pLoadTimer
->Stop();
3030 // and start the timer again
3031 m_pLoadTimer
->Start();
3035 void SAL_CALL
ODatabaseForm::rowChanged(const EventObject
& /*event*/) throw( RuntimeException
, std::exception
)
3041 void SAL_CALL
ODatabaseForm::rowSetChanged(const EventObject
& /*event*/) throw( RuntimeException
, std::exception
)
3043 // not interested in :
3044 // if our parent is an ODatabaseForm, too, then after this rowSetChanged we'll get a "reloaded"
3045 // or a "loaded" event.
3046 // If somebody gave us another parent which is an XRowSet but doesn't handle an execute as
3047 // "load" respectively "reload" ... can't do anything ....
3051 bool ODatabaseForm::impl_approveRowChange_throw( const EventObject
& _rEvent
, const bool _bAllowSQLException
,
3052 ::osl::ClearableMutexGuard
& _rGuard
)
3054 ::cppu::OInterfaceIteratorHelper
aIter( m_aRowSetApproveListeners
);
3056 while ( aIter
.hasMoreElements() )
3058 Reference
< XRowSetApproveListener
> xListener( static_cast< XRowSetApproveListener
* >( aIter
.next() ) );
3059 if ( !xListener
.is() )
3064 if ( !xListener
->approveRowSetChange( _rEvent
) )
3067 catch (const DisposedException
& e
)
3069 if ( e
.Context
== xListener
)
3072 catch (const RuntimeException
&)
3076 catch (const SQLException
&)
3078 if ( _bAllowSQLException
)
3080 DBG_UNHANDLED_EXCEPTION();
3082 catch (const Exception
&)
3084 DBG_UNHANDLED_EXCEPTION();
3091 sal_Bool SAL_CALL
ODatabaseForm::approveCursorMove(const EventObject
& event
) throw( RuntimeException
, std::exception
)
3093 // is our aggregate calling?
3094 if (event
.Source
== InterfaceRef(static_cast<XWeak
*>(this)))
3096 // Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
3097 // for XRowSetApproveBroadcaster-interface.
3098 // So we have to multiplex this approve request.
3099 ::cppu::OInterfaceIteratorHelper
aIter( m_aRowSetApproveListeners
);
3100 while ( aIter
.hasMoreElements() )
3102 Reference
< XRowSetApproveListener
> xListener( static_cast< XRowSetApproveListener
* >( aIter
.next() ) );
3103 if ( !xListener
.is() )
3108 if ( !xListener
->approveCursorMove( event
) )
3111 catch (const DisposedException
& e
)
3113 if ( e
.Context
== xListener
)
3116 catch (const RuntimeException
&)
3120 catch (const Exception
&)
3122 DBG_UNHANDLED_EXCEPTION();
3129 // this is a call from our parent ...
3130 // a parent's cursor move will result in a re-execute of our own row-set, so we have to
3131 // ask our own RowSetChangesListeners, too
3132 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3133 if ( !impl_approveRowChange_throw( event
, false, aGuard
) )
3140 sal_Bool SAL_CALL
ODatabaseForm::approveRowChange(const RowChangeEvent
& event
) throw( RuntimeException
, std::exception
)
3142 // is our aggregate calling?
3143 if (event
.Source
== InterfaceRef(static_cast<XWeak
*>(this)))
3145 // Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
3146 // for XRowSetApproveBroadcaster-interface.
3147 // So we have to multiplex this approve request.
3148 ::cppu::OInterfaceIteratorHelper
aIter( m_aRowSetApproveListeners
);
3149 while ( aIter
.hasMoreElements() )
3151 Reference
< XRowSetApproveListener
> xListener( static_cast< XRowSetApproveListener
* >( aIter
.next() ) );
3152 if ( !xListener
.is() )
3157 if ( !xListener
->approveRowChange( event
) )
3160 catch (const DisposedException
& e
)
3162 if ( e
.Context
== xListener
)
3165 catch (const RuntimeException
&)
3169 catch (const Exception
&)
3171 DBG_UNHANDLED_EXCEPTION();
3180 sal_Bool SAL_CALL
ODatabaseForm::approveRowSetChange(const EventObject
& event
) throw( RuntimeException
, std::exception
)
3182 if (event
.Source
== InterfaceRef(static_cast<XWeak
*>(this))) // ignore our aggregate as we handle this approve ourself
3184 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3185 bool bWasLoaded
= isLoaded();
3186 if ( !impl_approveRowChange_throw( event
, false, aGuard
) )
3191 m_aLoadListeners
.notifyEach( &XLoadListener::reloading
, event
);
3196 // this is a call from our parent ...
3197 // a parent's cursor move will result in a re-execute of our own row-set, so we have to
3198 // ask our own RowSetChangesListeners, too
3199 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3200 if ( !impl_approveRowChange_throw( event
, false, aGuard
) )
3207 // com::sun::star::sdb::XRowSetApproveBroadcaster
3209 void SAL_CALL
ODatabaseForm::addRowSetApproveListener(const Reference
<XRowSetApproveListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3211 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3212 m_aRowSetApproveListeners
.addInterface(_rListener
);
3214 // do we have to multiplex ?
3215 if (m_aRowSetApproveListeners
.getLength() == 1)
3217 Reference
<XRowSetApproveBroadcaster
> xBroadcaster
;
3218 if (query_aggregation( m_xAggregate
, xBroadcaster
))
3220 Reference
<XRowSetApproveListener
> xListener((XRowSetApproveListener
*)this);
3221 xBroadcaster
->addRowSetApproveListener(xListener
);
3227 void SAL_CALL
ODatabaseForm::removeRowSetApproveListener(const Reference
<XRowSetApproveListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3229 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3230 // do we have to remove the multiplex ?
3231 m_aRowSetApproveListeners
.removeInterface(_rListener
);
3232 if ( m_aRowSetApproveListeners
.getLength() == 0 )
3234 Reference
<XRowSetApproveBroadcaster
> xBroadcaster
;
3235 if (query_aggregation( m_xAggregate
, xBroadcaster
))
3237 Reference
<XRowSetApproveListener
> xListener((XRowSetApproveListener
*)this);
3238 xBroadcaster
->removeRowSetApproveListener(xListener
);
3244 // com::sun:star::form::XDatabaseParameterBroadcaster
3246 void SAL_CALL
ODatabaseForm::addDatabaseParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3248 m_aParameterManager
.addParameterListener( _rListener
);
3251 void SAL_CALL
ODatabaseForm::removeDatabaseParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3253 m_aParameterManager
.removeParameterListener( _rListener
);
3257 void SAL_CALL
ODatabaseForm::addParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3259 ODatabaseForm::addDatabaseParameterListener( _rListener
);
3263 void SAL_CALL
ODatabaseForm::removeParameterListener(const Reference
<XDatabaseParameterListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3265 ODatabaseForm::removeDatabaseParameterListener( _rListener
);
3269 // com::sun::star::sdb::XCompletedExecution
3271 void SAL_CALL
ODatabaseForm::executeWithCompletion( const Reference
< XInteractionHandler
>& _rxHandler
) throw(SQLException
, RuntimeException
, std::exception
)
3273 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
3274 // the difference between execute and load is, that we position on the first row in case of load
3275 // after execute we remain before the first row
3279 load_impl(false, false, _rxHandler
);
3283 EventObject
event(static_cast< XWeak
* >(this));
3284 if ( !impl_approveRowChange_throw( event
, true, aGuard
) )
3287 // we're loaded and somebody want's to execute ourself -> this means a reload
3288 reload_impl(false, _rxHandler
);
3293 // com::sun::star::sdbc::XRowSet
3295 void SAL_CALL
ODatabaseForm::execute() throw( SQLException
, RuntimeException
, std::exception
)
3297 ::osl::ResettableMutexGuard
aGuard(m_aMutex
);
3298 // if somebody calls an execute and we're not loaded we reroute this call to our load method.
3300 // the difference between execute and load is, that we position on the first row in case of load
3301 // after execute we remain before the first row
3305 load_impl(false, false);
3309 EventObject
event(static_cast< XWeak
* >(this));
3310 if ( !impl_approveRowChange_throw( event
, true, aGuard
) )
3313 // we're loaded and somebody want's to execute ourself -> this means a reload
3319 void SAL_CALL
ODatabaseForm::addRowSetListener(const Reference
<XRowSetListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3321 if (m_xAggregateAsRowSet
.is())
3322 m_xAggregateAsRowSet
->addRowSetListener(_rListener
);
3326 void SAL_CALL
ODatabaseForm::removeRowSetListener(const Reference
<XRowSetListener
>& _rListener
) throw( RuntimeException
, std::exception
)
3328 if (m_xAggregateAsRowSet
.is())
3329 m_xAggregateAsRowSet
->removeRowSetListener(_rListener
);
3333 // com::sun::star::sdbc::XResultSet
3335 sal_Bool SAL_CALL
ODatabaseForm::next() throw( SQLException
, RuntimeException
, std::exception
)
3337 return m_xAggregateAsRowSet
->next();
3341 sal_Bool SAL_CALL
ODatabaseForm::isBeforeFirst() throw( SQLException
, RuntimeException
, std::exception
)
3343 return m_xAggregateAsRowSet
->isBeforeFirst();
3347 sal_Bool SAL_CALL
ODatabaseForm::isAfterLast() throw( SQLException
, RuntimeException
, std::exception
)
3349 return m_xAggregateAsRowSet
->isAfterLast();
3353 sal_Bool SAL_CALL
ODatabaseForm::isFirst() throw( SQLException
, RuntimeException
, std::exception
)
3355 return m_xAggregateAsRowSet
->isFirst();
3359 sal_Bool SAL_CALL
ODatabaseForm::isLast() throw( SQLException
, RuntimeException
, std::exception
)
3361 return m_xAggregateAsRowSet
->isLast();
3365 void SAL_CALL
ODatabaseForm::beforeFirst() throw( SQLException
, RuntimeException
, std::exception
)
3367 m_xAggregateAsRowSet
->beforeFirst();
3371 void SAL_CALL
ODatabaseForm::afterLast() throw( SQLException
, RuntimeException
, std::exception
)
3373 m_xAggregateAsRowSet
->afterLast();
3377 sal_Bool SAL_CALL
ODatabaseForm::first() throw( SQLException
, RuntimeException
, std::exception
)
3379 return m_xAggregateAsRowSet
->first();
3383 sal_Bool SAL_CALL
ODatabaseForm::last() throw( SQLException
, RuntimeException
, std::exception
)
3385 return m_xAggregateAsRowSet
->last();
3389 sal_Int32 SAL_CALL
ODatabaseForm::getRow() throw( SQLException
, RuntimeException
, std::exception
)
3391 return m_xAggregateAsRowSet
->getRow();
3395 sal_Bool SAL_CALL
ODatabaseForm::absolute(sal_Int32 row
) throw( SQLException
, RuntimeException
, std::exception
)
3397 return m_xAggregateAsRowSet
->absolute(row
);
3401 sal_Bool SAL_CALL
ODatabaseForm::relative(sal_Int32 rows
) throw( SQLException
, RuntimeException
, std::exception
)
3403 return m_xAggregateAsRowSet
->relative(rows
);
3407 sal_Bool SAL_CALL
ODatabaseForm::previous() throw( SQLException
, RuntimeException
, std::exception
)
3409 return m_xAggregateAsRowSet
->previous();
3413 void SAL_CALL
ODatabaseForm::refreshRow() throw( SQLException
, RuntimeException
, std::exception
)
3415 m_xAggregateAsRowSet
->refreshRow();
3419 sal_Bool SAL_CALL
ODatabaseForm::rowUpdated() throw( SQLException
, RuntimeException
, std::exception
)
3421 return m_xAggregateAsRowSet
->rowUpdated();
3425 sal_Bool SAL_CALL
ODatabaseForm::rowInserted() throw( SQLException
, RuntimeException
, std::exception
)
3427 return m_xAggregateAsRowSet
->rowInserted();
3431 sal_Bool SAL_CALL
ODatabaseForm::rowDeleted() throw( SQLException
, RuntimeException
, std::exception
)
3433 return m_xAggregateAsRowSet
->rowDeleted();
3437 InterfaceRef SAL_CALL
ODatabaseForm::getStatement() throw( SQLException
, RuntimeException
, std::exception
)
3439 return m_xAggregateAsRowSet
->getStatement();
3442 // com::sun::star::sdbc::XResultSetUpdate
3443 // exceptions during insert update and delete will be forwarded to the errorlistener
3445 void SAL_CALL
ODatabaseForm::insertRow() throw( SQLException
, RuntimeException
, std::exception
)
3449 Reference
<XResultSetUpdate
> xUpdate
;
3450 if (query_aggregation( m_xAggregate
, xUpdate
))
3451 xUpdate
->insertRow();
3453 catch(const RowSetVetoException
&)
3457 catch(const SQLException
& eDb
)
3459 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD
));
3465 void SAL_CALL
ODatabaseForm::updateRow() throw( SQLException
, RuntimeException
, std::exception
)
3469 Reference
<XResultSetUpdate
> xUpdate
;
3470 if (query_aggregation( m_xAggregate
, xUpdate
))
3471 xUpdate
->updateRow();
3473 catch(const RowSetVetoException
&)
3477 catch(const SQLException
& eDb
)
3479 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_UPDATERECORD
));
3485 void SAL_CALL
ODatabaseForm::deleteRow() throw( SQLException
, RuntimeException
, std::exception
)
3489 Reference
<XResultSetUpdate
> xUpdate
;
3490 if (query_aggregation( m_xAggregate
, xUpdate
))
3491 xUpdate
->deleteRow();
3493 catch(const RowSetVetoException
&)
3497 catch(const SQLException
& eDb
)
3499 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_DELETERECORD
));
3505 void SAL_CALL
ODatabaseForm::cancelRowUpdates() throw( SQLException
, RuntimeException
, std::exception
)
3509 Reference
<XResultSetUpdate
> xUpdate
;
3510 if (query_aggregation( m_xAggregate
, xUpdate
))
3511 xUpdate
->cancelRowUpdates();
3513 catch(const RowSetVetoException
&)
3517 catch(const SQLException
& eDb
)
3519 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD
));
3525 void SAL_CALL
ODatabaseForm::moveToInsertRow() throw( SQLException
, RuntimeException
, std::exception
)
3527 Reference
<XResultSetUpdate
> xUpdate
;
3528 if (query_aggregation( m_xAggregate
, xUpdate
))
3530 // _always_ move to the insert row
3532 // Formerly, the following line was conditioned with a "not is new", means we did not move the aggregate
3533 // to the insert row if it was already positioned there.
3535 // This prevented the RowSet implementation from resetting it's column values. We, ourself, formerly
3536 // did this reset of columns in reset_impl, where we set every column to the ControlDefault, or, if this
3537 // was not present, to NULL. However, the problem with setting to NULL was #88888#, the problem with
3538 // _not_ setting to NULL (which was the original fix for #88888#) was #97955#.
3541 // * move our aggregate to the insert row
3543 // - set the control defaults into the columns if not void
3544 // - do _not_ set the columns to NULL if no control default is set
3546 // Still, there is #72756#. During fixing this bug, DG introduced not calling the aggregate here. So
3547 // in theory, we re-introduced #72756#. But the bug described therein does not happen anymore, as the
3548 // preliminaries for it changed (no display of guessed values for new records with autoinc fields)
3550 // BTW: the public Issuezilla bug is #i2815#
3552 xUpdate
->moveToInsertRow();
3554 // then set the default values and the parameters given from the parent
3560 void SAL_CALL
ODatabaseForm::moveToCurrentRow() throw( SQLException
, RuntimeException
, std::exception
)
3562 Reference
<XResultSetUpdate
> xUpdate
;
3563 if (query_aggregation( m_xAggregate
, xUpdate
))
3564 xUpdate
->moveToCurrentRow();
3567 // com::sun::star::sdbcx::XDeleteRows
3569 Sequence
<sal_Int32
> SAL_CALL
ODatabaseForm::deleteRows(const Sequence
<Any
>& rows
) throw( SQLException
, RuntimeException
, std::exception
)
3573 Reference
<XDeleteRows
> xDelete
;
3574 if (query_aggregation( m_xAggregate
, xDelete
))
3575 return xDelete
->deleteRows(rows
);
3577 catch(const RowSetVetoException
&)
3581 catch(const SQLException
& eDb
)
3583 onError(eDb
, FRM_RES_STRING(RID_STR_ERR_DELETERECORDS
));
3587 return Sequence
< sal_Int32
>();
3590 // com::sun::star::sdbc::XParameters
3592 void SAL_CALL
ODatabaseForm::setNull(sal_Int32 parameterIndex
, sal_Int32 sqlType
) throw( SQLException
, RuntimeException
, std::exception
)
3594 m_aParameterManager
.setNull(parameterIndex
, sqlType
);
3598 void SAL_CALL
ODatabaseForm::setObjectNull(sal_Int32 parameterIndex
, sal_Int32 sqlType
, const OUString
& typeName
) throw( SQLException
, RuntimeException
, std::exception
)
3600 m_aParameterManager
.setObjectNull(parameterIndex
, sqlType
, typeName
);
3604 void SAL_CALL
ODatabaseForm::setBoolean(sal_Int32 parameterIndex
, sal_Bool x
) throw( SQLException
, RuntimeException
, std::exception
)
3606 m_aParameterManager
.setBoolean(parameterIndex
, x
);
3610 void SAL_CALL
ODatabaseForm::setByte(sal_Int32 parameterIndex
, sal_Int8 x
) throw( SQLException
, RuntimeException
, std::exception
)
3612 m_aParameterManager
.setByte(parameterIndex
, x
);
3616 void SAL_CALL
ODatabaseForm::setShort(sal_Int32 parameterIndex
, sal_Int16 x
) throw( SQLException
, RuntimeException
, std::exception
)
3618 m_aParameterManager
.setShort(parameterIndex
, x
);
3622 void SAL_CALL
ODatabaseForm::setInt(sal_Int32 parameterIndex
, sal_Int32 x
) throw( SQLException
, RuntimeException
, std::exception
)
3624 m_aParameterManager
.setInt(parameterIndex
, x
);
3628 void SAL_CALL
ODatabaseForm::setLong(sal_Int32 parameterIndex
, sal_Int64 x
) throw( SQLException
, RuntimeException
, std::exception
)
3630 m_aParameterManager
.setLong(parameterIndex
, x
);
3634 void SAL_CALL
ODatabaseForm::setFloat(sal_Int32 parameterIndex
, float x
) throw( SQLException
, RuntimeException
, std::exception
)
3636 m_aParameterManager
.setFloat(parameterIndex
, x
);
3640 void SAL_CALL
ODatabaseForm::setDouble(sal_Int32 parameterIndex
, double x
) throw( SQLException
, RuntimeException
, std::exception
)
3642 m_aParameterManager
.setDouble(parameterIndex
, x
);
3646 void SAL_CALL
ODatabaseForm::setString(sal_Int32 parameterIndex
, const OUString
& x
) throw( SQLException
, RuntimeException
, std::exception
)
3648 m_aParameterManager
.setString(parameterIndex
, x
);
3652 void SAL_CALL
ODatabaseForm::setBytes(sal_Int32 parameterIndex
, const Sequence
< sal_Int8
>& x
) throw( SQLException
, RuntimeException
, std::exception
)
3654 m_aParameterManager
.setBytes(parameterIndex
, x
);
3658 void SAL_CALL
ODatabaseForm::setDate(sal_Int32 parameterIndex
, const ::com::sun::star::util::Date
& x
) throw( SQLException
, RuntimeException
, std::exception
)
3660 m_aParameterManager
.setDate(parameterIndex
, x
);
3664 void SAL_CALL
ODatabaseForm::setTime(sal_Int32 parameterIndex
, const ::com::sun::star::util::Time
& x
) throw( SQLException
, RuntimeException
, std::exception
)
3666 m_aParameterManager
.setTime(parameterIndex
, x
);
3670 void SAL_CALL
ODatabaseForm::setTimestamp(sal_Int32 parameterIndex
, const ::com::sun::star::util::DateTime
& x
) throw( SQLException
, RuntimeException
, std::exception
)
3672 m_aParameterManager
.setTimestamp(parameterIndex
, x
);
3676 void SAL_CALL
ODatabaseForm::setBinaryStream(sal_Int32 parameterIndex
, const Reference
<XInputStream
>& x
, sal_Int32 length
) throw( SQLException
, RuntimeException
, std::exception
)
3678 m_aParameterManager
.setBinaryStream(parameterIndex
, x
, length
);
3682 void SAL_CALL
ODatabaseForm::setCharacterStream(sal_Int32 parameterIndex
, const Reference
<XInputStream
>& x
, sal_Int32 length
) throw( SQLException
, RuntimeException
, std::exception
)
3684 m_aParameterManager
.setCharacterStream(parameterIndex
, x
, length
);
3688 void SAL_CALL
ODatabaseForm::setObjectWithInfo(sal_Int32 parameterIndex
, const Any
& x
, sal_Int32 targetSqlType
, sal_Int32 scale
) throw( SQLException
, RuntimeException
, std::exception
)
3690 m_aParameterManager
.setObjectWithInfo(parameterIndex
, x
, targetSqlType
, scale
);
3694 void SAL_CALL
ODatabaseForm::setObject(sal_Int32 parameterIndex
, const Any
& x
) throw( SQLException
, RuntimeException
, std::exception
)
3696 m_aParameterManager
.setObject(parameterIndex
, x
);
3700 void SAL_CALL
ODatabaseForm::setRef(sal_Int32 parameterIndex
, const Reference
<XRef
>& x
) throw( SQLException
, RuntimeException
, std::exception
)
3702 m_aParameterManager
.setRef(parameterIndex
, x
);
3706 void SAL_CALL
ODatabaseForm::setBlob(sal_Int32 parameterIndex
, const Reference
<XBlob
>& x
) throw( SQLException
, RuntimeException
, std::exception
)
3708 m_aParameterManager
.setBlob(parameterIndex
, x
);
3712 void SAL_CALL
ODatabaseForm::setClob(sal_Int32 parameterIndex
, const Reference
<XClob
>& x
) throw( SQLException
, RuntimeException
, std::exception
)
3714 m_aParameterManager
.setClob(parameterIndex
, x
);
3718 void SAL_CALL
ODatabaseForm::setArray(sal_Int32 parameterIndex
, const Reference
<XArray
>& x
) throw( SQLException
, RuntimeException
, std::exception
)
3720 m_aParameterManager
.setArray(parameterIndex
, x
);
3724 void SAL_CALL
ODatabaseForm::clearParameters() throw( SQLException
, RuntimeException
, std::exception
)
3726 m_aParameterManager
.clearParameters();
3730 void SAL_CALL
ODatabaseForm::propertyChange( const PropertyChangeEvent
& evt
) throw (RuntimeException
, std::exception
)
3732 if ( evt
.Source
== m_xParent
)
3734 if ( evt
.PropertyName
== PROPERTY_ISNEW
)
3736 bool bCurrentIsNew( false );
3737 OSL_VERIFY( evt
.NewValue
>>= bCurrentIsNew
);
3738 if ( !bCurrentIsNew
)
3739 reload_impl( true );
3743 OFormComponents::propertyChange( evt
);
3746 // com::sun::star::lang::XServiceInfo
3748 OUString SAL_CALL
ODatabaseForm::getImplementationName_Static()
3750 return OUString( "com.sun.star.comp.forms.ODatabaseForm" );
3753 Sequence
< OUString
> SAL_CALL
ODatabaseForm::getSupportedServiceNames_Static()
3755 return css::uno::Sequence
<OUString
>{
3756 FRM_SUN_FORMCOMPONENT
, "com.sun.star.form.FormComponents",
3757 FRM_SUN_COMPONENT_FORM
, FRM_SUN_COMPONENT_HTMLFORM
,
3758 FRM_SUN_COMPONENT_DATAFORM
, FRM_COMPONENT_FORM
};
3762 OUString SAL_CALL
ODatabaseForm::getImplementationName() throw( RuntimeException
, std::exception
)
3764 return getImplementationName_Static();
3768 Sequence
< OUString
> SAL_CALL
ODatabaseForm::getSupportedServiceNames() throw( RuntimeException
, std::exception
)
3770 // the services of our aggregate
3771 Sequence
< OUString
> aServices
;
3772 Reference
< XServiceInfo
> xInfo
;
3773 if (query_aggregation(m_xAggregate
, xInfo
))
3774 aServices
= xInfo
->getSupportedServiceNames();
3776 // concat with out own services
3777 return ::comphelper::concatSequences(
3778 getSupportedServiceNames_Static(),
3783 sal_Bool SAL_CALL
ODatabaseForm::supportsService(const OUString
& ServiceName
) throw( RuntimeException
, std::exception
)
3785 return cppu::supportsService(this, ServiceName
);
3788 // com::sun::star::io::XPersistObject
3789 const sal_uInt16 CYCLE
= 0x0001;
3790 const sal_uInt16 DONTAPPLYFILTER
= 0x0002;
3792 OUString
ODatabaseForm::getServiceName() throw( RuntimeException
, std::exception
)
3794 return OUString(FRM_COMPONENT_FORM
); // old (non-sun) name for compatibility !
3797 void SAL_CALL
ODatabaseForm::write(const Reference
<XObjectOutputStream
>& _rxOutStream
) throw( IOException
, RuntimeException
, std::exception
)
3799 DBG_ASSERT(m_xAggregateSet
.is(), "ODatabaseForm::write : only to be called if the aggregate exists !");
3802 OFormComponents::write(_rxOutStream
);
3805 _rxOutStream
->writeShort(0x0003);
3808 _rxOutStream
<< m_sName
;
3810 OUString sDataSource
;
3811 if (m_xAggregateSet
.is())
3812 m_xAggregateSet
->getPropertyValue(PROPERTY_DATASOURCE
) >>= sDataSource
;
3813 _rxOutStream
<< sDataSource
;
3815 // former CursorSource
3817 if (m_xAggregateSet
.is())
3818 m_xAggregateSet
->getPropertyValue(PROPERTY_COMMAND
) >>= sCommand
;
3819 _rxOutStream
<< sCommand
;
3821 // former MasterFields
3822 _rxOutStream
<< m_aMasterFields
;
3823 // former DetailFields
3824 _rxOutStream
<< m_aDetailFields
;
3826 // former DataSelectionType
3827 DataSelectionType eTranslated
= DataSelectionType_TABLE
;
3828 if (m_xAggregateSet
.is())
3830 sal_Int32 nCommandType
= 0;
3831 m_xAggregateSet
->getPropertyValue(PROPERTY_COMMANDTYPE
) >>= nCommandType
;
3832 switch (nCommandType
)
3834 case CommandType::TABLE
: eTranslated
= DataSelectionType_TABLE
; break;
3835 case CommandType::QUERY
: eTranslated
= DataSelectionType_QUERY
; break;
3836 case CommandType::COMMAND
:
3838 bool bEscapeProcessing
= getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_ESCAPE_PROCESSING
));
3839 eTranslated
= bEscapeProcessing
? DataSelectionType_SQL
: DataSelectionType_SQLPASSTHROUGH
;
3842 default : OSL_FAIL("ODatabaseForm::write : wrong CommandType !");
3845 _rxOutStream
->writeShort((sal_Int16
)eTranslated
); // former DataSelectionType
3847 // very old versions expect a CursorType here
3848 _rxOutStream
->writeShort(DatabaseCursorType_KEYSET
);
3850 _rxOutStream
->writeBoolean(m_eNavigation
!= NavigationBarMode_NONE
);
3853 if (m_xAggregateSet
.is())
3854 _rxOutStream
->writeBoolean(getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_INSERTONLY
)));
3856 _rxOutStream
->writeBoolean(sal_False
);
3858 _rxOutStream
->writeBoolean(m_bAllowInsert
);
3859 _rxOutStream
->writeBoolean(m_bAllowUpdate
);
3860 _rxOutStream
->writeBoolean(m_bAllowDelete
);
3863 OUString sTmp
= INetURLObject::decode( m_aTargetURL
, INetURLObject::DECODE_UNAMBIGUOUS
);
3864 _rxOutStream
<< sTmp
;
3865 _rxOutStream
->writeShort( (sal_Int16
)m_eSubmitMethod
);
3866 _rxOutStream
->writeShort( (sal_Int16
)m_eSubmitEncoding
);
3867 _rxOutStream
<< m_aTargetFrame
;
3869 // version 2 didn't know some options and the "default" state
3870 sal_Int32 nCycle
= TabulatorCycle_RECORDS
;
3871 if (m_aCycle
.hasValue())
3873 ::cppu::enum2int(nCycle
, m_aCycle
);
3874 if (m_aCycle
== TabulatorCycle_PAGE
)
3875 // unknown in earlier versions
3876 nCycle
= TabulatorCycle_RECORDS
;
3878 _rxOutStream
->writeShort((sal_Int16
) nCycle
);
3880 _rxOutStream
->writeShort((sal_Int16
)m_eNavigation
);
3884 if (m_xAggregateSet
.is())
3886 m_xAggregateSet
->getPropertyValue(PROPERTY_FILTER
) >>= sFilter
;
3887 m_xAggregateSet
->getPropertyValue(PROPERTY_SORT
) >>= sOrder
;
3889 _rxOutStream
<< sFilter
;
3890 _rxOutStream
<< sOrder
;
3894 sal_uInt16 nAnyMask
= 0;
3895 if (m_aCycle
.hasValue())
3898 if (m_xAggregateSet
.is() && !getBOOL(m_xAggregateSet
->getPropertyValue(PROPERTY_APPLYFILTER
)))
3899 nAnyMask
|= DONTAPPLYFILTER
;
3901 _rxOutStream
->writeShort(nAnyMask
);
3903 if (nAnyMask
& CYCLE
)
3905 sal_Int32 nRealCycle
= 0;
3906 ::cppu::enum2int(nRealCycle
, m_aCycle
);
3907 _rxOutStream
->writeShort((sal_Int16
)nRealCycle
);
3912 void SAL_CALL
ODatabaseForm::read(const Reference
<XObjectInputStream
>& _rxInStream
) throw( IOException
, RuntimeException
, std::exception
)
3914 DBG_ASSERT(m_xAggregateSet
.is(), "ODatabaseForm::read : only to be called if the aggregate exists !");
3916 OFormComponents::read(_rxInStream
);
3919 sal_uInt16 nVersion
= _rxInStream
->readShort();
3921 _rxInStream
>> m_sName
;
3923 OUString sAggregateProp
;
3924 _rxInStream
>> sAggregateProp
;
3925 if (m_xAggregateSet
.is())
3926 m_xAggregateSet
->setPropertyValue(PROPERTY_DATASOURCE
, makeAny(sAggregateProp
));
3927 _rxInStream
>> sAggregateProp
;
3928 if (m_xAggregateSet
.is())
3929 m_xAggregateSet
->setPropertyValue(PROPERTY_COMMAND
, makeAny(sAggregateProp
));
3931 _rxInStream
>> m_aMasterFields
;
3932 _rxInStream
>> m_aDetailFields
;
3934 sal_Int16 nCursorSourceType
= _rxInStream
->readShort();
3935 sal_Int32 nCommandType
= 0;
3936 switch ((DataSelectionType
)nCursorSourceType
)
3938 case DataSelectionType_TABLE
: nCommandType
= CommandType::TABLE
; break;
3939 case DataSelectionType_QUERY
: nCommandType
= CommandType::QUERY
; break;
3940 case DataSelectionType_SQL
:
3941 case DataSelectionType_SQLPASSTHROUGH
:
3943 nCommandType
= CommandType::COMMAND
;
3944 bool bEscapeProcessing
= ((DataSelectionType
)nCursorSourceType
) != DataSelectionType_SQLPASSTHROUGH
;
3945 m_xAggregateSet
->setPropertyValue(PROPERTY_ESCAPE_PROCESSING
, makeAny(bEscapeProcessing
));
3948 default : OSL_FAIL("ODatabaseForm::read : wrong CommandType !");
3950 if (m_xAggregateSet
.is())
3951 m_xAggregateSet
->setPropertyValue(PROPERTY_COMMANDTYPE
, makeAny(nCommandType
));
3954 _rxInStream
->readShort();
3956 // navigation mode was a boolean in version 1
3957 // was a sal_Bool in version 1
3958 bool bNavigation
= _rxInStream
->readBoolean();
3960 m_eNavigation
= bNavigation
? NavigationBarMode_CURRENT
: NavigationBarMode_NONE
;
3962 bool bInsertOnly
= _rxInStream
->readBoolean();
3963 if (m_xAggregateSet
.is())
3964 m_xAggregateSet
->setPropertyValue(PROPERTY_INSERTONLY
, makeAny(bInsertOnly
));
3966 m_bAllowInsert
= _rxInStream
->readBoolean();
3967 m_bAllowUpdate
= _rxInStream
->readBoolean();
3968 m_bAllowDelete
= _rxInStream
->readBoolean();
3972 _rxInStream
>> sTmp
;
3973 m_aTargetURL
= INetURLObject::decode( sTmp
, INetURLObject::DECODE_UNAMBIGUOUS
);
3974 m_eSubmitMethod
= (FormSubmitMethod
)_rxInStream
->readShort();
3975 m_eSubmitEncoding
= (FormSubmitEncoding
)_rxInStream
->readShort();
3976 _rxInStream
>> m_aTargetFrame
;
3980 sal_Int32 nCycle
= _rxInStream
->readShort();
3981 m_aCycle
= ::cppu::int2enum(nCycle
, cppu::UnoType
<TabulatorCycle
>::get());
3982 m_eNavigation
= (NavigationBarMode
)_rxInStream
->readShort();
3984 _rxInStream
>> sAggregateProp
;
3985 setPropertyValue(PROPERTY_FILTER
, makeAny(sAggregateProp
));
3987 _rxInStream
>> sAggregateProp
;
3988 if (m_xAggregateSet
.is())
3989 m_xAggregateSet
->setPropertyValue(PROPERTY_SORT
, makeAny(sAggregateProp
));
3992 sal_uInt16 nAnyMask
= 0;
3995 nAnyMask
= _rxInStream
->readShort();
3996 if (nAnyMask
& CYCLE
)
3998 sal_Int32 nCycle
= _rxInStream
->readShort();
3999 m_aCycle
= ::cppu::int2enum(nCycle
, cppu::UnoType
<TabulatorCycle
>::get());
4004 if (m_xAggregateSet
.is())
4005 m_xAggregateSet
->setPropertyValue(PROPERTY_APPLYFILTER
, makeAny((nAnyMask
& DONTAPPLYFILTER
) == 0));
4009 void ODatabaseForm::implInserted( const ElementDescription
* _pElement
)
4011 OFormComponents::implInserted( _pElement
);
4013 Reference
< XSQLErrorBroadcaster
> xBroadcaster( _pElement
->xInterface
, UNO_QUERY
);
4014 Reference
< XForm
> xForm ( _pElement
->xInterface
, UNO_QUERY
);
4016 if ( xBroadcaster
.is() && !xForm
.is() )
4017 { // the object is an error broadcaster, but no form itself -> add ourself as listener
4018 xBroadcaster
->addSQLErrorListener( this );
4023 void ODatabaseForm::implRemoved(const InterfaceRef
& _rxObject
)
4025 OFormComponents::implRemoved( _rxObject
);
4027 Reference
<XSQLErrorBroadcaster
> xBroadcaster(_rxObject
, UNO_QUERY
);
4028 Reference
<XForm
> xForm(_rxObject
, UNO_QUERY
);
4029 if (xBroadcaster
.is() && !xForm
.is())
4030 { // the object is an error broadcaster, but no form itself -> remove ourself as listener
4031 xBroadcaster
->removeSQLErrorListener(this);
4035 void SAL_CALL
ODatabaseForm::errorOccured(const SQLErrorEvent
& _rEvent
) throw( RuntimeException
, std::exception
)
4037 // give it to my own error listener
4039 // TODO: think about extending the chain with an SQLContext object saying
4040 // "this was an error of one of my children"
4043 // com::sun::star::container::XNamed
4044 OUString SAL_CALL
ODatabaseForm::getName() throw( RuntimeException
, std::exception
)
4049 OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME
) >>= sReturn
;
4051 catch (const css::beans::UnknownPropertyException
&)
4053 throw WrappedTargetRuntimeException(
4054 "ODatabaseForm::getName",
4055 *const_cast< ODatabaseForm
* >( this ),
4056 ::cppu::getCaughtException()
4062 void SAL_CALL
ODatabaseForm::setName(const OUString
& aName
) throw( RuntimeException
, std::exception
)
4064 setFastPropertyValue(PROPERTY_ID_NAME
, makeAny(aName
));
4069 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
4070 com_sun_star_comp_forms_ODatabaseForm_get_implementation(css::uno::XComponentContext
* context
,
4071 css::uno::Sequence
<css::uno::Any
> const &)
4073 return cppu::acquire(new frm::ODatabaseForm(context
));
4076 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */