/************************************************************************* * * $RCSfile: DatabaseForm.cxx,v $ * * $Revision: 1.38 $ * * last change: $Author: oj $ $Date: 2001-09-28 06:58:43 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #include #include #ifndef _FRM_DATABASEFORM_HXX_ #include "DatabaseForm.hxx" #endif #ifndef _FRM_EVENT_THREAD_HXX_ #include "EventThread.hxx" #endif #ifndef _FORMS_LISTBOX_HXX_ #include "ListBox.hxx" #endif #ifndef _FRM_RESOURCE_HXX_ #include "frm_resource.hxx" #endif #ifndef _FRM_RESOURCE_HRC_ #include "frm_resource.hrc" #endif #ifndef _COM_SUN_STAR_SDB_XSQLQUERYCOMPOSERFACTORY_HPP_ #include #endif #ifndef _COM_SUN_STAR_UTIL_XCANCELLABLE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_RESULTSETTYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_RESULTSETCONCURRENCY_HPP_ #include #endif #ifndef _COM_SUN_STAR_IO_XOBJECTINPUTSTREAM_HPP_ #include #endif #ifndef _COM_SUN_STAR_IO_XOBJECTOUTPUTSTREAM_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_DATASELECTIONTYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_ #include #endif #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_ #include #endif #ifndef _COM_SUN_STAR_FRAME_XDISPATCH_HPP_ #include #endif #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_ROWSETVETOEXCEPTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_XPARAMETERSSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XROWSET_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_TABULATORCYCLE_HPP_ #include #endif #ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_ #include #endif #ifndef _COM_SUN_STAR_AWT_XTEXTCOMPONENT_HPP_ #include #endif #ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_ #include #endif #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _SV_TIMER_HXX #include #endif #ifndef _FRM_GROUPMANAGER_HXX_ #include "GroupManager.hxx" #endif #ifndef _FRM_PROPERTY_HRC_ #include "property.hrc" #endif #ifndef _FRM_PROPERTY_HXX_ #include "property.hxx" #endif #ifndef _FRM_SERVICES_HXX_ #include "services.hxx" #endif #ifndef _FRM_IDS_HXX_ #include "ids.hxx" #endif #ifndef _FSYS_HXX #include #endif #ifndef _TOOLS_INETMSG_HXX #include #endif #ifndef _INETSTRM_HXX //autogen #include #endif #ifndef _CPPUHELPER_IMPLBASE2_HXX_ #include #endif #ifndef _COMPHELPER_STLTYPES_HXX_ #include #endif #ifndef _COMPHELPER_SEQUENCE_HXX_ #include #endif #ifndef _COMPHELPER_STLTYPES_HXX_ #include #endif #ifndef _COMPHELPER_UNO3_HXX_ #include #endif #ifndef _COMPHELPER_SEQSTREAM_HXX #include #endif #ifndef _COMPHELPER_ENUMHELPER_HXX_ #include #endif #ifndef _COMPHELPER_CONTAINER_HXX_ #include #endif #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include #endif #ifndef _OSL_MUTEX_HXX_ #include #endif #ifndef _URLOBJ_HXX #include #endif #ifndef _TOOLS_SOLMATH_HXX #include #endif #ifndef _INETTYPE_HXX #include #endif #ifndef _COMPHELPER_EXTRACT_HXX_ #include #endif #ifndef _VOS_MUTEX_HXX_ #include #endif #ifndef _SV_SVAPP_HXX // because of the solar mutex #include #endif #ifndef _RTL_TENCINFO_H #include #endif #ifndef _UNTOOLS_UCBLOCKBYTES_HXX #include #endif #ifndef _UNTOOLS_UCBSTREAMHELPER_HXX #include #endif // compatiblity: DatabaseCursorType is dead, but for compatiblity reasons we still have to write it ... namespace com { namespace sun { namespace star { namespace data { enum DatabaseCursorType { DatabaseCursorType_FORWARD = 0, DatabaseCursorType_SNAPSHOT = 1, DatabaseCursorType_KEYSET = 2, DatabaseCursorType_DYNAMIC = 3, DatabaseCursorType_MAKE_FIXED_SIZE = SAL_MAX_ENUM }; } } } } #ifndef _COMPHELPER_INTERACTION_HXX_ #include #endif #ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_PARAMETERSREQUEST_HPP_ #include #endif #define DATABASEFORM_IMPLEMENTATION_NAME ::rtl::OUString::createFromAscii("com.sun.star.comp.forms.ODatabaseForm") using namespace ::dbtools; using namespace ::comphelper; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; using namespace ::com::sun::star::task; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::form; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::io; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::data; using namespace ::com::sun::star::util; //......................................................................... namespace frm { //......................................................................... //------------------------------------------------------------------ Reference< XModel> getXModel(const Reference< XInterface>& xIface) { Reference< XModel> xModel(xIface, UNO_QUERY); if (xModel.is()) return xModel; else { Reference< XChild> xChild(xIface, UNO_QUERY); if (xChild.is()) { Reference< XInterface> xParent( xChild->getParent()); return getXModel(xParent); } else return NULL; } } //================================================================== // OParameterContinuation //================================================================== class OParameterContinuation : public OInteraction< XInteractionSupplyParameters > { Sequence< PropertyValue > m_aValues; public: OParameterContinuation() { } Sequence< PropertyValue > getValues() const { return m_aValues; } // XInteractionSupplyParameters virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException); }; //------------------------------------------------------------------ void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException) { m_aValues = _rValues; } //================================================================== //= OParameterWrapper //=----------------------------------------------------------------- //= wraps a parameter property set got from an SQLQueryComposer //= so it has an additional property "Value", which is forwarded to //= an XParameters interface //================================================================== class OParameterWrapper :public ::cppu::OWeakObject ,public ::cppu::OPropertySetHelper ,public ::comphelper::OAggregationArrayUsageHelper { Any m_aValue; ::osl::Mutex m_aMutex; ::cppu::OBroadcastHelper m_aBroadcastHelper; OImplementationIdsRef m_aHoldIdHelper; Reference m_xPseudoAggregate; Reference m_xValueDestination; sal_Int32 m_nIndex; virtual ~OParameterWrapper(); public: OParameterWrapper(const Reference& _rxColumn, const Reference& _rxAllParameters, sal_Int32 _nIndex); // UNO DECLARE_UNO3_DEFAULTS(OParameterWrapper, OWeakObject); virtual Any SAL_CALL queryInterface(const Type& _rType) throw (RuntimeException); virtual Sequence SAL_CALL getImplementationId() throw(RuntimeException); virtual Sequence SAL_CALL getTypes() throw(RuntimeException); // XPropertySet virtual Reference SAL_CALL getPropertySetInfo() throw( RuntimeException ); virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); // OPropertySetHelper virtual sal_Bool SAL_CALL convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw( IllegalArgumentException ); virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception ); virtual void SAL_CALL getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const; // OAggregationArrayUsageHelper virtual void fillProperties( Sequence< Property >& /* [out] */ _rProps, Sequence< Property >& /* [out] */ _rAggregateProps ) const; protected: ::rtl::OUString getPseudoAggregatePropertyName(sal_Int32 _nHandle) const; }; DBG_NAME(OParameterWrapper) //------------------------------------------------------------------------------ OParameterWrapper::OParameterWrapper(const Reference& _rxColumn, const Reference& _rxAllParameters, sal_Int32 _nIndex) :OPropertySetHelper(m_aBroadcastHelper) ,m_aBroadcastHelper(m_aMutex) ,m_xPseudoAggregate(_rxColumn) ,m_xValueDestination(_rxAllParameters) ,m_nIndex(_nIndex) { DBG_CTOR(OParameterWrapper, NULL); } //------------------------------------------------------------------------------ OParameterWrapper::~OParameterWrapper() { DBG_DTOR(OParameterWrapper, NULL); } //------------------------------------------------------------------------------ Any SAL_CALL OParameterWrapper::queryInterface(const Type& _rType) throw (RuntimeException) { Any aReturn; aReturn = OWeakObject::queryInterface(_rType); if (!aReturn.hasValue()) OPropertySetHelper::queryInterface(_rType); return aReturn; } //------------------------------------------------------------------------------ Sequence< Type > SAL_CALL OParameterWrapper::getTypes( ) throw(RuntimeException) { Sequence< Type > aWeakTypes(1); aWeakTypes.getArray()[0] = ::getCppuType(static_cast*>(NULL)); Sequence< Type > aPropertyTypes(3); aPropertyTypes.getArray()[0] = ::getCppuType(static_cast*>(NULL)); aPropertyTypes.getArray()[1] = ::getCppuType(static_cast*>(NULL)); aPropertyTypes.getArray()[2] = ::getCppuType(static_cast*>(NULL)); return concatSequences(aWeakTypes, aPropertyTypes); } //------------------------------------------------------------------------------ Sequence SAL_CALL OParameterWrapper::getImplementationId() throw(RuntimeException) { Reference xMyTpes; query_interface(static_cast(this), xMyTpes); return OImplementationIds::getImplementationId(xMyTpes); } //------------------------------------------------------------------------------ ::rtl::OUString OParameterWrapper::getPseudoAggregatePropertyName(sal_Int32 _nHandle) const { Reference xInfo = const_cast(this)->getPropertySetInfo(); Sequence aProperties = xInfo->getProperties(); const Property* pProperties = aProperties.getConstArray(); for (sal_Int32 i=0; iHandle == _nHandle) return pProperties->Name; } DBG_ERROR("OParameterWrapper::getPseudoAggregatePropertyName : invalid argument !"); return ::rtl::OUString(); } //------------------------------------------------------------------------------ Reference OParameterWrapper::getPropertySetInfo() throw( RuntimeException ) { Reference xInfo( createPropertySetInfo( getInfoHelper() ) ); return xInfo; } //------------------------------------------------------------------------------ void OParameterWrapper::fillProperties( Sequence< Property >& _rProps, Sequence< Property >& _rAggregateProps ) const { BEGIN_AGGREGATION_PROPERTY_HELPER(1, m_xPseudoAggregate) DECL_PROP2(VALUE, ::rtl::OUString, TRANSIENT, MAYBEVOID); END_AGGREGATION_PROPERTY_HELPER(); } //------------------------------------------------------------------------------ ::cppu::IPropertyArrayHelper& OParameterWrapper::getInfoHelper() { return *const_cast(this)->getArrayHelper(); } //------------------------------------------------------------------------------ sal_Bool OParameterWrapper::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw( IllegalArgumentException ) { DBG_ASSERT(PROPERTY_ID_VALUE == nHandle, "OParameterWrapper::convertFastPropertyValue : the only non-readonly prop should be our PROPERTY_VALUE"); // we're lazy here ... rOldValue = m_aValue; rConvertedValue = rValue; return sal_True; // assume "modified" ... } //------------------------------------------------------------------------------ void OParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception ) { if (nHandle == PROPERTY_ID_VALUE) { // get the type of the param Any aParamType = m_xPseudoAggregate->getPropertyValue(PROPERTY_FIELDTYPE); DBG_ASSERT(aParamType.getValueType().getTypeClass() == TypeClass_LONG, "ODatabaseForm::setPropertyValue : invalid parameter field !"); sal_Int32 nScale = 0; if (hasProperty(PROPERTY_SCALE, m_xPseudoAggregate)) { Any aScale = m_xPseudoAggregate->getPropertyValue(PROPERTY_SCALE); DBG_ASSERT(aScale.getValueType().getTypeClass() == TypeClass_LONG, "ODatabaseForm::setPropertyValue : invalid parameter field !"); nScale = getINT32(aScale); } // TODO : aParamType & nScale can be obtained within the constructor .... try { m_xValueDestination->setObjectWithInfo(m_nIndex + 1, rValue, getINT32(aParamType), nScale); // the index of the parameters is one-based m_aValue = rValue; } catch(SQLException& e) { WrappedTargetException aExceptionWrapper; aExceptionWrapper.Context = e.Context; aExceptionWrapper.Message = e.Message; aExceptionWrapper.TargetException <<= e; throw WrappedTargetException(aExceptionWrapper); } } else { ::rtl::OUString aName = getPseudoAggregatePropertyName(nHandle); m_xPseudoAggregate->setPropertyValue(aName, rValue); } } //------------------------------------------------------------------------------ void OParameterWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const { if (nHandle == PROPERTY_ID_VALUE) { rValue = m_aValue; } else { ::rtl::OUString aName = getPseudoAggregatePropertyName(nHandle); rValue = m_xPseudoAggregate->getPropertyValue(aName); } } //================================================================== //= OParametersImpl //=----------------------------------------------------------------- //= class for the parameter event see approveParameter //================================================================== typedef ::cppu::WeakImplHelper2 OParametersImplBase; class OParametersImpl : public OParametersImplBase { public: typedef ::std::vector > Parameters; typedef Parameters::iterator ParametersIterator; private: Parameters m_aParameters; public: // UNO DECLARE_UNO3_AGG_DEFAULTS(OParametersImpl, OParametersImplBase); // XElementAccess virtual Type SAL_CALL getElementType() throw( RuntimeException ); virtual sal_Bool SAL_CALL hasElements() throw( RuntimeException ); // XEnumerationAccess virtual Reference SAL_CALL createEnumeration() throw( RuntimeException ); // XIndexAccess virtual sal_Int32 SAL_CALL getCount() throw( RuntimeException ); virtual Any SAL_CALL getByIndex(sal_Int32 _rIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); Parameters& getParameters() { return m_aParameters; } }; // XElementAccess //------------------------------------------------------------------------------ Type SAL_CALL OParametersImpl::getElementType() throw( RuntimeException ) { return ::getCppuType(static_cast*>(NULL)); } //------------------------------------------------------------------------------ sal_Bool SAL_CALL OParametersImpl::hasElements() throw( RuntimeException ) { return m_aParameters.size() != 0; } // XIndexAccess //------------------------------------------------------------------------------ sal_Int32 SAL_CALL OParametersImpl::getCount() throw( RuntimeException ) { return m_aParameters.size(); } //------------------------------------------------------------------------------ Any SAL_CALL OParametersImpl::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) { if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aParameters.size())) throw IndexOutOfBoundsException(); return makeAny(m_aParameters[_nIndex]); } // XEnumerationAccess //------------------------------------------------------------------------------ Reference OParametersImpl::createEnumeration() throw( RuntimeException ) { return new OEnumerationByIndex(reinterpret_cast(this)); } //================================================================== //= OParameterInfoImpl //=----------------------------------------------------------------- //= class which collects all information for parameter filling //================================================================== DECLARE_STL_USTRINGACCESS_MAP(sal_Int32, MapUString2INT32); struct OParameterInfoImpl { sal_Int32 nCount; // Number of Parameters Reference xComposer; Reference xParamsAsNames; OParametersImpl* pParameters; MapUString2INT32 aParamMapping; OParameterInfoImpl():nCount(0),pParameters(NULL){} ~OParameterInfoImpl() { if (pParameters) pParameters->release(); } }; //================================================================== //= OFormSubmitResetThread //=----------------------------------------------------------------- //= submitting and resetting html-forms asynchronously //================================================================== //------------------------------------------------------------------ class OFormSubmitResetThread: public OComponentEventThread { protected: // duplicate an event with respect to it's type virtual EventObject *cloneEvent( const EventObject *pEvt ) const; // process an event. while processing the mutex isn't locked, and pCompImpl // is made sure to remain valid virtual void processEvent( ::cppu::OComponentHelper* _pCompImpl, const EventObject* _pEvt, const Reference& _rControl, sal_Bool _bSubmit); public: OFormSubmitResetThread(ODatabaseForm* pControl) : OComponentEventThread(pControl) { } }; //------------------------------------------------------------------ EventObject* OFormSubmitResetThread::cloneEvent( const EventObject *pEvt ) const { return new MouseEvent( *(MouseEvent *)pEvt ); } //------------------------------------------------------------------ void OFormSubmitResetThread::processEvent( ::cppu::OComponentHelper* pCompImpl, const EventObject *_pEvt, const Reference& _rControl, sal_Bool _bSubmit) { if (_bSubmit) ((ODatabaseForm *)pCompImpl)->submit_impl(_rControl, *reinterpret_cast(_pEvt), true); else ((ODatabaseForm *)pCompImpl)->reset_impl(true); } //================================================================== //= ODatabaseForm //================================================================== //------------------------------------------------------------------ InterfaceRef SAL_CALL ODatabaseForm_CreateInstance(const Reference& _rxFactory) { return *(new ODatabaseForm(_rxFactory)); } //------------------------------------------------------------------------------ Sequence SAL_CALL ODatabaseForm::getImplementationId() throw(RuntimeException) { return OImplementationIds::getImplementationId(getTypes()); } //------------------------------------------------------------------ Sequence SAL_CALL ODatabaseForm::getTypes() throw(RuntimeException) { // ask the aggregate Sequence aAggregateTypes; Reference xAggregateTypes; if (query_aggregation(m_xAggregate, xAggregateTypes)) aAggregateTypes = xAggregateTypes->getTypes(); Sequence aRet = concatSequences(aAggregateTypes, ODatabaseForm_BASE1::getTypes(), OFormComponents::getTypes()); return concatSequences(aRet,ODatabaseForm_BASE2::getTypes(), ODatabaseForm_BASE3::getTypes()); } //------------------------------------------------------------------ Any SAL_CALL ODatabaseForm::queryAggregation(const Type& _rType) throw(RuntimeException) { Any aReturn = ODatabaseForm_BASE1::queryInterface(_rType); // our own interfaces if (!aReturn.hasValue()) { aReturn = ODatabaseForm_BASE2::queryInterface(_rType); // property set related interfaces if (!aReturn.hasValue()) { aReturn = OPropertySetAggregationHelper::queryInterface(_rType); // form component collection related interfaces if (!aReturn.hasValue()) { aReturn = OFormComponents::queryAggregation(_rType); // interfaces already present in the aggregate which we want to reroute // only available if we could create the aggregate if (!aReturn.hasValue() && m_xAggregateAsRowSet.is()) aReturn = ODatabaseForm_BASE3::queryInterface(_rType); // aggregate interfaces // (ask the aggregated object _after_ the OComponentHelper (base of OFormComponents), // so calls to the XComponent interface reach us and not the aggreagtion) if (!aReturn.hasValue() && m_xAggregate.is()) aReturn = m_xAggregate->queryAggregation(_rType); } } } return aReturn; } DBG_NAME(ODatabaseForm); //------------------------------------------------------------------ ODatabaseForm::ODatabaseForm(const Reference& _rxFactory) :OFormComponents(_rxFactory) ,OPropertySetAggregationHelper(OComponentHelper::rBHelper) ,OPropertyChangeListener(m_aMutex) ,m_aLoadListeners(m_aMutex) ,m_aRowSetApproveListeners(m_aMutex) ,m_aRowSetListeners(m_aMutex) ,m_aParameterListeners(m_aMutex) ,m_aResetListeners(m_aMutex) ,m_aSubmitListeners(m_aMutex) ,m_aErrorListeners(m_aMutex) ,m_bLoaded(sal_False) ,m_bSubForm(sal_False) ,m_eNavigation(NavigationBarMode_CURRENT) ,m_nPrivileges(0) ,m_pParameterInfo(NULL) ,m_pThread(NULL) ,m_eSubmitMethod(FormSubmitMethod_GET) ,m_eSubmitEncoding(FormSubmitEncoding_URL) ,m_bAllowDelete(sal_True) ,m_bAllowUpdate(sal_True) ,m_bAllowInsert(sal_True) ,m_pLoadTimer(NULL) ,m_nResetsPending(0) ,m_bForwardingConnection(sal_False) ,m_pAggregatePropertyMultiplexer(NULL) ,m_bSharingConnection ( sal_False ) { DBG_CTOR(ODatabaseForm,NULL); // aggregate a row set increment(m_refCount); { m_xAggregate = Reference(m_xServiceFactory->createInstance(SRV_SDB_ROWSET), UNO_QUERY); // m_xAggregate = Reference(m_xServiceFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.sdb.dbaccess.ORowSet")), UNO_QUERY); DBG_ASSERT(m_xAggregate.is(), "ODatabaseForm::ODatabaseForm : could not instantiate an SDB rowset !"); m_xAggregateAsRowSet = Reference (m_xAggregate,UNO_QUERY); setAggregation(m_xAggregate); } // listen for the properties, important for Parameters if (m_xAggregateSet.is()) { m_pAggregatePropertyMultiplexer = new OPropertyChangeMultiplexer(this, m_xAggregateSet, sal_False); m_pAggregatePropertyMultiplexer->acquire(); m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_COMMAND); m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_FILTER_CRITERIA); m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_APPLYFILTER); m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_ACTIVE_CONNECTION); } if (m_xAggregate.is()) { m_xAggregate->setDelegator(static_cast(this)); } decrement(m_refCount); m_pGroupManager = new OGroupManager(this); m_pGroupManager->acquire(); } //------------------------------------------------------------------ ODatabaseForm::~ODatabaseForm() { DBG_DTOR(ODatabaseForm,NULL); m_pGroupManager->release(); if (m_xAggregate.is()) m_xAggregate->setDelegator(InterfaceRef()); if (m_pAggregatePropertyMultiplexer) { m_pAggregatePropertyMultiplexer->dispose(); m_pAggregatePropertyMultiplexer->release(); m_pAggregatePropertyMultiplexer = NULL; } } //============================================================================== // html tools //------------------------------------------------------------------------ ::rtl::OUString ODatabaseForm::GetDataURLEncoded(const Reference& SubmitButton, const MouseEvent& MouseEvt) { // Liste von successful Controls fuellen HtmlSuccessfulObjList aSuccObjList; FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt ); // Liste zu ::rtl::OUString zusammensetzen ::rtl::OUString aResult; ::rtl::OUString aName; ::rtl::OUString aValue; for ( HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin(); pSuccObj < aSuccObjList.end(); ++pSuccObj ) { aName = pSuccObj->aName; aValue = pSuccObj->aValue; if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE && aValue.getLength() ) { // Bei File-URLs wird der Dateiname und keine URL uebertragen, // weil Netscape dies so macht. INetURLObject aURL; aURL.SetSmartProtocol(INET_PROT_FILE); aURL.SetSmartURL(aValue); if( INET_PROT_FILE == aURL.GetProtocol() ) aValue = INetURLObject::decode(aURL.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS); } Encode( aName ); Encode( aValue ); aResult += aName; aResult += UniString('='); aResult += aValue; if (pSuccObj < aSuccObjList.end() - 1) aResult += UniString('&'); } aSuccObjList.clear(); return aResult; } //============================================================================== // html tools //------------------------------------------------------------------------ ::rtl::OUString ODatabaseForm::GetDataTextEncoded(const Reference& SubmitButton, const MouseEvent& MouseEvt) { // Liste von successful Controls fuellen HtmlSuccessfulObjList aSuccObjList; FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt ); // Liste zu ::rtl::OUString zusammensetzen ::rtl::OUString aResult; ::rtl::OUString aName; ::rtl::OUString aValue; for ( HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin(); pSuccObj < aSuccObjList.end(); ++pSuccObj ) { aName = pSuccObj->aName; aValue = pSuccObj->aValue; if (pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE && aValue.getLength()) { // Bei File-URLs wird der Dateiname und keine URL uebertragen, // weil Netscape dies so macht. INetURLObject aURL; aURL.SetSmartProtocol(INET_PROT_FILE); aURL.SetSmartURL(aValue); if( INET_PROT_FILE == aURL.GetProtocol() ) aValue = INetURLObject::decode(aURL.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS); } Encode( aName ); Encode( aValue ); aResult += pSuccObj->aName; aResult += UniString('='); aResult += pSuccObj->aValue; if (pSuccObj < aSuccObjList.end() - 1) aResult += ::rtl::OUString::createFromAscii("\r\n"); } // Liste loeschen aSuccObjList.clear(); return aResult; } //------------------------------------------------------------------------ Sequence ODatabaseForm::GetDataMultiPartEncoded(const Reference& SubmitButton, const MouseEvent& MouseEvt, ::rtl::OUString& rContentType) { // Parent erzeugen INetMIMEMessage aParent; aParent.EnableAttachChild( INETMSG_MULTIPART_FORM_DATA ); // Liste von successful Controls fuellen HtmlSuccessfulObjList aSuccObjList; FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt ); // Liste zu ::rtl::OUString zusammensetzen ::rtl::OUString aResult; for ( HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin(); pSuccObj < aSuccObjList.end(); ++pSuccObj ) { if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_TEXT ) InsertTextPart( aParent, pSuccObj->aName, pSuccObj->aValue ); else if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE ) InsertFilePart( aParent, pSuccObj->aName, pSuccObj->aValue ); } // Liste loeschen aSuccObjList.clear(); // Fuer Parent MessageStream erzeugen INetMIMEMessageStream aMessStream; aMessStream.SetSourceMessage( &aParent ); aMessStream.GenerateHeader( sal_False ); // MessageStream in SvStream kopieren SvMemoryStream aMemStream; char* pBuf = new char[1025]; int nRead; while( (nRead = aMessStream.Read(pBuf, 1024)) > 0 ) aMemStream.Write( pBuf, nRead ); delete[] pBuf; aMemStream.Flush(); aMemStream.Seek( 0 ); void* pData = (void*)aMemStream.GetData(); sal_Int32 nLen = aMemStream.Seek(STREAM_SEEK_TO_END); rContentType = UniString(aParent.GetContentType()); return Sequence((sal_Int8*)pData, nLen); } //------------------------------------------------------------------------ void ODatabaseForm::AppendComponent(HtmlSuccessfulObjList& rList, const Reference& xComponentSet, const ::rtl::OUString& rNamePrefix, const Reference& rxSubmitButton, const MouseEvent& MouseEvt) { if (!xComponentSet.is()) return; // MIB 25.6.98: Geschachtelte Formulare abfangen ... oder muesste // man sie submitten? if (!hasProperty(PROPERTY_CLASSID, xComponentSet)) return; // Namen ermitteln if (!hasProperty(PROPERTY_NAME, xComponentSet)) return; sal_Int16 nClassId; xComponentSet->getPropertyValue(PROPERTY_CLASSID) >>= nClassId; ::rtl::OUString aName; xComponentSet->getPropertyValue( PROPERTY_NAME ) >>= aName; if( !aName.getLength() && nClassId != FormComponentType::IMAGEBUTTON) return; else // Name um den Prefix erweitern aName = rNamePrefix + aName; switch( nClassId ) { // Buttons case FormComponentType::COMMANDBUTTON: { // Es wird nur der gedrueckte Submit-Button ausgewertet // MIB: Sofern ueberhaupt einer uebergeben wurde if( rxSubmitButton.is() ) { Reference xSubmitButtonComponent(rxSubmitButton->getModel(), UNO_QUERY); if (xSubmitButtonComponent == xComponentSet && hasProperty(PROPERTY_LABEL, xComponentSet)) { // =